plutonium 0.12.9 → 0.12.10

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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/app/views/components/form/form_component.html.erb +1 -3
  3. data/app/views/components/interactive_action_form/interactive_action_form_component.html.erb +5 -7
  4. data/app/views/components/nested_resource_form_fields/nested_resource_form_fields_component.html.erb +2 -2
  5. data/app/views/components/table_search_input/table_search_input_component.html.erb +8 -2
  6. data/app/views/resource/_interactive_resource_action_form.html.erb +1 -1
  7. data/app/views/resource/_resource_details.html.erb +9 -2
  8. data/app/views/resource/_resource_table.html.erb +9 -1
  9. data/lib/generators/pu/core/assets/templates/tailwind.config.js +2 -0
  10. data/lib/generators/pu/core/install/install_generator.rb +1 -1
  11. data/lib/generators/pu/core/install/templates/config/initializers/plutonium.rb +4 -0
  12. data/lib/generators/pu/eject/layout/layout_generator.rb +3 -2
  13. data/lib/generators/pu/eject/shell/shell_generator.rb +3 -2
  14. data/lib/generators/pu/field/input/input_generator.rb +32 -0
  15. data/lib/generators/pu/field/input/templates/.keep +0 -0
  16. data/lib/generators/pu/field/input/templates/input.rb.tt +15 -0
  17. data/lib/generators/pu/field/renderer/renderer_generator.rb +32 -0
  18. data/lib/generators/pu/field/renderer/templates/.keep +0 -0
  19. data/lib/generators/pu/field/renderer/templates/renderer.rb.tt +9 -0
  20. data/lib/plutonium/core/actions/interactive_action.rb +2 -2
  21. data/lib/plutonium/core/associations/renderers/base.rb +77 -0
  22. data/lib/plutonium/core/associations/renderers/factory.rb +0 -2
  23. data/lib/plutonium/core/associations/renderers/has_many_renderer.rb +6 -4
  24. data/lib/plutonium/core/controllers/crud_actions.rb +1 -1
  25. data/lib/plutonium/core/controllers/presentable.rb +3 -3
  26. data/lib/plutonium/core/definers/field_definer.rb +4 -4
  27. data/lib/plutonium/core/definers/{input_definer.rb → field_input_definer.rb} +4 -4
  28. data/lib/plutonium/core/definers/{renderer_definer.rb → field_renderer_definer.rb} +10 -10
  29. data/lib/plutonium/core/fields/inputs/attachment_input.rb +2 -2
  30. data/lib/plutonium/core/fields/inputs/base.rb +76 -10
  31. data/lib/plutonium/core/fields/inputs/checkbox_input.rb +3 -1
  32. data/lib/plutonium/core/fields/inputs/date_time_input.rb +3 -1
  33. data/lib/plutonium/core/fields/inputs/nested_input.rb +36 -21
  34. data/lib/plutonium/core/fields/inputs/noop_input.rb +1 -4
  35. data/lib/plutonium/core/fields/inputs/polymorphic_belongs_to_association_input.rb +8 -7
  36. data/lib/plutonium/core/fields/inputs/simple_form_association_input.rb +4 -5
  37. data/lib/plutonium/core/fields/inputs/simple_form_input.rb +2 -3
  38. data/lib/plutonium/core/fields/renderers/association_renderer.rb +11 -5
  39. data/lib/plutonium/core/fields/renderers/attachment_renderer.rb +3 -10
  40. data/lib/plutonium/core/fields/renderers/base.rb +83 -0
  41. data/lib/plutonium/core/fields/renderers/basic_renderer.rb +3 -17
  42. data/lib/plutonium/core/fields/renderers/factory.rb +0 -1
  43. data/lib/plutonium/core/renderable.rb +20 -0
  44. data/lib/plutonium/helpers/display_helper.rb +1 -1
  45. data/lib/plutonium/resource/controller.rb +1 -1
  46. data/lib/plutonium/resource/policy.rb +1 -1
  47. data/lib/plutonium/resource/presenter.rb +3 -3
  48. data/lib/plutonium/resource/query_object.rb +4 -4
  49. data/lib/plutonium/resource/record.rb +1 -1
  50. data/lib/plutonium/simple_form/attachment_component.rb +1 -1
  51. data/lib/plutonium/version.rb +1 -1
  52. data/package.json +1 -1
  53. metadata +13 -5
  54. data/lib/plutonium/core/associations/renderers/basic_renderer.rb +0 -28
