halitosis 0.2.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6dc2b6951bb551687107ecbf28dd84ef5d616b86a01f405bfd0578592e2ae572
4
- data.tar.gz: a98c1b99cc9973958db53bd3ea5d6acd11de9b6f79fb9a5c9fcf07f97514de01
3
+ metadata.gz: 0576b2d1e7ce15303f1bdc4a845bc7e81d1f2e497d3e49b220f1dd68920938cb
4
+ data.tar.gz: 79a5d29e8ec21cf3f035719dab8ef719216424a8514c2ff045d8f0f0d1cbe552
5
5
  SHA512:
6
- metadata.gz: dfed5ec625a1764322fa5ddc3df08b3fe0ee2dca6bcbe21da0c92daa00a168518f2f31e69ac0c7834ef4dded8ba3c62e93ba9349f9e68d63e7403ce98131d96b
7
- data.tar.gz: bb36dc686ccecdefc51500b9cf5d8142a72d4e460ad562ea020de9b93b57f00f9a2ff4ddac12351afe3060c2494408dbefa3735002672bb80e39d97bb88e2f34
6
+ metadata.gz: '02779ecf3fd87d66cab25c245c1ca82a2eee370241088d1af6fcc72bde1f3e7917687119260e4d5d04f22dfb363c1d8d9b54730caece6a82825d2ca65f6d9ef5'
7
+ data.tar.gz: 2e77dae400e7f5ece72aa1604898444b90c43cca04694b495f23dda4aaf38e4b62b05bc1cdd67b1f32d1e5c1014924756e2b242bd4c5a648df944bee18d61520
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Halitosis
4
- module Attributes
4
+ module Identifiers
5
5
  class Field < Halitosis::Field
6
6
  end
7
7
  end
@@ -48,8 +48,8 @@ module Halitosis
48
48
 
49
49
  # @return [Hash] rendered representation
50
50
  #
51
- def render
52
- render_with_context(build_context)
51
+ def render(**options)
52
+ render_with_context(build_context(options))
53
53
  end
54
54
 
55
55
  # @param context [Halitosis::Context] the context instance
@@ -39,6 +39,21 @@ module Halitosis
39
39
  def collection_field
40
40
  fields.for_type(Field).last || raise(InvalidCollection, "#{name || Collection.name} collection is not defined")
41
41
  end
42
+
43
+ # Provide an alias for root_link
44
+ def link(*, **, &)
45
+ root_link(*, **, &)
46
+ end
47
+
48
+ # Provide an alias for root_meta
49
+ def meta(*, **, &)
50
+ root_meta(*, **, &)
51
+ end
52
+
53
+ # Provide an alias for root_permission
54
+ def permission(*, **, &)
55
+ root_permission(*, **, &)
56
+ end
42
57
  end
43
58
 
44
59
  module InstanceMethods
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Halitosis
4
+ module Attributes
5
+ class Field < Halitosis::Field
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Halitosis
4
+ module Identifiers
5
+ def self.included(base)
6
+ base.extend ClassMethods
7
+
8
+ base.send :include, InstanceMethods
9
+ end
10
+
11
+ module ClassMethods
12
+ # Rails-style identifier definition
13
+ #
14
+ # @param name [Symbol, String]
15
+ # @param options [nil, Hash]
16
+ #
17
+ # @return [Halitosis::Identifiers::Field]
18
+ #
19
+ def identifier(name, options = {}, &procedure)
20
+ if fields.for_type(Field).any?
21
+ raise InvalidField, "You can only define one identifier per serializer"
22
+ end
23
+
24
+ fields.add(Field.new(name, options, procedure))
25
+ end
26
+ end
27
+
28
+ module InstanceMethods
29
+ # @return [Hash] the rendered hash with identifiers, if any
30
+ #
31
+ def render_with_context(context)
32
+ super.merge(identifiers(context))
33
+ end
34
+
35
+ # @return [Hash] identifiers from fields
36
+ #
37
+ def identifiers(context = build_context)
38
+ render_fields(Field, context) do |field, result|
39
+ result[field.name] = field.value(context)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ require "halitosis/identifiers/field"
@@ -3,8 +3,13 @@ module Halitosis
3
3
  #
