sanger-jsonapi-resources 0.1.1 → 0.2.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/LICENSE.txt +1 -1
- data/README.md +35 -12
- data/lib/bug_report_templates/rails_5_latest.rb +125 -0
- data/lib/bug_report_templates/rails_5_master.rb +140 -0
- data/lib/jsonapi/active_relation/adapters/join_left_active_record_adapter.rb +26 -0
- data/lib/jsonapi/active_relation/join_manager.rb +297 -0
- data/lib/jsonapi/active_relation_resource.rb +898 -0
- data/lib/jsonapi/acts_as_resource_controller.rb +130 -113
- data/lib/jsonapi/basic_resource.rb +1164 -0
- data/lib/jsonapi/cached_response_fragment.rb +129 -0
- data/lib/jsonapi/callbacks.rb +2 -0
- data/lib/jsonapi/compatibility_helper.rb +29 -0
- data/lib/jsonapi/compiled_json.rb +13 -1
- data/lib/jsonapi/configuration.rb +88 -21
- data/lib/jsonapi/error.rb +29 -0
- data/lib/jsonapi/error_codes.rb +4 -0
- data/lib/jsonapi/exceptions.rb +82 -50
- data/lib/jsonapi/formatter.rb +5 -3
- data/lib/jsonapi/include_directives.rb +22 -67
- data/lib/jsonapi/link_builder.rb +76 -80
- data/lib/jsonapi/mime_types.rb +6 -10
- data/lib/jsonapi/naive_cache.rb +2 -0
- data/lib/jsonapi/operation.rb +18 -5
- data/lib/jsonapi/operation_result.rb +76 -16
- data/lib/jsonapi/paginator.rb +2 -0
- data/lib/jsonapi/path.rb +45 -0
- data/lib/jsonapi/path_segment.rb +78 -0
- data/lib/jsonapi/processor.rb +193 -115
- data/lib/jsonapi/relationship.rb +145 -14
- data/lib/jsonapi/request.rb +734 -0
- data/lib/jsonapi/resource.rb +3 -1251
- data/lib/jsonapi/resource_controller.rb +2 -0
- data/lib/jsonapi/resource_controller_metal.rb +7 -1
- data/lib/jsonapi/resource_fragment.rb +56 -0
- data/lib/jsonapi/resource_identity.rb +44 -0
- data/lib/jsonapi/resource_serializer.rb +158 -284
- data/lib/jsonapi/resource_set.rb +196 -0
- data/lib/jsonapi/resource_tree.rb +236 -0
- data/lib/jsonapi/resources/railtie.rb +9 -0
- data/lib/jsonapi/resources/version.rb +1 -1
- data/lib/jsonapi/response_document.rb +107 -83
- data/lib/jsonapi/routing_ext.rb +50 -26
- data/lib/jsonapi-resources.rb +23 -5
- data/lib/tasks/check_upgrade.rake +52 -0
- metadata +43 -31
- data/lib/jsonapi/cached_resource_fragment.rb +0 -127
- data/lib/jsonapi/operation_dispatcher.rb +0 -88
- data/lib/jsonapi/operation_results.rb +0 -35
- data/lib/jsonapi/relationship_builder.rb +0 -167
- data/lib/jsonapi/request_parser.rb +0 -678
@@ -1,15 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module JSONAPI
|
2
4
|
class OperationResult
|
3
5
|
attr_accessor :code
|
4
6
|
attr_accessor :meta
|
5
7
|
attr_accessor :links
|
6
8
|
attr_accessor :options
|
9
|
+
attr_accessor :warnings
|
7
10
|
|
8
11
|
def initialize(code, options = {})
|
9
|
-
@code = code
|
12
|
+
@code = Rack::Utils.status_code(code)
|
10
13
|
@options = options
|
11
14
|
@meta = options.fetch(:meta, {})
|
12
15
|
@links = options.fetch(:links, {})
|
16
|
+
@warnings = options.fetch(:warnings, {})
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_hash(serializer = nil)
|
20
|
+
{}
|
13
21
|
end
|
14
22
|
end
|
15
23
|
|
@@ -20,46 +28,98 @@ module JSONAPI
|
|
20
28
|
@errors = errors
|
21
29
|
super(code, options)
|
22
30
|
end
|
31
|
+
|
32
|
+
def to_hash(serializer = nil)
|
33
|
+
{
|
34
|
+
errors: errors.collect do |error|
|
35
|
+
# :nocov:
|
36
|
+
error.to_hash
|
37
|
+
# :nocov:
|
38
|
+
end
|
39
|
+
}
|
40
|
+
end
|
23
41
|
end
|
24
42
|
|
25
|
-
class
|
26
|
-
attr_accessor :
|
43
|
+
class ResourceSetOperationResult < OperationResult
|
44
|
+
attr_accessor :resource_set, :pagination_params
|
27
45
|
|
28
|
-
def initialize(code,
|
29
|
-
@
|
46
|
+
def initialize(code, resource_set, options = {})
|
47
|
+
@resource_set = resource_set
|
48
|
+
@pagination_params = options.fetch(:pagination_params, {})
|
30
49
|
super(code, options)
|
31
50
|
end
|
51
|
+
|
52
|
+
def to_hash(serializer)
|
53
|
+
if serializer
|
54
|
+
serializer.serialize_resource_set_to_hash_single(resource_set)
|
55
|
+
else
|
56
|
+
# :nocov:
|
57
|
+
{}
|
58
|
+
# :nocov:
|
59
|
+
end
|
60
|
+
end
|
32
61
|
end
|
33
62
|
|
34
|
-
class
|
35
|
-
attr_accessor :
|
63
|
+
class ResourcesSetOperationResult < OperationResult
|
64
|
+
attr_accessor :resource_set, :pagination_params, :record_count, :page_count
|
36
65
|
|
37
|
-
def initialize(code,
|
38
|
-
@
|
66
|
+
def initialize(code, resource_set, options = {})
|
67
|
+
@resource_set = resource_set
|
39
68
|
@pagination_params = options.fetch(:pagination_params, {})
|
40
69
|
@record_count = options[:record_count]
|
41
70
|
@page_count = options[:page_count]
|
42
71
|
super(code, options)
|
43
72
|
end
|
73
|
+
|
74
|
+
def to_hash(serializer)
|
75
|
+
if serializer
|
76
|
+
serializer.serialize_resource_set_to_hash_plural(resource_set)
|
77
|
+
else
|
78
|
+
# :nocov:
|
79
|
+
{}
|
80
|
+
# :nocov:
|
81
|
+
end
|
82
|
+
end
|
44
83
|
end
|
45
84
|
|
46
|
-
class
|
47
|
-
attr_accessor :source_resource, :_type
|
85
|
+
class RelatedResourcesSetOperationResult < ResourcesSetOperationResult
|
86
|
+
attr_accessor :resource_set, :source_resource, :_type
|
48
87
|
|
49
|
-
def initialize(code, source_resource, type,
|
88
|
+
def initialize(code, source_resource, type, resource_set, options = {})
|
50
89
|
@source_resource = source_resource
|
51
90
|
@_type = type
|
52
|
-
super(code,
|
91
|
+
super(code, resource_set, options)
|
92
|
+
end
|
93
|
+
|
94
|
+
def to_hash(serializer = nil)
|
95
|
+
if serializer
|
96
|
+
serializer.serialize_related_resource_set_to_hash_plural(resource_set, source_resource)
|
97
|
+
else
|
98
|
+
# :nocov:
|
99
|
+
{}
|
100
|
+
# :nocov:
|
101
|
+
end
|
53
102
|
end
|
54
103
|
end
|
55
104
|
|
56
|
-
class
|
57
|
-
attr_accessor :parent_resource, :relationship
|
105
|
+
class RelationshipOperationResult < OperationResult
|
106
|
+
attr_accessor :parent_resource, :relationship, :resource_ids
|
58
107
|
|
59
|
-
def initialize(code, parent_resource, relationship, options = {})
|
108
|
+
def initialize(code, parent_resource, relationship, resource_ids, options = {})
|
60
109
|
@parent_resource = parent_resource
|
61
110
|
@relationship = relationship
|
111
|
+
@resource_ids = resource_ids
|
62
112
|
super(code, options)
|
63
113
|
end
|
114
|
+
|
115
|
+
def to_hash(serializer = nil)
|
116
|
+
if serializer
|
117
|
+
serializer.serialize_to_relationship_hash(parent_resource, relationship, resource_ids)
|
118
|
+
else
|
119
|
+
# :nocov:
|
120
|
+
{}
|
121
|
+
# :nocov:
|
122
|
+
end
|
123
|
+
end
|
64
124
|
end
|
65
125
|
end
|
data/lib/jsonapi/paginator.rb
CHANGED
data/lib/jsonapi/path.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONAPI
|
4
|
+
class Path
|
5
|
+
attr_reader :segments, :resource_klass
|
6
|
+
def initialize(resource_klass:,
|
7
|
+
path_string:,
|
8
|
+
ensure_default_field: true,
|
9
|
+
parse_fields: true)
|
10
|
+
@resource_klass = resource_klass
|
11
|
+
|
12
|
+
current_resource_klass = resource_klass
|
13
|
+
@segments = path_string.to_s.split('.').collect do |segment_string|
|
14
|
+
segment = PathSegment.parse(source_resource_klass: current_resource_klass,
|
15
|
+
segment_string: segment_string,
|
16
|
+
parse_fields: parse_fields)
|
17
|
+
|
18
|
+
current_resource_klass = segment.resource_klass
|
19
|
+
segment
|
20
|
+
end
|
21
|
+
|
22
|
+
if ensure_default_field && parse_fields && @segments.last.is_a?(PathSegment::Relationship)
|
23
|
+
last = @segments.last
|
24
|
+
@segments << PathSegment::Field.new(resource_klass: last.resource_klass,
|
25
|
+
field_name: last.resource_klass._primary_key)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def relationship_segments
|
30
|
+
@segments.select {|p| p.is_a?(PathSegment::Relationship)}
|
31
|
+
end
|
32
|
+
|
33
|
+
def relationship_path_string
|
34
|
+
relationship_segments.collect(&:to_s).join('.')
|
35
|
+
end
|
36
|
+
|
37
|
+
def last_relationship
|
38
|
+
if @segments.last.is_a?(PathSegment::Relationship)
|
39
|
+
@segments.last
|
40
|
+
else
|
41
|
+
@segments[-2]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONAPI
|
4
|
+
class PathSegment
|
5
|
+
def self.parse(source_resource_klass:, segment_string:, parse_fields: true)
|
6
|
+
first_part, last_part = segment_string.split('#', 2)
|
7
|
+
relationship = source_resource_klass._relationship(first_part)
|
8
|
+
|
9
|
+
if relationship
|
10
|
+
if last_part
|
11
|
+
unless relationship.resource_types.include?(last_part)
|
12
|
+
raise JSONAPI::Exceptions::InvalidRelationship.new(source_resource_klass._type, segment_string)
|
13
|
+
end
|
14
|
+
resource_klass = source_resource_klass.resource_klass_for(last_part)
|
15
|
+
end
|
16
|
+
return PathSegment::Relationship.new(relationship: relationship, resource_klass: resource_klass)
|
17
|
+
else
|
18
|
+
if last_part.blank? && parse_fields
|
19
|
+
return PathSegment::Field.new(resource_klass: source_resource_klass, field_name: first_part)
|
20
|
+
else
|
21
|
+
raise JSONAPI::Exceptions::InvalidRelationship.new(source_resource_klass._type, segment_string)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class Relationship
|
27
|
+
attr_reader :relationship, :resource_klass
|
28
|
+
|
29
|
+
def initialize(relationship:, resource_klass: nil)
|
30
|
+
@relationship = relationship
|
31
|
+
@resource_klass = resource_klass
|
32
|
+
end
|
33
|
+
|
34
|
+
def eql?(other)
|
35
|
+
other.is_a?(self.class) && relationship == other.relationship && resource_klass == other.resource_klass
|
36
|
+
end
|
37
|
+
|
38
|
+
def hash
|
39
|
+
[relationship, resource_klass].hash
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_s
|
43
|
+
@resource_klass ? "#{relationship.parent_resource_klass._type}.#{relationship.name}##{resource_klass._type}" : "#{resource_klass._type}.#{relationship.name}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def resource_klass
|
47
|
+
@resource_klass || relationship.resource_klass
|
48
|
+
end
|
49
|
+
|
50
|
+
def path_specified_resource_klass?
|
51
|
+
!@resource_klass.nil?
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class Field
|
56
|
+
attr_reader :resource_klass, :field_name
|
57
|
+
|
58
|
+
def initialize(resource_klass:, field_name:)
|
59
|
+
@resource_klass = resource_klass
|
60
|
+
@field_name = field_name
|
61
|
+
end
|
62
|
+
|
63
|
+
def eql?(other)
|
64
|
+
other.is_a?(self.class) && field_name == other.field_name && resource_klass == other.resource_klass
|
65
|
+
end
|
66
|
+
|
67
|
+
def delegated_field_name
|
68
|
+
resource_klass._attribute_delegated_name(field_name)
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_s
|
72
|
+
# :nocov:
|
73
|
+
"#{resource_klass._type}.#{field_name.to_s}"
|
74
|
+
# :nocov:
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|