@@ -3,17 +3,23 @@ module Plutonium
3
3
  module Fields
4
4
  module Inputs
5
5
  class Base
6
- attr_reader :name, :user_options
6
+ include Plutonium::Core::Renderable
7
7
 
8
+ attr_reader :name
9
+
10
+ # Initializes the Base input class with a name and user-defined options.
11
+ #
12
+ # @param name [String] the name of the input field.
13
+ # @param user_options [Hash] user-defined options for the input field.
8
14
  def initialize(name, **user_options)
9
15
  @name = name
10
16
  @user_options = user_options
11
17
  end
12
18
 
13
- def render(view_context, f, record, **)
14
- raise NotImplementedError, "#{self.class}#render"
15
- end
16
-
19
+ # Collects parameters matching the input field's name with multi-parameter attributes.
20
+ #
21
+ # @param params [Hash] the parameters to collect from.
22
+ # @return [Hash] the collected parameters.
17
23
  def collect(params)
18
24
  # Handles multi parameter attributes
19
25
  # https://www.cookieshq.co.uk/posts/rails-spelunking-date-select
@@ -26,17 +32,77 @@ module Plutonium
26
32
  # - parameter(1i)
27
33
  # - parameter(2f)
28
34
  regex = /^#{param}(\(\d+[if]?\))?$/
29
- keys = params.select { |key, value| regex.match?(key) }.keys
35
+ keys = params.select { |key, _| regex.match?(key) }.keys
30
36
  params.slice(*keys)
31
37
  end
32
38
 
33
- protected
39
+ # Sets the form and record objects on the input field.
40
+ #
41
+ # @param form [Object] the form object.
42
+ # @param record [Object] the record object.
43
+ # @param render_options [Hash] additional options for rendering.
44
+ def with(form:, record:, **render_options)
45
+ @form = form
46
+ @record = record
47
+ @render_options = render_options
48
+ @options = build_options(render_options)
49
+
50
+ self
51
+ end
52
+
53
+ private
54
+
55
+ # Returns input-specific options, can be overridden by subclasses.
56
+ #
57
+ # @return [Hash] the input-specific options.
58
+ def input_options
59
+ {}
60
+ end
61
+
62
+ # Returns the parameter name for the input field.
63
+ #
64
+ # @return [String] the parameter name.
65
+ def param
66
+ name
67
+ end
68
+
69
+ # Raises an error if #options is accessed before rendering.
70
+ #
71
+ # @raise [RuntimeError] if accessed before rendering.
72
+ # @return [Hash] the rendering options.
73
+ def options
74
+ raise "cannot access #options before calling #with" unless defined?(@options)
34
75
 
35
- def input_options = {}
76
+ @options
77
+ end
36
78
 
37
- def param = name
79
+ # Raises an error if #form is accessed before rendering.
80
+ #
81
+ # @raise [RuntimeError] if accessed before rendering.
82
+ # @return [Object] the form object.
83
+ def form
84
+ raise "cannot access #form before calling #with" unless defined?(@form)
85
+
86
+ @form
87
+ end
38
88
 
39
- def options = @options ||= input_options.deep_merge(@user_options)
89
+ # Raises an error if #record is accessed before rendering.
90
+ #
91
+ # @raise [RuntimeError] if accessed before rendering.
92
+ # @return [Object] the record object.
93
+ def record
94
+ raise "cannot access #record before calling #with" unless defined?(@record)
95
+
96
+ @record
97
+ end
98
+
99
+ # Builds the options for rendering by merging input options, user options, and render options.
100
+ #
101
+ # @param render_options [Hash] additional options for rendering.
102
+ # @return [Hash] the merged options.
103
+ def build_options(render_options)
104
+ input_options.deep_merge(@user_options).deep_merge(render_options)
105
+ end
40
106
  end
41
107
  end
42
108
  end
@@ -5,7 +5,9 @@ module Plutonium
5
5
  class CheckboxInput < SimpleFormInput
6
6
  private
7
7
 
8
- def input_options = {wrapper: :resource_checkbox}
8
+ def input_options
9
+ {wrapper: :resource_checkbox}
10
+ end
9
11
  end
10
12
  end
11
13
  end
@@ -5,7 +5,9 @@ module Plutonium
5
5
  class DateTimeInput < SimpleFormInput
6
6
  private
7
7
 
8
- def input_options = {wrapper: :resource_multi_select}
8
+ def input_options
9
+ {wrapper: :resource_multi_select}
10
+ end
9
11
  end
10
12
  end
11
13
  end
@@ -3,52 +3,67 @@ module Plutonium
3
3
  module Fields
4
4
  module Inputs
5
5
  class NestedInput < Base
6
- include Plutonium::Core::Definers::InputDefiner
6
+ include Plutonium::Core::Definers::FieldInputDefiner
7
7
 
8
8
  attr_reader :inputs, :resource_class
9
9
 
10
- def initialize(name, inputs:, resource_class:, allow_destroy:, update_only:, limit:, **user_options)
10
+ def initialize(name, inputs:, resource_class:, allow_destroy:, update_only:, limit:, **options)
11
11
  @inputs = inputs
12
12
  @resource_class = resource_class
13
13
  @allow_destroy = allow_destroy
14
14
  @update_only = update_only
15
15
  @limit = limit
16
16
 
17
- super(name, **user_options)
17
+ super(name, **options)
18
18
  end
19
19
 
20
- def render(view_context, f, record, **opts)
21
- opts = options.deep_merge opts
22
- view_context.render_component :nested_resource_form_fields, form: f, **opts
20
+ def render
21
+ render_component :nested_resource_form_fields, form:, **options
23
22
  end
24
23
 
25
24
  def collect(params)
25
+ nested_params = params[param] || {}
26
+ attributes = (nested_params.keys.first == "0") ? collect_indexed_attributes(nested_params) : collect_single_attributes(nested_params)
27
+ {param => attributes}
28
+ end
29
+
30
+ private
31
+
32
+ def collect_single_attributes(params)
33
+ collected = defined_inputs.collect_all(params)
34
+ collected[:id] = params[:id] if params.key?(:id) && !@update_only
35
+ collected[:_destroy] = params[:_destroy] if @allow_destroy
36
+ collected
37
+ end
38
+
39
+ def collect_indexed_attributes(params)
26
40
  attributes = {}
27
- params[param].each do |index, nested_params|
41
+ params.each do |index, nested_params|
28
42
  collected = defined_inputs.collect_all(nested_params)
29
43
  collected[:id] = nested_params[:id] if nested_params.key?(:id) && !@update_only
30
44
  collected[:_destroy] = nested_params[:_destroy] if @allow_destroy
31
45
  attributes[index] = collected
32
46
  end
33
-
34
- {param => attributes}
47
+ attributes
35
48
  end
36
49
 
37
- private
38
-
39
- def param = :"#{name}_attributes"
50
+ def param
51
+ :"#{name}_attributes"
52
+ end
40
53
 
41
- def input_options = {
42
- name:,
43
- resource_class:,
44
- allow_destroy: @allow_destroy,
45
- update_only: @update_only,
46
- limit: @limit,
47
- inputs: defined_inputs
48
- }
54
+ def input_options
55
+ {
56
+ name:,
57
+ resource_class:,
58
+ allow_destroy: @allow_destroy,
59
+ update_only: @update_only,
60
+ limit: @limit,
61
+ inputs: defined_inputs
62
+ }
63
+ end
49
64
 
50
65
  def defined_inputs
51
- @defined_inputs ||= defined_inputs_for(*inputs)
66
+ @defined_inputs ||= defined_field_inputs_for(*inputs)
52
67
  end
53
68
  end
54
69
  end
@@ -3,10 +3,7 @@ module Plutonium
3
3
  module Fields
4
4
  module Inputs
5
5
  class NoopInput
6
- def initialize(*)
7
- end
8
-
9
- def render(view_context, f, record, **)
6
+ def render
10
7
  end
11
8
 
12
9
  def collect(params)
@@ -3,9 +3,8 @@ module Plutonium
3
3
  module Fields
4
4
  module Inputs
5
5
  class PolymorphicBelongsToAssociationInput < SimpleFormAssociationInput
6
- def render(view_context, f, record, **opts)
7
- opts = options.deep_merge opts
8
- f.input param, **opts
6
+ def render
7
+ form.input param, **options
9
8
  end
10
9
 
11
10
  private
@@ -15,12 +14,11 @@ module Plutonium
15
14
  end
16
15
 
17
16
  def input_options
17
+ collection = @user_options.delete(:collection).presence || associated_classes
18
18
  {
19
19
  as: :grouped_select,
20
+ collection:,
20
21
  label: reflection.name.to_s.humanize,
21
- collection: associated_classes.map { |klass|
22
- [klass.name, klass.all]
23
- }.to_h,
24
22
  group_label_method: :first,
25
23
  group_method: :last, include_blank: "Select One"
26
24
  }
@@ -38,7 +36,10 @@ module Plutonium
38
36
  end
39
37
  end
40
38
  end
41
- associated_classes
39
+
40
+ associated_classes.map { |klass|
41
+ [klass.name, klass.all]
42
+ }.to_h
42
43
  end
43
44
  end
44
45
  end
@@ -5,14 +5,13 @@ module Plutonium
5
5
  class SimpleFormAssociationInput < Base
6
6
  attr_reader :reflection
7
7
 
8
- def initialize(name, reflection:, **user_options)
8
+ def initialize(name, reflection:, **)
9
9
  @reflection = reflection
10
- super(name, **user_options)
10
+ super(name, **)
11
11
  end
12
12
 
13
- def render(view_context, f, record, **opts)
14
- opts = options.deep_merge opts
15
- f.association name, **opts
13
+ def render
14
+ form.association name, **options
16
15
  end
17
16
 
18
17
  private
@@ -3,9 +3,8 @@ module Plutonium
3
3
  module Fields
4
4
  module Inputs
5
5
  class SimpleFormInput < Base
6
- def render(view_context, f, record, **opts)
7
- opts = options.deep_merge opts
8
- f.input name, **opts
6
+ def render
7
+ form.input name, **options
9
8
  end
10
9
  end
11
10
  end
@@ -2,7 +2,7 @@ module Plutonium
2
2
  module Core
3
3
  module Fields
4
4
  module Renderers
5
- class AssociationRenderer < BasicRenderer
5
+ class AssociationRenderer < Base
6
6
  attr_reader :reflection
7
7
 
8
8
  def initialize(name, reflection:, **user_options)
@@ -10,10 +10,16 @@ module Plutonium
10
10
  super(name, **user_options)
11
11
  end
12
12
 
13
- def render(view_context, record)
14
- value = record.send(name)
15
- options = self.options.merge(helper: value.class.include?(Plutonium::Resource::Record) ? :display_association_value : :display_name_of)
16
- view_context.display_field value:, **options
13
+ def render
14
+ display_field value:, **options
15
+ end
16
+
17
+ private
18
+
19
+ def renderer_options
20
+ {
21
+ helper: value.class.include?(Plutonium::Resource::Record) ? :display_association_value : :display_name_of
22
+ }
17
23
  end
18
24
  end
19
25
  end
@@ -2,16 +2,9 @@ module Plutonium
2
2
  module Core
3
3
  module Fields
4
4
  module Renderers
5
- class AttachmentRenderer < BasicRenderer
6
- attr_reader :reflection
7
-
8
- def initialize(name, reflection:, **user_options)
9
- @reflection = reflection
10
- super(name, **user_options)
11
- end
12
-
13
- def render(view_context, record)
14
- view_context.attachment_preview record.send(name), **options
5
+ class AttachmentRenderer < AssociationRenderer
6
+ def render
7
+ attachment_preview value, **options
15
8
  end
16
9
 
17
10
  private
@@ -0,0 +1,83 @@
1
+ module Plutonium
2
+ module Core
3
+ module Fields
4
+ module Renderers
5
+ class Base
6
+ include Plutonium::Core::Renderable
7
+
8
+ attr_reader :name
9
+
10
+ # Initializes the Base renderer class with a name and user-defined options.
11
+ #
12
+ # @param name [String] the name of the renderer.
13
+ # @param user_options [Hash] user-defined options for the renderer.
14
+ def initialize(name, **user_options)
15
+ @name = name
16
+ @user_options = user_options
17
+ end
18
+
19
+ # Sets the record object on the renderer and merges render options.
20
+ #
21
+ # @param record [Object] the record object.
22
+ # @param render_options [Hash] additional options for rendering.
23
+ # @return [self] the renderer instance.
24
+ def with(record:, **render_options)
25
+ @record = record
26
+ @render_options = render_options
27
+ @options = build_options(render_options)
28
+
29
+ self
30
+ end
31
+
32
+ def label
33
+ options[:label] || record.class.human_attribute_name(name)
34
+ end
35
+
36
+ private
37
+
38
+ # Returns the merged options for rendering.
39
+ #
40
+ # @raise [RuntimeError] if accessed before rendering.
41
+ # @return [Hash] the merged options.
42
+ def options
43
+ raise "cannot access #options before calling #with" unless defined?(@options)
44
+
45
+ @options
46
+ end
47
+
48
+ # Returns the record object.
49
+ #
50
+ # @raise [RuntimeError] if accessed before rendering.
51
+ # @return [Object] the record object.
52
+ def record
53
+ raise "cannot access #record before calling #with" unless defined?(@record)
54
+
55
+ @record
56
+ end
57
+
58
+ # Returns the value of the record's attribute corresponding to the renderer's name.
59
+ #
60
+ # @return [Object] the value of the attribute.
61
+ def value
62
+ record.public_send(name)
63
+ end
64
+
65
+ # Returns renderer-specific options, can be overridden by subclasses.
66
+ #
67
+ # @return [Hash] the renderer-specific options.
68
+ def renderer_options
69
+ {}
70
+ end
71
+
72
+ # Builds the options for rendering by merging renderer options, user options, and render options.
73
+ #
74
+ # @param render_options [Hash] additional options for rendering.
75
+ # @return [Hash] the merged options.
76
+ def build_options(render_options)
77
+ renderer_options.deep_merge(@user_options).deep_merge(render_options)
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -2,24 +2,10 @@ module Plutonium
2
2
  module Core
3
3
  module Fields
4
4
  module Renderers
5
- class BasicRenderer
6
- attr_reader :name, :label, :user_options
7
-
8
- def initialize(name, label:, **user_options)
9
- @name = name
10
- @label = label
11
- @user_options = user_options
5
+ class BasicRenderer < Base
6
+ def render
7
+ display_field value:, **options
12
8
  end
13
-
14
- def render(view_context, record)
15
- view_context.display_field value: record.send(name), **options
16
- end
17
-
18
- def options = @options ||= renderer_options.deep_merge(@user_options)
19
-
20
- private
21
-
22
- def renderer_options = {}
23
9
  end
24
10
  end
25
11
  end
@@ -17,7 +17,6 @@ module Plutonium
17
17
 
18
18
  def self.for_resource_attribute(resource_class, attr_name, **options)
19
19
  type = nil
20
- options[:label] ||= resource_class.human_attribute_name(attr_name)
21
20
 
22
21
  if (attachment = resource_class.try(:reflect_on_attachment, attr_name))
23
22
  type = :attachment
@@ -0,0 +1,20 @@
1
+ module Plutonium
2
+ module Core
3
+ module Renderable
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ delegate_missing_to :@view_context
8
+ end
9
+
10
+ def render_in(view_context)
11
+ @view_context = view_context
12
+ render
13
+ end
14
+
15
+ def render
16
+ raise NotImplementedError, "#{self.class}#render"
17
+ end
18
+ end
19
+ end
20
+ end
@@ -73,7 +73,7 @@ module Plutonium
73
73
 
74
74
  # Fallback to retrieving the value from a predefined list
75
75
  %i[to_label name title].each do |method|
76
- name = obj.send(method) if obj.respond_to?(method)
76
+ name = obj.public_send(method) if obj.respond_to?(method)
77
77
  return name if name.present?
78
78
  end
79
79
 
@@ -69,7 +69,7 @@ module Plutonium
69
69
  override_entity_scoping_params(input_params)
70
70
  override_parent_params(input_params)
71
71
 