4
4
  class Railtie < ::Rails::Railtie
5
5
  module Renderable
6
+ def render_with_params(params)
7
+ render(include: params[:include])
8
+ end
9
+
6
10
  def render_in(view_context)
7
- view_context.render json: self
11
+ rendered = render_with_params(view_context.params)
12
+ view_context.render plain: rendered.to_json
8
13
  end
9
14
 
10
15
  def format
@@ -37,9 +37,7 @@ module Halitosis
37
37
  render_fields(Field, context) do |field, result|
38
38
  value = field.value(context)
39
39
 
40
- child = relationships_child(field.name.to_s, context, value)
41
-
42
- result[field.name] = child if child
40
+ result[field.name] = relationships_child(field.name.to_s, context, value)
43
41
  end
44
42
  end
45
43
 
@@ -27,6 +27,18 @@ module Halitosis
27
27
  alias_method name, :resource
28
28
  end
29
29
 
30
+ # Override standard identifier field for resource-based serializers
31
+ #
32
+ # @param name [Symbol, String] name of the identifier
33
+ # @param options [nil, Hash] identifier options for field
34
+ #
35
+ def identifier(name, options = {}, &procedure)
36
+ unless procedure || options.key?(:value)
37
+ procedure = proc { resource.public_send(name) }
38
+ end
39
+ super(name, options, &procedure)
40
+ end
41
+
30
42
  # Override standard attribute field for resource-based serializers
31
43
  #
32
44
  # @param name [Symbol, String] name of the attribute
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Halitosis
4
+ module RootLinks
5
+ class Field < Halitosis::Links::Field
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Halitosis
4
+ module RootLinks
5
+ def self.included(base)
6
+ base.extend ClassMethods
7
+
8
+ base.send :include, InstanceMethods
9
+ end
10
+
11
+ module ClassMethods
12
+ # @return [Halitosis::RootLinks::Field]
13
+ #
14
+ def root_link(name, **options, &procedure)
15
+ fields.add(Field.new(name, options, procedure))
16
+ end
17
+ end
18
+
19
+ module InstanceMethods
20
+ # @return [Hash] the rendered hash with link, if any
21
+ #
22
+ def render(**)
23
+ super.tap do |result|
24
+ next unless options.fetch(:include_root) { true }
25
+
26
+ value = root_links
27
+ result[:_links] = result.fetch(:_links, {}).merge(value) if value.any?
28
+ end
29
+ end
30
+
31
+ # @return [Hash] link from fields
32
+ #
33
+ # @return [Hash] root_links from fields
34
+ #
35
+ def root_links(context = build_context)
36
+ render_fields(Field, context) do |field, result|
37
+ value = field.value(context)
38
+
39
+ result[field.name] = value if value
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ require "halitosis/root_links/field"
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Halitosis
4
+ module RootMeta
5
+ class Field < Halitosis::Meta::Field
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Halitosis
4
+ module RootMeta
5
+ def self.included(base)
6
+ base.extend ClassMethods
7
+
8
+ base.send :include, InstanceMethods
9
+ end
10
+
11
+ module ClassMethods
12
+ # @return [Halitosis::RootMeta::Field]
13
+ #
14
+ def root_meta(name, **options, &procedure)
15
+ fields.add(Field.new(name, options, procedure))
16
+ end
17
+ end
18
+
19
+ module InstanceMethods
20
+ # @return [Hash] the rendered hash with meta, if any
21
+ #
22
+ def render(**)
23
+ super.tap do |result|
24
+ next unless options.fetch(:include_root) { true }
25
+
26
+ value = root_meta
27
+ result[:_meta] = result.fetch(:_meta, {}).merge(value) if value.any?
28
+ end
29
+ end
30
+
31
+ # @return [Hash] meta from fields
32
+ #
33
+ def root_meta(context = build_context)
34
+ render_fields(Field, context) do |field, result|
35
+ value = field.value(context)
36
+
37
+ result[field.name] = value
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ require "halitosis/root_meta/field"
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Halitosis
4
+ module RootPermissions
5
+ class Field < Halitosis::Permissions::Field
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Halitosis
4
+ module RootPermissions
5
+ def self.included(base)
6
+ base.extend ClassMethods
7
+
8
+ base.send :include, InstanceMethods
9
+ end
10
+
11
+ module ClassMethods
12
+ # @return [Halitosis::RootPermission::Field]
13
+ #
14
+ def root_permission(name, **options, &procedure)
15
+ fields.add(Field.new(name, options, procedure))
16
+ end
17
+ end
18
+
19
+ module InstanceMethods
20
+ # @return [Hash] the rendered hash with permissions, if any
21
+ #
22
+ def render(**)
23
+ super.tap do |result|
24
+ value = root_permissions
25
+ result[:_permissions] = result.fetch(:_permissions, {}).merge(value) if value.any?
26
+ end
27
+ end
28
+
29
+ # @return [Hash] permissions from fields
30
+ #
31
+ def root_permissions(context = build_context)
32
+ render_fields(Field, context) do |field, result|
33
+ next unless options.fetch(:include_root) { true }
34
+
35
+ value = field.value(context)
36
+ result[field.name] = value || false
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ require "halitosis/root_permissions/field"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Halitosis
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
data/lib/halitosis.rb CHANGED
@@ -33,24 +33,31 @@ module Halitosis
33
33
  base.extend ClassMethods
