jsonapi_helpers 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3e0943785b54133ddee5a1597e8f83ebb2336bd1
4
- data.tar.gz: 456c0ab8c77f0db5c3f70d6d658179218ac39838
3
+ metadata.gz: e7c7204fad99ba81fb2677c0bcaf99655ca3991b
4
+ data.tar.gz: a2e3a050fee11dea4c56c4caa8f51602204db2c0
5
5
  SHA512:
6
- metadata.gz: bee0ed026e233e84b95ccc18b64c5a0f0a851e0c29c85d32ed50286beec3433d12b74918d99b74be8971fe5bee419bf280e897684dc6bb16259262d2560b6da3
7
- data.tar.gz: 3df19149d25c943a0ae7c0242ded7d08ebea0053a82d25f9f8326955b646ca65db1ca72a61dd658958118aae425aa253db9c9a0e2cef2f8767c18c9933087052
6
+ metadata.gz: 3b6897227e38470925b03f6d5747556abee220ddaf689b1345795d06e25117cd70df3ee507b158be04d20ee4378cdeca4f24b79e60a1cff57c59ee9f707c96cc
7
+ data.tar.gz: 4a866970c77fe525ee3486b6180353cd867fc8d31654202cff3eaba0f893666bc45907c4c8f351c5a147ea61de7438bdf0ed1709f8faa9e2cc4353f0980f27ae
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ .byebug_history
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.4.1
5
+ before_install: gem install bundler -v 1.12.5
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in jsonapi_helpers.gemspec
6
+ gemspec
File without changes
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ lib = File.expand_path('../lib', __FILE__)
5
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
+ require 'jsonapi_helpers/version'
7
+
8
+ Gem::Specification.new do |spec|
9
+ spec.name = 'jsonapi_helpers'
10
+ spec.version = JSONAPIHelpers::VERSION
11
+ spec.authors = ['Jacob Burenstam']
12
+ spec.email = ['burenstam@gmail.com']
13
+
14
+ spec.summary = 'A set of helpers for generating JSON API compliant responses.'
15
+ spec.description = 'A set of helpers for generating JSON API compliant responses with together with the active_model_serializers gem.' # rubocop:disable Metrics/LineLength
16
+ spec.homepage = 'https://github.com/buren/jsonapi_helpers'
17
+ spec.license = 'MIT'
18
+
19
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
20
+ f.match(%r{^(test|spec|features)/})
21
+ end
22
+ spec.bindir = 'exe'
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ['lib']
25
+
26
+ spec.add_dependency 'activesupport', '>= 4.2'
27
+
28
+ spec.add_development_dependency 'active_model_serializers', '~> 0.10'
29
+ spec.add_development_dependency 'activemodel', '>= 4.2'
30
+ spec.add_development_dependency 'bundler', '~> 1.12'
31
+ spec.add_development_dependency 'rake', '~> 10.0'
32
+ spec.add_development_dependency 'rspec', '~> 3.0'
33
+ spec.add_development_dependency 'byebug', '~> 9.0'
34
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/object/json'
4
+
5
+ # Local requires
6
+ require 'jsonapi_helpers/version'
7
+
8
+ require 'jsonapi_helpers/support/key_transform'
9
+ require 'jsonapi_helpers/support/string_support'
10
+
11
+ require 'jsonapi_helpers/serializers/deserializer'
12
+ require 'jsonapi_helpers/serializers/model'
13
+ require 'jsonapi_helpers/serializers/model_error'
14
+ require 'jsonapi_helpers/serializers/data'
15
+ require 'jsonapi_helpers/serializers/datum'
16
+ require 'jsonapi_helpers/serializers/error'
17
+ require 'jsonapi_helpers/serializers/errors'
18
+
19
+ require 'jsonapi_helpers/params/fields'
20
+ require 'jsonapi_helpers/params/filter'
21
+ require 'jsonapi_helpers/params/includes'
22
+ require 'jsonapi_helpers/params/sort'
23
+
24
+ module JSONAPIHelpers
25
+ class << self
26
+ attr_accessor :config
27
+ end
28
+
29
+ def self.configure
30
+ self.config ||= Configuration.new
31
+ block_given? ? yield(config) : config
32
+ config
33
+ end
34
+
35
+ class Configuration
36
+ KEY_TRANSFORMS = %i(dash camel camel_lower underscore unaltered).freeze
37
+
38
+ attr_reader :key_transform
39
+ attr_writer :deserializer_klass, :params_klass
40
+
41
+ def initialize
42
+ @key_transform = :unaltered
43
+ @deserializer_klass = nil
44
+ @params_klass = nil
45
+ end
46
+
47
+ def key_transform=(key_transform)
48
+ type = key_transform.to_sym
49
+ unknown_key_transform!(type) unless KEY_TRANSFORMS.include?(type)
50
+
51
+ @key_transform = type
52
+ end
53
+
54
+ def deserializer_klass
55
+ @deserializer_klass || fail('deserializer_klass must be set, e.g: ActiveModelSerializers::Deserialization') # rubocop:disable Metrics/LineLength
56
+ end
57
+
58
+ def params_klass
59
+ @params_klass || fail('params_klass must be set, e.g: ActionController::Parameters')
60
+ end
61
+
62
+ private
63
+
64
+ def unknown_key_transform!(type)
65
+ types = KEY_TRANSFORMS.join(', ')
66
+ fail(ArgumentError, "Unknown key transform type '#{type}', known types: #{types}")
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JSONAPIHelpers
4
+ module Params
5
+ class Fields
6
+ attr_reader :fields_params
7
+
8
+ def initialize(fields_params)
9
+ @fields_params = {}
10
+ (fields_params || {}).each do |model_name, value|
11
+ @fields_params[model_name] = value.split(',').map do |name|
12
+ StringSupport.underscore(name.strip)
13
+ end
14
+ end
15
+ end
16
+
17
+ def to_h
18
+ fields_params
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'date'
4
+
5
+ module JSONAPIHelpers
6
+ module Params
7
+ module Filter
8
+ def self.build(filters, allowed, transform = {})
9
+ return {} if filters.nil? || filters.is_a?(String)
10
+
11
+ filtered = {}
12
+ filters.each do |key, value|
13
+ key_sym = StringSupport.underscore(key).to_sym
14
+ if allowed.include?(key_sym)
15
+ filtered[key_sym] = format_value(value, transform[key_sym])
16
+ end
17
+ end
18
+ filtered
19
+ end
20
+
21
+ def self.format_value(value, type)
22
+ case type
23
+ when :date_range
24
+ format_date_range(value)
25
+ else
26
+ value
27
+ end
28
+ end
29
+
30
+ def self.format_date_range(value)
31
+ date_parts = value.split('..')
32
+ start = _parse_date_string(date_parts.first)
33
+ finish = _parse_date_string(date_parts.last)
34
+ start..finish
35
+ rescue ArgumentError
36
+ nil
37
+ end
38
+
39
+ def self._parse_date_string(string)
40
+ Date.parse(string, false)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JSONAPIHelpers
4
+ module Params
5
+ class Includes
6
+ attr_reader :include_param
7
+
8
+ def initialize(include_param)
9
+ @include_param = StringSupport.underscore(include_param || '')
10
+ end
11
+
12
+ def permit(*permitted_includes)
13
+ include_array = include_param.split(',')
14
+ include_array & permitted_includes.flatten(1)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JSONAPIHelpers
4
+ module Params
5
+ module Sort
6
+ def self.build(sort, allowed, default)
7
+ allowed = allowed.map(&:to_s)
8
+ fields = sort.to_s.split(',')
9
+
10
+ ordered_fields = convert_to_ordered_hash(fields)
11
+ filtered_fields = ordered_fields.select { |key, _value| allowed.include?(key) }
12
+ filtered_fields.empty? ? default : filtered_fields
13
+ end
14
+
15
+ def self.convert_to_ordered_hash(fields)
16
+ fields.each_with_object({}) do |field, hash|
17
+ if field.start_with?('-')
18
+ field = StringSupport.underscore(field[1..-1])
19
+ hash[field] = :desc
20
+ else
21
+ hash[StringSupport.underscore(field)] = :asc
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/hash/keys'
4
+ require 'jsonapi_helpers/serializers/relationships'
5
+
6
+ module JSONAPIHelpers
7
+ module Serializers
8
+ class Data
9
+ def initialize(
10
+ id:,
11
+ type:,
12
+ attributes: {},
13
+ meta: {},
14
+ relationships: nil,
15
+ key_transform: JSONAPIHelpers.config.key_transform
16
+ )
17
+ @id = id
18
+ @type = type
19
+ @attributes = attributes
20
+ @meta = meta
21
+ @relationships = relationships
22
+ @key_transform = key_transform
23
+ end
24
+
25
+ def to_h(shallow: false)
26
+ data = {
27
+ id: @id,
28
+ type: KeyTransform.call(@type.to_s, key_transform: @key_transform),
29
+ attributes: KeyTransform.call(@attributes, key_transform: @key_transform)
30
+ }
31
+
32
+ if @relationships
33
+ data[:relationships] = KeyTransform.call(
34
+ @relationships.to_h,
35
+ key_transform: @key_transform
36
+ )
37
+ end
38
+
39
+ if shallow
40
+ data
41
+ else
42
+ { data: data, meta: @meta }
43
+ end
44
+ end
45
+
46
+ # Rails is awkward and calls #to_json with a context argument
47
+ # NOTE: Rails only method Hash#to_json
48
+ def to_json(_context = nil)
49
+ to_h.to_json
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JSONAPIHelpers
4
+ module Serializers
5
+ class Datum
6
+ def initialize(jsonapi_datums)
7
+ @datums = jsonapi_datums
8
+ end
9
+
10
+ def to_h
11
+ {
12
+ data: @datums.map { |data| data.to_h(shallow: true) },
13
+ meta: {
14
+ total: @datums.length
15
+ }
16
+ }
17
+ end
18
+
19
+ # Rails is awkward and calls #to_json with a context argument
20
+ # NOTE: Rails only method Hash#to_json
21
+ def to_json(_context = nil)
22
+ to_h.to_json
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JSONAPIHelpers
4
+ module Serializers
5
+ module Deserializer
6
+ def self.parse(params)
7
+ # Parse the params hash and "flatten" the structure
8
+ parsed_params = JSONAPIHelpers.config.deserializer_klass.jsonapi_parse(params)
9
+ # Pass the hash to a params klass where normal whitelisting of params can be made
10
+ JSONAPIHelpers.config.params_klass.new(parsed_params || {})
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JSONAPIHelpers
4
+ module Serializers
5
+ class Error
6
+ attr_reader :status, :detail, :code
7
+
8
+ def initialize(
9
+ detail:,
10
+ status: 422,
11
+ code: nil,
12
+ pointer: nil,
13
+ attribute: nil,
14
+ key_transform: JSONAPIHelpers.config.key_transform
15
+ )
16
+ @status = status
17
+ @detail = detail
18
+ @pointer = pointer(
19
+ pointer: pointer,
20
+ attribute: attribute,
21
+ key_transform: key_transform
22
+ )
23
+ @code = code
24
+ end
25
+
26
+ def to_h
27
+ response = { status: @status, detail: @detail }
28
+ response[:code] = @code unless @code.nil?
29
+ response.merge!(@pointer)
30
+ end
31
+
32
+ private
33
+
34
+ def pointer(pointer:, attribute:, key_transform:)
35
+ return {} if pointer.nil? && attribute.nil?
36
+
37
+ full_pointer = if pointer
38
+ pointer
39
+ else
40
+ attribute_pointer(attribute, key_transform: key_transform)
41
+ end
42
+ {
43
+ source: {
44
+ pointer: full_pointer
45
+ }
46
+ }
47
+ end
48
+
49
+ def attribute_pointer(attribute, key_transform:)
50
+ attribute_name = KeyTransform.call(attribute.to_s, key_transform: key_transform)
51
+ "/data/attributes/#{attribute_name}"
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JSONAPIHelpers
4
+ module Serializers
5
+ class Errors
6
+ include Enumerable
7
+
8
+ def initialize
9
+ @errors = []
10
+ end
11
+
12
+ def add(**args)
13
+ @errors << Error.new(**args)
14
+ end
15
+
16
+ def each(&block)
17
+ @errors.each(&block)
18
+ end
19
+
20
+ def length
21
+ @errors.length
22
+ end
23
+ alias_method :size, :length
24
+
25
+ def to_h
26
+ { errors: @errors.map(&:to_h) }
27
+ end
28
+
29
+ # Rails is awkward and calls #to_json with a context argument
30
+ # NOTE: Rails only method Hash#to_json
31
+ def to_json(_context = nil)
32
+ to_h.to_json
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jsonapi_helpers/action_dispatch_request_wrapper'
4
+
5
+ module JSONAPIHelpers
6
+ module Serializers
7
+ class Model
8
+ attr_reader :serializer, :included, :fields, :current_user, :current_language, :model_scope, :meta, :request, :key_transform # rubocop:disable Metrics/LineLength
9
+
10
+ def self.serialize(*args)
11
+ new(*args).serialize
12
+ end
13
+
14
+ # private
15
+
16
+ def initialize(
17
+ model_scope,
18
+ included: [],
19
+ fields: {},
20
+ current_user: nil,
21
+ current_language: nil,
22
+ meta: {},
23
+ request: nil,
24
+ key_transform: JSONAPIHelpers.config.key_transform
25
+ )
26
+ @model_scope = model_scope
27
+ @included = included
28
+ @fields = fields
29
+ @meta = meta
30
+ @current_user = current_user
31
+ @current_language = current_language
32
+ @key_transform = key_transform
33
+ # NOTE: ActiveModel::Serializer#serializer_for is from active_model_serializers
34
+ @serializer = ActiveModel::Serializer.serializer_for(model_scope)
35
+ @request = ActionDispatchRequestWrapper.new(request)
36
+ end
37
+
38
+ def serializer_instance
39
+ serializer_options = {
40
+ scope: {
41
+ current_user: current_user,
42
+ current_language: current_language,
43
+ current_language_id: current_language&.id
44
+ }
45
+ }
46
+
47
+ if @model_scope.respond_to?(:to_ary)
48
+ serializer_options[:each_serializer] = serializer
49
+ end
50
+
51
+ serializer.new(@model_scope, serializer_options)
52
+ end
53
+
54
+ def serialize
55
+ # NOTE: ActiveModelSerializers::Adapter#create is from active_model_serializers
56
+ ActiveModelSerializers::Adapter.create(
57
+ serializer_instance,
58
+ key_transform: key_transform,
59
+ include: included,
60
+ fields: fields,
61
+ meta: meta,
62
+ serialization_context: request
63
+ )
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'set'
4
+
5
+ module JSONAPIHelpers
6
+ module Serializers
7
+ module ModelError
8
+ KNOWN_ERROR_TYPES = Set.new(%i(
9
+ accepted
10
+ blank
11
+ confirmation
12
+ empty
13
+ equal_to
14
+ even
15
+ exclusion
16
+ greater_than
17
+ greater_than_or_equal_to
18
+ inclusion
19
+ invalid
20
+ less_than
21
+ less_than_or_equal_to
22
+ not_a_number
23
+ not_an_integer
24
+ odd
25
+ other_than
26
+ present
27
+ required
28
+ taken
29
+ too_long
30
+ too_short
31
+ wrong_length
32
+ )).freeze
33
+
34
+ def self.serialize(model, key_transform: JSONAPIHelpers.config.key_transform)
35
+ model.errors.details.flat_map do |field, errors|
36
+ errors.map do |error|
37
+ attribute_name = KeyTransform.call(field.to_s, key_transform: key_transform)
38
+
39
+ {
40
+ status: 422,
41
+ source: { pointer: "/data/attributes/#{attribute_name}" },
42
+ detail: error_message_for(model.errors, field, error),
43
+ meta: error_meta_for(error)
44
+ }
45
+ end
46
+ end
47
+ end
48
+
49
+ def self.error_message_for(model_errors, field, error)
50
+ message = error.fetch(:error)
51
+ return message if message.is_a?(String) # expects it to already be translated
52
+
53
+ model_errors.generate_message(field, message, count: error[:count])
54
+ end
55
+
56
+ def self.error_meta_for(error)
57
+ meta = {
58
+ type: error_type_for(error.fetch(:error))
59
+ }
60
+ meta[:count] = error[:count] if error[:count]
61
+ meta[:value] = error[:value] if error[:value]
62
+ meta
63
+ end
64
+
65
+ def self.error_type_for(error_type)
66
+ return error_type if KNOWN_ERROR_TYPES.include?(error_type)
67
+ :invalid
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/hash/keys'
4
+
5
+ module JSONAPIHelpers
6
+ module Serializers
7
+ class Relationships
8
+ def initialize
9
+ @relationships = {}
10
+ end
11
+
12
+ def add(relation:, id:, type:)
13
+ @relationships[relation] = { id: id, type: type }
14
+ end
15
+
16
+ def to_h
17
+ @relationships
18
+ end
19
+
20
+ # Rails is awkward and calls #to_json with a context argument
21
+ # NOTE: Rails only method Hash#to_json
22
+ def to_json(_context = nil)
23
+ to_h.to_json
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/string'
4
+ require 'active_support/core_ext/hash/keys'
5
+
6
+ # Slightly modified from https://github.com/rails-api/active_model_serializers/blob/a1826186e556b4aa6cbe2a2588df8b2186e06252/lib/active_model_serializers/key_transform.rb
7
+ module JSONAPIHelpers
8
+ module KeyTransform
9
+ module_function
10
+
11
+ def call(object, key_transform: nil)
12
+ key_transform ||= JSONAPIHelpers.config.key_transform
13
+ public_send(key_transform, object)
14
+ end
15
+
16
+ # Transforms values to UpperCamelCase or PascalCase.
17
+ #
18
+ # @example:
19
+ # "some_key" => "SomeKey",
20
+ def camel(value)
21
+ case value
22
+ when Hash then value.deep_transform_keys! { |key| camel(key) }
23
+ when Symbol then camel(value.to_s).to_sym
24
+ when String then StringSupport.camel(value)
25
+ else value
26
+ end
27
+ end
28
+
29
+ # Transforms values to camelCase.
30
+ #
31
+ # @example:
32
+ # "some_key" => "someKey",
33
+ def camel_lower(value)
34
+ case value
35
+ when Hash then value.deep_transform_keys! { |key| camel_lower(key) }
36
+ when Symbol then camel_lower(value.to_s).to_sym
37
+ when String then StringSupport.camel_lower(value)
38
+ else value
39
+ end
40
+ end
41
+
42
+ # Transforms values to dashed-case.
43
+ # This is the default case for the JsonApi adapter.
44
+ #
45
+ # @example:
46
+ # "some_key" => "some-key",
47
+ def dash(value)
48
+ case value
49
+ when Hash then value.deep_transform_keys! { |key| dash(key) }
50
+ when Symbol then dash(value.to_s).to_sym
51
+ when String then StringSupport.dash(value)
52
+ else value
53
+ end
54
+ end
55
+
56
+ # Transforms values to underscore_case.
57
+ # This is the default case for deserialization in the JsonApi adapter.
58
+ #
59
+ # @example:
60
+ # "some-key" => "some_key",
61
+ def underscore(value)
62
+ case value
63
+ when Hash then value.deep_transform_keys! { |key| underscore(key) }
64
+ when Symbol then underscore(value.to_s).to_sym
65
+ when String then StringSupport.underscore(value)
66
+ else value
67
+ end
68
+ end
69
+
70
+ # Returns the value unaltered
71
+ def unaltered(value)
72
+ value
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JSONAPIHelpers
4
+ module StringSupport
5
+ module_function
6
+
7
+ def camel(string)
8
+ string.underscore.camelize
9
+ end
10
+
11
+ def camel_lower(string)
12
+ string.underscore.camelize(:lower)
13
+ end
14
+
15
+ def dash(string)
16
+ string.underscore.dasherize
17
+ end
18
+
19
+ def underscore(string)
20
+ string.underscore
21
+ end
22
+ end
23
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module JSONAPIHelpers
4
4
  MAJOR = '0'
