motion-json-api 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b00c290ef84e915cf55ea3e6f7d3a9e68a096951
4
+ data.tar.gz: 95b4a777808fe8751731487f047604f46648b3ad
5
+ SHA512:
6
+ metadata.gz: 9184db4c31abc1e0646ea541d82d3f6d862fb5203f0fb6d51799ceaf16d7f75ea986b91e29d0e65fcab46a5b9f32c07a102a8069d3c9485b350f4d738a51fe6a
7
+ data.tar.gz: da1a3ed70b72a6af029eb7ef090dd1f03ea357cbc76e544c90404ff2f3cfbe1a8c6d462559e5af16c52fc9c7f9194f969d0ace50898e47c195cef464e2ae34fe
data/LICENSE.txt ADDED
@@ -0,0 +1,8 @@
1
+ The MIT License (MIT)
2
+ Copyright (c) 2016 Joffrey Jaffeux
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5
+
6
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7
+
8
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # MotionJsonApi
2
+
3
+ A small library that helps you transform JSONApi server responses into objects.
4
+
5
+ Note: this gem is not intended to create valid JSON Api payload to send to a server.
6
+ If you have this need, feel free to contribute.
7
+
8
+
9
+ ## Usage
10
+
11
+ ```ruby
12
+
13
+ # Define resources
14
+ class User < MotionJsonApi::Resource
15
+ resource_type :users
16
+
17
+ attribute :name
18
+
19
+ has_one :blog
20
+ end
21
+
22
+ class Blog < MotionJsonApi::Resource
23
+ resource_type :blogs
24
+
25
+ attribute :title
26
+ has_many :articles
27
+ end
28
+
29
+ class Article < MotionJsonApi::Resource
30
+ resource_type :articles
31
+
32
+ attribute :title
33
+ attribute :body
34
+
35
+ has_one :user, as: :author
36
+ end
37
+
38
+ resource = MotionJsonApi.parse(server_response)
39
+
40
+ resource.user
41
+ resource.user.name
42
+ resource.user.blog
43
+ resource.user.blog.title
44
+ resource.user.blog.articles
45
+ resource.user.blog.articles.first.author
46
+
47
+ resource.links
48
+ resource.meta
49
+
50
+ resource.user.links
51
+ ```
52
+
53
+ ## Run tests
54
+
55
+ ```
56
+ bundle install
57
+ rake test
58
+ ```
@@ -0,0 +1,8 @@
1
+ require 'motion-json-api/exceptions'
2
+ require 'motion-json-api/resource'
3
+
4
+ module MotionJsonApi
5
+ def self.parse(json)
6
+ Resource._object_handler(json, json.fetch("data", []), json.fetch("included", []))
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ module MotionJsonApi
2
+ class UndefinedResource < StandardError; end
3
+ end
@@ -0,0 +1,100 @@
1
+ module MotionJsonApi
2
+ class Resource
3
+ attr_accessor :id
4
+ attr_accessor :attributes
5
+ attr_accessor :relationships
6
+ attr_accessor :meta
7
+ attr_accessor :links
8
+ attr_accessor :top_level
9
+ attr_accessor :included
10
+
11
+ def initialize(object, top_level = [], included = [])
12
+ @id = object["data"]["id"]
13
+ @attributes = object["data"]["attributes"]
14
+ @relationships = object["data"]["relationships"]
15
+ @meta = object.fetch("meta", {})
16
+ @links = object.fetch("links", {})
17
+ @top_level = top_level
18
+ @included = included
19
+ end
20
+
21
+ @_resource_type = nil
22
+ def self.resource_type(resource_type)
23
+ @_resource_type = resource_type
24
+ end
25
+
26
+ def self._resource_type
27
+ @_resource_type
28
+ end
29
+
30
+ def self.attribute(attribute)
31
+ define_method(attribute) do
32
+ self.attributes.fetch(attribute.to_s)
33
+ end
34
+ end
35
+
36
+ def self.has_one(relation, options = {})
37
+ key = options.fetch(:as, relation).to_s
38
+ define_method(key) do
39
+ relationship = self.relationships.fetch(key)
40
+ data = relationship.fetch("data")
41
+ object = _find_in_included(data["id"], data["type"])
42
+ payload = {"data" => object, "links" => relationship.fetch("links", {})}
43
+ Resource._object_handler(payload, self.top_level, self.included)
44
+ end
45
+ end
46
+
47
+ def self.has_many(relation, options = {})
48
+ key = options.fetch(:as, relation).to_s
49
+ define_method(key) do
50
+ relationship = self.relationships.fetch(key)
51
+ relationship.fetch("data").map do |data|
52
+ object = _find_in_included(data["id"], data["type"])
53
+ Resource._object_handler({"data" => object}, self.top_level, self.included)
54
+ end
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def _find_in_included(id, type)
61
+ object = self.included.find { |x| x["id"] == id && x["type"] == type }
62
+ if object.nil?
63
+ object = self.top_level.find { |x| x["id"] == id && x["type"] == type }
64
+ end
65
+ object
66
+ end
67
+
68
+ def self._klass_for_type(type)
69
+ resource_klass = Resource._descendants.select do |klass|
70
+ type == klass._resource_type.to_s
71
+ end.first
72
+
73
+ unless resource_klass
74
+ raise UndefinedResource, "Couldn’t find defined resource for type: #{type}"
75
+ end
76
+
77
+ resource_klass
78
+ end
79
+
80
+ def self._descendants
81
+ ObjectSpace.each_object(Class).select { |klass| klass < self }
82
+ end
83
+
84
+ def self._object_handler(object, top_level, included = nil)
85
+ included ||= self.included || object.fetch("included", [])
86
+ top_level ||= self.top_level || [object["data"]].flatten
87
+
88
+ case object["data"]
89
+ when Array
90
+ return object["data"].map do |data|
91
+ resource_klass = Resource._klass_for_type(data["type"])
92
+ resource_klass.new({"data" => data}, top_level, included)
93
+ end
94
+ when Hash
95
+ resource_klass = Resource._klass_for_type(object["data"]["type"])
96
+ resource_klass.new(object, top_level, included)
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,3 @@
1
+ module MotionJsonApi
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: motion-json-api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Joffrey Jaffeux
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-11-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.12'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.12'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.9'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.9'
55
+ description: A small library that helps you transform JSONApi server responses into
56
+ objects.
57
+ email:
58
+ - j.jaffeux@gmail.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - LICENSE.txt
64
+ - README.md
65
+ - lib/motion-json-api.rb
66
+ - lib/motion-json-api/exceptions.rb
67
+ - lib/motion-json-api/resource.rb
68
+ - lib/motion-json-api/version.rb
69
+ homepage: https://github.com/jjaffeux/motion-json-api
70
+ licenses:
71
+ - MIT
72
+ metadata: {}
73
+ post_install_message:
74
+ rdoc_options: []
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ requirements: []
88
+ rubyforge_project:
89
+ rubygems_version: 2.5.1
90
+ signing_key:
91
+ specification_version: 4
92
+ summary: Simplified JSONApi client for RubyMotion iOS apps.
93
+ test_files: []