34
34
 
35
35
  base.include Base
36
- base.include Links
37
- base.include Meta
38
- base.include Permissions
39
36
  base.include Attributes
40
- base.include Relationships
41
37
 
42
38
  config.extensions.each { |extension| base.send :include, extension }
43
39
  end
44
40
 
45
41
  module ClassMethods
46
42
  def resource(name)
43
+ include Identifiers
44
+ include Links
45
+ include Meta
46
+ include Permissions
47
+ include Relationships
47
48
  include Halitosis::Resource
49
+ include RootLinks
50
+ include RootMeta
51
+ include RootPermissions
48
52
 
49
53
  define_resource(name)
50
54
  end
51
55
 
52
56
  def collection(name, ...)
53
57
  include Halitosis::Collection
58
+ include RootLinks
59
+ include RootMeta
60
+ include RootPermissions
54
61
 
55
62
  define_collection(name, ...)
56
63
  end
@@ -79,10 +86,14 @@ require_relative "halitosis/errors"
79
86
  require_relative "halitosis/field"
80
87
  require_relative "halitosis/fields"
81
88
  require_relative "halitosis/attributes"
89
+ require_relative "halitosis/identifiers"
82
90
  require_relative "halitosis/links"
83
91
  require_relative "halitosis/meta"
84
92
  require_relative "halitosis/permissions"
85
93
  require_relative "halitosis/relationships"
94
+ require_relative "halitosis/root_links"
95
+ require_relative "halitosis/root_meta"
96
+ require_relative "halitosis/root_permissions"
86
97
  require_relative "halitosis/resource"
87
98
  require_relative "halitosis/collection"
88
99
  require_relative "halitosis/hash_util"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: halitosis
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Morrall
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-10-07 00:00:00.000000000 Z
11
+ date: 2024-12-17 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Provides an interface for serializing resources as JSON with HAL-like
14
14
  links and relationships.
@@ -37,6 +37,8 @@ files:
37
37
  - lib/halitosis/field.rb
38
38
  - lib/halitosis/fields.rb
39
39
  - lib/halitosis/hash_util.rb
40
+ - lib/halitosis/identifiers.rb
41
+ - lib/halitosis/identifiers/field.rb
40
42
  - lib/halitosis/links.rb
41
43
  - lib/halitosis/links/field.rb
42
44
  - lib/halitosis/meta.rb
@@ -47,6 +49,12 @@ files:
47
49
  - lib/halitosis/relationships.rb
48
50
  - lib/halitosis/relationships/field.rb
49
51
  - lib/halitosis/resource.rb
52
+ - lib/halitosis/root_links.rb
53
+ - lib/halitosis/root_links/field.rb
54
+ - lib/halitosis/root_meta.rb
55
+ - lib/halitosis/root_meta/field.rb
56
+ - lib/halitosis/root_permissions.rb
57
+ - lib/halitosis/root_permissions/field.rb
50
58
  - lib/halitosis/version.rb
51
59
  - sig/halitosis.rbs
52
60
  homepage: https://github.com/bmorrall/halitosis