72
- current_presenter.defined_inputs_for(*permitted_attributes).collect_all(input_params)
72
+ current_presenter.defined_field_inputs_for(*permitted_attributes).collect_all(input_params)
73
73
  end
74
74
 
75
75
  # Returns the resource parameter key
@@ -18,7 +18,7 @@ module Plutonium
18
18
  raise NotImplementedError, "#{self.class.name} does not implement the required #{method}"
19
19
  end
20
20
 
21
- send(method)
21
+ public_send(method)
22
22
  end
23
23
 
24
24
  # Core actions
@@ -63,7 +63,7 @@ module Plutonium
63
63
 
64
64
  nested_attribute_options_class = nested_attribute_options&.[](:class)
65
65
  if nested_attribute_options_class.nil? && model_class.nil?
66
- raise ArgumentError, "model_class is required if your field is not an association or is polymorphic"
66
+ raise ArgumentError, "model_class is required if your field is not an association or is polymorphic. also ensure you have called `accepts_nested_attributes_for :#{name}`"
67
67
  end
68
68
  model_class ||= nested_attribute_options_class
69
69
 
@@ -83,7 +83,7 @@ module Plutonium
83
83
  )
84
84
  yield input if block_given?
85
85
 
86
- define_input name, input:
86
+ define_field_input name, input:
87
87
  end
88
88
 
89
89
  # Determines the limit for a nested input
@@ -92,7 +92,7 @@ module Plutonium
92
92
  # @param [Integer, nil] nested_attribute_limit The limit from nested attributes
93
93
  # @return [Integer, nil] The determined limit
94
94
  def determine_nested_input_limit(macro, option_limit, nested_attribute_limit)
95
- if macro == :has_one
95
+ if %i[belongs_to has_one].include? macro
96
96
  1
97
97
  elsif option_limit
98
98
  option_limit
@@ -5,7 +5,7 @@ module Plutonium
5
5
  end
6
6
 
7
7
  class Query
8
- include Plutonium::Core::Definers::InputDefiner
8
+ include Plutonium::Core::Definers::FieldInputDefiner
9
9
 
10
10
  # Applies the query to the given scope using the provided parameters.
11
11
  #
@@ -65,7 +65,7 @@ module Plutonium
65
65
  # @param params [Hash] The parameters for the query.
66
66
  # @return [Object] The modified scope.
67
67
  def apply_internal(scope, params)
68
- scope.send(name, **params)
68
+ scope.public_send(name, **params)
69
69
  end
70
70
  end
71
71
 
@@ -215,7 +215,7 @@ module Plutonium
215
215
  end
216
216
 
217
217
  sort_definitions[name] = build_query(body) do |query|
218
- query.define_input :direction
218
+ query.define_field_input :direction
219
219
  end
220
220
  end
221
221
 
@@ -224,7 +224,7 @@ module Plutonium
224
224
  # @param body [Proc, Symbol] The body of the search filter.
225
225
  def define_search(body)
226
226
  @search_filter = build_query(body) do |query|
227
- query.define_input :search
227
+ query.define_field_input :search
228
228
  end
229
229
  end
230
230
 
@@ -22,7 +22,7 @@ module Plutonium
22
22
  record_association = klass.find_association_to_self(record)
23
23
  if record_association
24
24
  # TODO: add a warning here about a potentially poor performing query
25
- return where(id: record.send(record_association.name))
25
+ return where(id: record.public_send(record_association.name))
26
26
  end
27
27
 
28
28
  klass.raise_association_error(record, named_scope)
@@ -40,7 +40,7 @@ module Plutonium
40
40
  private
41
41
 
42
42
  def value
43
- @value ||= object.send(attribute_name) if object&.respond_to?(attribute_name)
43
+ @value ||= object.public_send(attribute_name) if object&.respond_to?(attribute_name)
44
44
  end
45
45
 
46
46
  def multiple?
@@ -1,3 +1,3 @@
1
1
  module Plutonium
2
- VERSION = "0.12.9"
2
+ VERSION = "0.12.10"
3
3
  end
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@radioactive-labs/plutonium",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Core assets for the Plutonium gem",
5
5
  "type": "module",
6
6
  "main": "src/js/core.js",