5
- MINOR = '1'
6
- PATCH = '1'
5
+ MINOR = '2'
6
+ PATCH = '0'
7
7
  VERSION = [MAJOR, MINOR, PATCH].join('.').freeze
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonapi_helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jacob Burenstam
@@ -116,11 +116,32 @@ executables: []
116
116
  extensions: []
117
117
  extra_rdoc_files: []
118
118
  files:
119
+ - ".gitignore"
120
+ - ".rspec"
121
+ - ".travis.yml"
122
+ - Gemfile
119
123
  - LICENSE.txt
120
- - README.MD
124
+ - README.md
125
+ - Rakefile
121
126
  - bin/console
122
127
  - bin/setup
128
+ - jsonapi_helpers.gemspec
129
+ - lib/jsonapi_helpers.rb
123
130
  - lib/jsonapi_helpers/action_dispatch_request_wrapper.rb
131
+ - lib/jsonapi_helpers/params/fields.rb
132
+ - lib/jsonapi_helpers/params/filter.rb
133
+ - lib/jsonapi_helpers/params/includes.rb
134
+ - lib/jsonapi_helpers/params/sort.rb
135
+ - lib/jsonapi_helpers/serializers/data.rb
136
+ - lib/jsonapi_helpers/serializers/datum.rb
137
+ - lib/jsonapi_helpers/serializers/deserializer.rb
138
+ - lib/jsonapi_helpers/serializers/error.rb
139
+ - lib/jsonapi_helpers/serializers/errors.rb
140
+ - lib/jsonapi_helpers/serializers/model.rb
141
+ - lib/jsonapi_helpers/serializers/model_error.rb
142
+ - lib/jsonapi_helpers/serializers/relationships.rb
143
+ - lib/jsonapi_helpers/support/key_transform.rb
144
+ - lib/jsonapi_helpers/support/string_support.rb
124
145
  - lib/jsonapi_helpers/version.rb
125
146
  homepage: https://github.com/buren/jsonapi_helpers
126
147
  licenses: