graphiti 1.0.alpha.8 → 1.0.alpha.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/graphiti.rb +1 -2
- data/lib/graphiti/context.rb +3 -3
- data/lib/graphiti/errors.rb +19 -6
- data/lib/graphiti/extensions/boolean_attribute.rb +0 -4
- data/lib/graphiti/extensions/extra_attribute.rb +1 -12
- data/lib/graphiti/extensions/temp_id.rb +0 -4
- data/lib/graphiti/hash_renderer.rb +0 -1
- data/lib/graphiti/query.rb +5 -5
- data/lib/graphiti/resource.rb +5 -1
- data/lib/graphiti/resource/configuration.rb +1 -5
- data/lib/graphiti/resource/dsl.rb +3 -2
- data/lib/graphiti/schema.rb +4 -4
- data/lib/graphiti/schema_diff.rb +11 -11
- data/lib/graphiti/scoping/filter.rb +104 -31
- data/lib/graphiti/serializer.rb +30 -0
- data/lib/graphiti/types.rb +2 -1
- data/lib/graphiti/util/attribute_check.rb +1 -12
- data/lib/graphiti/util/include_params.rb +1 -1
- data/lib/graphiti/util/serializer_attributes.rb +17 -3
- data/lib/graphiti/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: caacb7b46b4b6380d1202102d599ea89292883e4
|
4
|
+
data.tar.gz: e1817089ad066f588c1b7b4d43e595e923bd93fc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c77ef723750a6220eafec17a1312886c75cb20e60fda62ea1a648916c8ddedf4f670abd0be7b7a62806755036aa674f78bb8ec98e587df2c8304e6c89c678d33
|
7
|
+
data.tar.gz: 97aa9cf93a8af91459b402b2379c81a461330fd47a467c5eb79a4a768569a6c15ba4ad2238f08bb41d7563607918d7b30c2dfdc2be5197e8d97cfaf77a3f6fe0
|
data/lib/graphiti.rb
CHANGED
@@ -62,12 +62,11 @@ require "graphiti/util/serializer_attributes"
|
|
62
62
|
require "graphiti/util/serializer_relationships"
|
63
63
|
require "graphiti/util/class"
|
64
64
|
require "graphiti/util/link"
|
65
|
-
|
66
65
|
require 'graphiti/adapters/null'
|
67
|
-
|
68
66
|
require "graphiti/extensions/extra_attribute"
|
69
67
|
require "graphiti/extensions/boolean_attribute"
|
70
68
|
require "graphiti/extensions/temp_id"
|
69
|
+
require "graphiti/serializer"
|
71
70
|
|
72
71
|
if defined?(ActiveRecord)
|
73
72
|
require 'graphiti/adapters/active_record'
|
data/lib/graphiti/context.rb
CHANGED
@@ -3,14 +3,14 @@ module Graphiti
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
module Overrides
|
6
|
-
def
|
6
|
+
def sideload_allowlist=(val)
|
7
7
|
super(JSONAPI::IncludeDirective.new(val).to_hash)
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
11
|
included do
|
12
|
-
class_attribute :
|
13
|
-
self.
|
12
|
+
class_attribute :sideload_allowlist
|
13
|
+
self.sideload_allowlist = {}
|
14
14
|
class << self;prepend Overrides;end
|
15
15
|
end
|
16
16
|
end
|
data/lib/graphiti/errors.rb
CHANGED
@@ -36,16 +36,16 @@ Remove the single: true option to bypass this error.
|
|
36
36
|
end
|
37
37
|
|
38
38
|
class UnsupportedSort < Base
|
39
|
-
def initialize(resource, attribute,
|
39
|
+
def initialize(resource, attribute, allowlist, direction)
|
40
40
|
@resource = resource
|
41
41
|
@attribute = attribute
|
42
|
-
@
|
42
|
+
@allowlist = allowlist
|
43
43
|
@direction = direction
|
44
44
|
end
|
45
45
|
|
46
46
|
def message
|
47
47
|
<<-MSG
|
48
|
-
#{@resource.class.name}: tried to sort on attribute #{@attribute.inspect}, but passed #{@direction.inspect} when only #{@
|
48
|
+
#{@resource.class.name}: tried to sort on attribute #{@attribute.inspect}, but passed #{@direction.inspect} when only #{@allowlist.inspect} is supported.
|
49
49
|
MSG
|
50
50
|
end
|
51
51
|
end
|
@@ -72,12 +72,12 @@ Remove the single: true option to bypass this error.
|
|
72
72
|
|
73
73
|
def message
|
74
74
|
allow = @filter.values[0][:allow]
|
75
|
-
|
75
|
+
deny = @filter.values[0][:deny]
|
76
76
|
msg = <<-MSG
|
77
77
|
#{@resource.class.name}: tried to filter on #{@filter.keys[0].inspect}, but passed invalid value #{@value.inspect}.
|
78
78
|
MSG
|
79
|
-
msg << "\
|
80
|
-
msg << "\
|
79
|
+
msg << "\nAllowlist: #{allow.inspect}" if allow
|
80
|
+
msg << "\nDenylist: #{deny.inspect}" if deny
|
81
81
|
msg
|
82
82
|
end
|
83
83
|
end
|
@@ -192,6 +192,19 @@ Graphiti.config.context_for_endpoint = ->(path, action) { ... }
|
|
192
192
|
end
|
193
193
|
end
|
194
194
|
|
195
|
+
class InvalidJSONArray < Base
|
196
|
+
def initialize(resource, value)
|
197
|
+
@resource = resource
|
198
|
+
@value = value
|
199
|
+
end
|
200
|
+
|
201
|
+
def message
|
202
|
+
<<-MSG
|
203
|
+
#{@resource.class.name}: passed filter with value #{@value.inspect}, and failed attempting to parse as JSON array.
|
204
|
+
MSG
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
195
208
|
class InvalidEndpoint < Base
|
196
209
|
def initialize(resource_class, path, action)
|
197
210
|
@resource_class = resource_class
|
@@ -24,7 +24,7 @@ module Graphiti
|
|
24
24
|
# end
|
25
25
|
# end
|
26
26
|
#
|
27
|
-
# class SerializablePerson <
|
27
|
+
# class SerializablePerson < Graphiti::Serializer
|
28
28
|
# # ... code ...
|
29
29
|
# extra_attribute :net_worth do
|
30
30
|
# @object.assets.sum(&:value)
|
@@ -57,14 +57,3 @@ module Graphiti
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|
60
|
-
|
61
|
-
JSONAPI::Serializable::Resource.class_eval do
|
62
|
-
def self.inherited(klass)
|
63
|
-
super
|
64
|
-
klass.class_eval do
|
65
|
-
extend JSONAPI::Serializable::Resource::ConditionalFields
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
include Graphiti::Extensions::ExtraAttribute
|
70
|
-
end
|
data/lib/graphiti/query.rb
CHANGED
@@ -156,13 +156,13 @@ module Graphiti
|
|
156
156
|
@include_hash ||= begin
|
157
157
|
requested = include_directive.to_hash
|
158
158
|
|
159
|
-
|
160
|
-
if @resource.context && @resource.context.respond_to?(:
|
161
|
-
|
162
|
-
|
159
|
+
allowlist = nil
|
160
|
+
if @resource.context && @resource.context.respond_to?(:sideload_allowlist)
|
161
|
+
allowlist = @resource.context.sideload_allowlist
|
162
|
+
allowlist = allowlist[@resource.context_namespace] if allowlist
|
163
163
|
end
|
164
164
|
|
165
|
-
|
165
|
+
allowlist ? Util::IncludeParams.scrub(requested, allowlist) : requested
|
166
166
|
end
|
167
167
|
|
168
168
|
@include_hash
|
data/lib/graphiti/resource.rb
CHANGED
@@ -62,7 +62,11 @@ module Graphiti
|
|
62
62
|
|
63
63
|
def typecast(name, value, flag)
|
64
64
|
att = get_attr!(name, flag, request: true)
|
65
|
-
|
65
|
+
type_name = att[:type]
|
66
|
+
if flag == :filterable
|
67
|
+
type_name = filters[name][:type]
|
68
|
+
end
|
69
|
+
type = Graphiti::Types[type_name]
|
66
70
|
return if value.nil? && type[:kind] != 'array'
|
67
71
|
begin
|
68
72
|
flag = :read if flag == :readable
|
@@ -134,7 +134,7 @@ module Graphiti
|
|
134
134
|
|
135
135
|
# @api private
|
136
136
|
def infer_serializer_superclass
|
137
|
-
serializer_class =
|
137
|
+
serializer_class = ::Graphiti::Serializer
|
138
138
|
namespace = Util::Class.namespace_for(self)
|
139
139
|
app_serializer = "#{namespace}::ApplicationSerializer"
|
140
140
|
.safe_constantize
|
@@ -185,10 +185,6 @@ module Graphiti
|
|
185
185
|
attributes.merge(extra_attributes)
|
186
186
|
end
|
187
187
|
|
188
|
-
def attribute_cache
|
189
|
-
@attribute_cache ||= all_attributes
|
190
|
-
end
|
191
|
-
|
192
188
|
def sideloads
|
193
189
|
config[:sideloads]
|
194
190
|
end
|
@@ -6,6 +6,7 @@ module Graphiti
|
|
6
6
|
class_methods do
|
7
7
|
def filter(name, *args, &blk)
|
8
8
|
opts = args.extract_options!
|
9
|
+
type_override = args[0]
|
9
10
|
|
10
11
|
if att = get_attr(name, :filterable, raise_error: :only_unsupported)
|
11
12
|
aliases = [name, opts[:aliases]].flatten.compact
|
@@ -19,9 +20,9 @@ module Graphiti
|
|
19
20
|
config[:filters][name.to_sym] = {
|
20
21
|
aliases: aliases,
|
21
22
|
name: name.to_sym,
|
22
|
-
type: att[:type],
|
23
|
+
type: type_override || att[:type],
|
23
24
|
allow: opts[:allow],
|
24
|
-
|
25
|
+
deny: opts[:deny],
|
25
26
|
single: !!opts[:single],
|
26
27
|
dependencies: opts[:dependent],
|
27
28
|
required: required,
|
data/lib/graphiti/schema.rb
CHANGED
@@ -57,9 +57,9 @@ module Graphiti
|
|
57
57
|
end
|
58
58
|
|
59
59
|
actions[a] = { resource: r.name }
|
60
|
-
if
|
61
|
-
if
|
62
|
-
actions[a].merge!(
|
60
|
+
if allowlist = ctx.sideload_allowlist
|
61
|
+
if allowlist[a]
|
62
|
+
actions[a].merge!(sideload_allowlist: allowlist[a])
|
63
63
|
end
|
64
64
|
end
|
65
65
|
end
|
@@ -165,7 +165,7 @@ module Graphiti
|
|
165
165
|
|
166
166
|
config[:single] = true if filter[:single]
|
167
167
|
config[:allow] = filter[:allow].map(&:to_s) if filter[:allow]
|
168
|
-
config[:
|
168
|
+
config[:deny] = filter[:deny].map(&:to_s) if filter[:deny]
|
169
169
|
config[:dependencies] = filter[:dependencies].map(&:to_s) if filter[:dependencies]
|
170
170
|
|
171
171
|
attr = resource.attributes[name]
|
data/lib/graphiti/schema_diff.rb
CHANGED
@@ -173,16 +173,16 @@ module Graphiti
|
|
173
173
|
old = old_filter[:allow] || []
|
174
174
|
diff = new - old
|
175
175
|
if diff.length > 0
|
176
|
-
@errors << "#{old_resource[:name]}: filter #{name.inspect}
|
176
|
+
@errors << "#{old_resource[:name]}: filter #{name.inspect} allowlist went from #{old.inspect} to #{new.inspect}."
|
177
177
|
end
|
178
178
|
end
|
179
179
|
|
180
|
-
if new_filter[:
|
181
|
-
new = new_filter[:
|
182
|
-
old = old_filter[:
|
180
|
+
if new_filter[:deny] != old_filter[:deny]
|
181
|
+
new = new_filter[:deny] || []
|
182
|
+
old = old_filter[:deny] || []
|
183
183
|
diff = new - old
|
184
184
|
if diff.length > 0
|
185
|
-
@errors << "#{old_resource[:name]}: filter #{name.inspect}
|
185
|
+
@errors << "#{old_resource[:name]}: filter #{name.inspect} denylist went from #{old.inspect} to #{new.inspect}."
|
186
186
|
end
|
187
187
|
end
|
188
188
|
|
@@ -215,16 +215,16 @@ module Graphiti
|
|
215
215
|
next
|
216
216
|
end
|
217
217
|
|
218
|
-
if new_action[:
|
219
|
-
@errors << "Endpoint \"#{path}\" added sideload
|
218
|
+
if new_action[:sideload_allowlist] && !old_action[:sideload_allowlist]
|
219
|
+
@errors << "Endpoint \"#{path}\" added sideload allowlist."
|
220
220
|
end
|
221
221
|
|
222
|
-
if new_action[:
|
223
|
-
if new_action[:
|
222
|
+
if new_action[:sideload_allowlist]
|
223
|
+
if new_action[:sideload_allowlist] != old_action[:sideload_allowlist]
|
224
224
|
removal = Util::Hash.include_removed? \
|
225
|
-
new_action[:
|
225
|
+
new_action[:sideload_allowlist], old_action[:sideload_allowlist]
|
226
226
|
if removal
|
227
|
-
@errors << "Endpoint \"#{path}\" had incompatible sideload
|
227
|
+
@errors << "Endpoint \"#{path}\" had incompatible sideload allowlist. Was #{old_action[:sideload_allowlist].inspect}, now #{new_action[:sideload_allowlist].inspect}."
|
228
228
|
end
|
229
229
|
end
|
230
230
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
module Graphiti
|
2
2
|
# Apply filtering logic to the scope
|
3
3
|
#
|
4
|
-
# If the user requests to filter a field that has not been
|
4
|
+
# If the user requests to filter a field that has not been allowlisted,
|
5
5
|
# a +Graphiti::Errors::BadFilter+ error will be raised.
|
6
6
|
#
|
7
|
-
# allow_filter :title # :title now
|
7
|
+
# allow_filter :title # :title now allowlisted
|
8
8
|
#
|
9
|
-
# If the user requests a filter field that has been
|
9
|
+
# If the user requests a filter field that has been allowlisted, but
|
10
10
|
# does not pass the associated `+:if+ clause, +BadFilter+ will be raised.
|
11
11
|
#
|
12
12
|
# allow_filter :title, if: :admin?
|
@@ -72,39 +72,19 @@ module Graphiti
|
|
72
72
|
def each_filter
|
73
73
|
filter_param.each_pair do |param_name, param_value|
|
74
74
|
filter = find_filter!(param_name)
|
75
|
-
|
76
|
-
value
|
77
|
-
|
78
|
-
value =
|
79
|
-
|
80
|
-
|
81
|
-
if filter.values[0][:single] && value.is_a?(Array)
|
82
|
-
raise Errors::SingularFilter.new(resource, filter, value)
|
83
|
-
end
|
84
|
-
|
85
|
-
value = coerce_types(param_name.to_sym, value)
|
86
|
-
|
87
|
-
value.each do |v|
|
88
|
-
if allow = filter.values[0][:allow]
|
89
|
-
unless allow.include?(v)
|
90
|
-
raise Errors::InvalidFilterValue.new(resource, filter, value)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
if reject = filter.values[0][:reject]
|
95
|
-
if reject.include?(v)
|
96
|
-
raise Errors::InvalidFilterValue.new(resource, filter, value)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
75
|
+
value, operator = normalize_param(filter, param_value)
|
76
|
+
value = parse_string_value(filter.values[0], value) if value.is_a?(String)
|
77
|
+
validate_singular(resource, filter, value)
|
78
|
+
value = coerce_types(filter.values[0], param_name.to_sym, value)
|
79
|
+
validate_allowlist(resource, filter, value)
|
80
|
+
validate_denylist(resource, filter, value)
|
101
81
|
value = value[0] if filter.values[0][:single]
|
102
82
|
yield filter, operator, value
|
103
83
|
end
|
104
84
|
end
|
105
85
|
|
106
|
-
def coerce_types(name, value)
|
107
|
-
type_name =
|
86
|
+
def coerce_types(filter, name, value)
|
87
|
+
type_name = filter[:type]
|
108
88
|
is_array = type_name.to_s.starts_with?('array_of') ||
|
109
89
|
Types[type_name][:canonical_name] == :array
|
110
90
|
|
@@ -115,5 +95,98 @@ module Graphiti
|
|
115
95
|
value.map { |v| @resource.typecast(name, v, :filterable) }
|
116
96
|
end
|
117
97
|
end
|
98
|
+
|
99
|
+
def normalize_param(filter, param_value)
|
100
|
+
param_value = { eq: param_value } unless param_value.is_a?(Hash)
|
101
|
+
value = param_value.values.first
|
102
|
+
operator = param_value.keys.first
|
103
|
+
|
104
|
+
if filter.values[0][:type] == :hash
|
105
|
+
value, operator = \
|
106
|
+
parse_hash_value(filter, param_value, value, operator)
|
107
|
+
else
|
108
|
+
value = param_value.values.first
|
109
|
+
end
|
110
|
+
|
111
|
+
[value, operator]
|
112
|
+
end
|
113
|
+
|
114
|
+
def validate_singular(resource, filter, value)
|
115
|
+
if filter.values[0][:single] && value.is_a?(Array)
|
116
|
+
raise Errors::SingularFilter.new(resource, filter, value)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def validate_allowlist(resource, filter, values)
|
121
|
+
values.each do |v|
|
122
|
+
if allow = filter.values[0][:allow]
|
123
|
+
unless allow.include?(v)
|
124
|
+
raise Errors::InvalidFilterValue.new(resource, filter, v)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def validate_denylist(resource, filter, values)
|
131
|
+
values.each do |v|
|
132
|
+
if deny = filter.values[0][:deny]
|
133
|
+
if deny.include?(v)
|
134
|
+
raise Errors::InvalidFilterValue.new(resource, filter, v)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def parse_hash_value(filter, param_value, value, operator)
|
141
|
+
if operator != :eq
|
142
|
+
operator = :eq
|
143
|
+
value = param_value
|
144
|
+
end
|
145
|
+
|
146
|
+
if value.is_a?(String)
|
147
|
+
value = value.gsub('{{{', '{').gsub('}}}', '}')
|
148
|
+
end
|
149
|
+
|
150
|
+
[value, operator]
|
151
|
+
end
|
152
|
+
|
153
|
+
# foo,bar,baz becomes ["foo", "bar", "baz"] (unless array type)
|
154
|
+
# {{foo}} becomes ["foo"]
|
155
|
+
# {{foo,bar}},baz becomes ["foo,bar", "baz"]
|
156
|
+
#
|
157
|
+
# JSON of
|
158
|
+
# {{{ "id": 1 }}} becomes { 'id' => 1 }
|
159
|
+
def parse_string_value(filter, value)
|
160
|
+
type = Graphiti::Types[filter[:type]]
|
161
|
+
array_or_string = [:string, :array].include?(type[:canonical_name])
|
162
|
+
if (arr = value.scan(/\[.*?\]/)).present? && array_or_string
|
163
|
+
value = arr.map do |json|
|
164
|
+
begin
|
165
|
+
JSON.parse(json)
|
166
|
+
rescue
|
167
|
+
raise Errors::InvalidJSONArray.new(resource, value)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
value = value[0] if value.length == 1
|
171
|
+
else
|
172
|
+
value = parse_string_arrays(value)
|
173
|
+
end
|
174
|
+
value
|
175
|
+
end
|
176
|
+
|
177
|
+
def parse_string_arrays(value)
|
178
|
+
# Find the quoted strings
|
179
|
+
quotes = value.scan(/{{.*?}}/)
|
180
|
+
# remove them from the rest
|
181
|
+
quotes.each { |q| value.gsub!(q, '') }
|
182
|
+
# remove the quote characters from the quoted strings
|
183
|
+
quotes.each { |q| q.gsub!('{{', '').gsub!('}}', '') }
|
184
|
+
# merge everything back together into an array
|
185
|
+
value = Array(value.split(',')) + quotes
|
186
|
+
# remove any blanks that are left
|
187
|
+
value.reject! { |v| v.length.zero? }
|
188
|
+
value = value[0] if value.length == 1
|
189
|
+
value
|
190
|
+
end
|
118
191
|
end
|
119
192
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Graphiti
|
2
|
+
class Serializer < JSONAPI::Serializable::Resource
|
3
|
+
include Graphiti::Extensions::BooleanAttribute
|
4
|
+
include Graphiti::Extensions::ExtraAttribute
|
5
|
+
include Graphiti::SerializableHash
|
6
|
+
prepend Graphiti::SerializableTempId
|
7
|
+
|
8
|
+
def self.inherited(klass)
|
9
|
+
super
|
10
|
+
klass.class_eval do
|
11
|
+
extend JSONAPI::Serializable::Resource::ConditionalFields
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Temporary fix until fixed upstream
|
16
|
+
# https://github.com/jsonapi-rb/jsonapi-serializable/pull/102
|
17
|
+
def requested_relationships(fields)
|
18
|
+
@_relationships
|
19
|
+
end
|
20
|
+
|
21
|
+
# Allow access to resource methods
|
22
|
+
def method_missing(id, *args, &blk)
|
23
|
+
if @resource.respond_to?(id, true)
|
24
|
+
@resource.send(id, *args, &blk)
|
25
|
+
else
|
26
|
+
super
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/graphiti/types.rb
CHANGED
@@ -69,7 +69,8 @@ module Graphiti
|
|
69
69
|
end
|
70
70
|
|
71
71
|
PresentParamsHash = create(::Hash) do |input|
|
72
|
-
|
72
|
+
input = JSON.parse(input) if input.is_a?(String)
|
73
|
+
Dry::Types['params.hash'][input]
|
73
74
|
end
|
74
75
|
|
75
76
|
REQUIRED_KEYS = [:params, :read, :write, :kind, :description]
|
@@ -56,10 +56,6 @@ module Graphiti
|
|
56
56
|
attribute[flag] != :required
|
57
57
|
end
|
58
58
|
|
59
|
-
def cache?
|
60
|
-
!!@cache
|
61
|
-
end
|
62
|
-
|
63
59
|
def error_class
|
64
60
|
Errors::AttributeError
|
65
61
|
end
|
@@ -68,15 +64,8 @@ module Graphiti
|
|
68
64
|
attribute[flag] != false
|
69
65
|
end
|
70
66
|
|
71
|
-
# If running in a request context, we've already loaded everything
|
72
|
-
# and there's no reason to perform logic, so go through attriubte cache
|
73
|
-
# Otherwise, this is a performance hit during typecasting
|
74
67
|
def attribute
|
75
|
-
@attribute ||=
|
76
|
-
resource.class.attribute_cache[name]
|
77
|
-
else
|
78
|
-
resource.all_attributes[name]
|
79
|
-
end
|
68
|
+
@attribute ||= resource.all_attributes[name]
|
80
69
|
end
|
81
70
|
|
82
71
|
def attribute?
|
@@ -57,20 +57,34 @@ module Graphiti
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
+
def typecast(type)
|
61
|
+
_resource = @resource
|
62
|
+
_name = @name
|
63
|
+
_type = type
|
64
|
+
->(value) {
|
65
|
+
begin
|
66
|
+
_type[value] unless value.nil?
|
67
|
+
rescue Exception => e
|
68
|
+
raise Errors::TypecastFailed.new(_resource, _name, value, e)
|
69
|
+
end
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
60
73
|
def default_proc
|
61
74
|
_name = @name
|
62
75
|
_resource = @resource.new
|
76
|
+
_typecast = typecast(Graphiti::Types[@attr[:type]][:read])
|
63
77
|
->(_) {
|
64
|
-
|
78
|
+
_typecast.call(@object.send(_name))
|
65
79
|
}
|
66
80
|
end
|
67
81
|
|
68
82
|
def wrap_proc(inner)
|
69
83
|
_resource = @resource.new
|
70
84
|
_name = @name
|
85
|
+
_typecast = typecast(Graphiti::Types[@attr[:type]][:read])
|
71
86
|
->(serializer_instance = nil) {
|
72
|
-
|
73
|
-
_resource.typecast(_name, value, :readable)
|
87
|
+
_typecast.call(serializer_instance.instance_eval(&inner))
|
74
88
|
}
|
75
89
|
end
|
76
90
|
|
data/lib/graphiti/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphiti
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.alpha.
|
4
|
+
version: 1.0.alpha.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lee Richmond
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-08-
|
11
|
+
date: 2018-08-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jsonapi-serializable
|
@@ -278,6 +278,7 @@ files:
|
|
278
278
|
- lib/graphiti/scoping/filterable.rb
|
279
279
|
- lib/graphiti/scoping/paginate.rb
|
280
280
|
- lib/graphiti/scoping/sort.rb
|
281
|
+
- lib/graphiti/serializer.rb
|
281
282
|
- lib/graphiti/sideload.rb
|
282
283
|
- lib/graphiti/sideload/belongs_to.rb
|
283
284
|
- lib/graphiti/sideload/has_many.rb
|