graphiti 1.0.alpha.8 → 1.0.alpha.9
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/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
|