wcc-jsonapi 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a0508ec8a9f9a06c3e595e95fc0858fb223c5d5d
4
+ data.tar.gz: eb6da7214a9f625b6a59e6f04a7873f46f762ce5
5
+ SHA512:
6
+ metadata.gz: 7bdf2b4539b048ba97d79f462c8752dcff1974b3863e38b5569cfce071b33d9cb5e677cbf184ed973ba33d4fb2cf7d68e78d7f69af01d577f9e27ea59ec126b4
7
+ data.tar.gz: 25aca96f9d68022dd7fa2e244d6fde81e4c42492e70fabfd02f5c135314870988c22df21127f764c4f99b9ea54661201b41f76105d0b58cb8a1d4791f5be9c65
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
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 wcc-api.gemspec
6
+ gemspec
data/LICENSE.txt ADDED
File without changes
data/README.md ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
@@ -0,0 +1,9 @@
1
+ module WCC::JsonAPI
2
+ class ClientGenerator < Rails::Generators::Base
3
+ desc "Generates a client from an OpenAPI specification"
4
+
5
+ def do_something
6
+ puts self.inspect
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,54 @@
1
+ module WCC::API::ActiveRecordShim
2
+ def self.included(base)
3
+ base.public_send :include, InstanceMethods
4
+ base.extend ClassMethods
5
+ end
6
+
7
+ module InstanceMethods
8
+ def attributes
9
+ raw.keys.each_with_object({}) do |key, h|
10
+ next unless respond_to?(key)
11
+
12
+ val = public_send(key)
13
+ h[key] =
14
+ if val.is_a? Array
15
+ val.map { |v| v.respond_to?(:to_h) ? v.to_h : v }
16
+ else
17
+ val.respond_to?(:to_h) ? val.to_h : val
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ module ClassMethods
24
+ def model_name
25
+ name
26
+ end
27
+
28
+ def table_name
29
+ endpoint
30
+ end
31
+
32
+ def unscoped
33
+ yield
34
+ end
35
+
36
+ def find_in_batches(options, &block)
37
+ options = options ? options.dup : {}
38
+ batch_size = options.delete(:batch_size) || 1000
39
+
40
+ filter = {
41
+ limit: batch_size,
42
+ offset: options.delete(:start) || 0
43
+ }
44
+
45
+ find_all(filter).each_slice(batch_size, &block)
46
+ end
47
+
48
+ def where(**conditions)
49
+ # TODO: return a Query object that implements more of the ActiveRecord query interface
50
+ # https://guides.rubyonrails.org/active_record_querying.html#conditions
51
+ find_all(conditions)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WCC::JsonAPI
4
+ class BaseClient
5
+ class ApiError < StandardError
6
+ attr_reader :response
7
+
8
+ def self.[](code)
9
+ case code
10
+ when 404
11
+ NotFoundError
12
+ else
13
+ ApiError
14
+ end
15
+ end
16
+
17
+ def initialize(response)
18
+ @response = response
19
+ super(response.error_message)
20
+ end
21
+ end
22
+
23
+ class NotFoundError < ApiError
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+ require_relative 'api_error'
5
+
6
+ module WCC::JsonAPI
7
+ class BaseClient
8
+ class BaseResponse
9
+ extend ::Forwardable
10
+
11
+ attr_reader :raw_response
12
+ attr_reader :raw_body
13
+ attr_reader :client
14
+ attr_reader :request
15
+
16
+ def_delegators :raw_response, :status, :headers
17
+ alias_method :code, :status
18
+
19
+ def body
20
+ @body ||= ::JSON.parse(raw_body)
21
+ end
22
+ alias_method :to_json, :body
23
+
24
+ def initialize(client, request, raw_response)
25
+ @client = client
26
+ @request = request
27
+ @raw_response = raw_response
28
+ @raw_body = raw_response.body.to_s
29
+ end
30
+
31
+ def skip
32
+ body.dig('meta', 'skip')
33
+ end
34
+
35
+ def count
36
+ body.dig('meta', 'total')
37
+ end
38
+
39
+ def data
40
+ body['data']
41
+ end
42
+
43
+ def links
44
+ @links ||= OpenStruct.new(body['links'])
45
+ end
46
+
47
+ def collection_response?
48
+ data.is_a?(Array) ? true : false
49
+ end
50
+
51
+ def error_message
52
+ parsed_message =
53
+ begin
54
+ body.dig('error', 'message') || body.dig('message')
55
+ rescue ::JSON::ParserError
56
+ nil
57
+ end
58
+ parsed_message || "#{code}: #{raw_response.body}"
59
+ end
60
+
61
+ def next_page?
62
+ return false unless collection_response?
63
+ return false if count.nil?
64
+
65
+ page_items.length + skip < count
66
+ end
67
+
68
+ def next_page
69
+ return unless next_page?
70
+
71
+ @next_page ||= @client.get(
72
+ @request[:url],
73
+ (@request[:query] || {}).merge(next_page_query)
74
+ )
75
+ @next_page.assert_ok!
76
+ end
77
+
78
+ def assert_ok!
79
+ return self if code >= 200 && code < 300
80
+
81
+ raise ApiError[code], self
82
+ end
83
+
84
+ # This method has a bit of complexity that is better kept in one location
85
+ def each_page(&block)
86
+ raise ArgumentError, 'Not a collection response' unless collection_response?
87
+
88
+ ret =
89
+ Enumerator.new do |y|
90
+ y << self
91
+
92
+ if next_page?
93
+ next_page.each_page.each do |page|
94
+ y << page
95
+ end
96
+ end
97
+ end
98
+
99
+ if block_given?
100
+ ret.map(&block)
101
+ else
102
+ ret.lazy
103
+ end
104
+ end
105
+
106
+ def items
107
+ return unless collection_response?
108
+
109
+ each_page.flat_map(&:page_items)
110
+ end
111
+
112
+ def first
113
+ raise ArgumentError, 'Not a collection response' unless collection_response?
114
+
115
+ page_items.first
116
+ end
117
+
118
+ def next_page_query
119
+ return unless collection_response?
120
+
121
+ {
122
+ skip: page_items.length + skip
123
+ }
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ gem 'http'
4
+ require 'http'
5
+
6
+ module WCC::JsonAPI
7
+ class BaseClient
8
+ class HttpAdapter
9
+ def call(url, query, headers = {}, proxy = {})
10
+ if proxy[:host]
11
+ HTTP[headers].via(proxy[:host], proxy[:port], proxy[:username], proxy[:password])
12
+ .get(url, params: query)
13
+ else
14
+ HTTP[headers].get(url, params: query)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+ gem 'typhoeus'
5
+ require 'typhoeus'
6
+
7
+ class WCC::JsonAPI::BaseClient::TyphoeusAdapter
8
+ def get(url, params = {}, headers = {})
9
+ req = OpenStruct.new(params: params, headers: headers)
10
+ yield req if block_given?
11
+ Response.new(
12
+ Typhoeus.get(
13
+ url,
14
+ params: req.params,
15
+ headers: req.headers
16
+ )
17
+ )
18
+ end
19
+
20
+ def post(url, body, headers = {})
21
+ Response.new(
22
+ Typhoeus.post(
23
+ url,
24
+ body: body.is_a?(String) ? body : body.to_json,
25
+ headers: headers
26
+ )
27
+ )
28
+ end
29
+
30
+ def put(url, body, headers = {})
31
+ Response.new(
32
+ Typhoeus.put(
33
+ url,
34
+ body: body.is_a?(String) ? body : body.to_json,
35
+ headers: headers
36
+ )
37
+ )
38
+ end
39
+
40
+ def delete(url, query = {}, headers = {})
41
+ Response.new(
42
+ Typhoeus.delete(
43
+ url,
44
+ headers: headers
45
+ )
46
+ )
47
+ end
48
+
49
+ class Response < SimpleDelegator
50
+ def raw
51
+ __getobj__
52
+ end
53
+
54
+ def to_s
55
+ body&.to_s
56
+ end
57
+
58
+ def status
59
+ code
60
+ end
61
+ end
62
+ end
63
+
@@ -0,0 +1,142 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'wcc'
4
+ require_relative 'base_client/response'
5
+ require_relative 'base_client/builder'
6
+ require_relative 'active_record_shim'
7
+
8
+ module WCC::JsonAPI
9
+ class BaseClient
10
+ attr_reader :api_url
11
+
12
+ def initialize(api_url:, headers: nil, **options)
13
+ # normalizes a URL to have a slash on the end
14
+ @api_url = api_url.gsub(/\/+$/, '') + '/'
15
+
16
+ @adapter = BaseClient.load_adapter(options[:adapter])
17
+
18
+ @options = options
19
+ @query_defaults = {}
20
+ @headers = {
21
+ 'Accept' => 'application/json'
22
+ }.merge(headers || {}).freeze
23
+ @response_class = options[:response_class] || BaseResponse
24
+ end
25
+
26
+ # performs an HTTP GET request to the specified path within the configured
27
+ # space and environment. Query parameters are merged with the defaults and
28
+ # appended to the request.
29
+ def get(path, query = {})
30
+ url = URI.join(@api_url, path)
31
+
32
+ @response_class.new(self,
33
+ { url: url, query: query },
34
+ get_http(url, query))
35
+ end
36
+
37
+ def post(path, body = {})
38
+ url = URI.join(@api_url, path)
39
+
40
+ @response_class.new(self,
41
+ { url: url },
42
+ post_http(url,
43
+ body.to_json,
44
+ headers: { 'Content-Type': 'application/json' }))
45
+ end
46
+
47
+ def put(path, body = {})
48
+ url = URI.join(@api_url, path)
49
+
50
+ @response_class.new(self,
51
+ { url: url },
52
+ put_http(url,
53
+ body.to_json,
54
+ headers: { 'Content-Type': 'application/json' }))
55
+ end
56
+
57
+ def delete(path)
58
+ url = URI.join(@api_url, path)
59
+
60
+ @response_class.new(self,
61
+ { url: url },
62
+ delete_http(url))
63
+ end
64
+
65
+ ADAPTERS = {
66
+ faraday: ['faraday', '~> 0.9'],
67
+ typhoeus: ['typhoeus', '~> 1.0']
68
+ }.freeze
69
+
70
+ def self.load_adapter(adapter)
71
+ case adapter
72
+ when nil
73
+ ADAPTERS.each do |a, spec|
74
+ begin
75
+ gem(*spec)
76
+ return load_adapter(a)
77
+ rescue Gem::LoadError
78
+ next
79
+ end
80
+ end
81
+ raise ArgumentError, 'Unable to load adapter! Please install one of '\
82
+ "#{ADAPTERS.values.map(&:join).join(',')}"
83
+ when :faraday
84
+ require 'faraday'
85
+ ::Faraday.new do |faraday|
86
+ faraday.response :logger, (Rails.logger if defined?(Rails)), { headers: false, bodies: false }
87
+ faraday.adapter :net_http
88
+ end
89
+ when :typhoeus
90
+ require_relative 'base_client/typhoeus_adapter'
91
+ TyphoeusAdapter.new
92
+ else
93
+ unless adapter.respond_to?(:get)
94
+ raise ArgumentError, "Adapter #{adapter} is not invokeable! Please "\
95
+ "pass use one of #{ADAPTERS.keys} or create a Faraday-compatible adapter"
96
+ end
97
+ adapter
98
+ end
99
+ end
100
+
101
+ private
102
+
103
+ def get_http(url, query, headers = {})
104
+ headers = @headers.merge(headers || {})
105
+
106
+ q = @query_defaults.dup
107
+ q = q.merge(query) if query
108
+
109
+ resp = @adapter.get(url, q, headers)
110
+
111
+ resp = get_http(resp.headers['location'], nil, headers) if [301, 302, 307].include?(resp.status) && !@options[:no_follow_redirects]
112
+ resp
113
+ end
114
+
115
+ def post_http(url, body, headers: {})
116
+ headers = @headers.merge(headers || {})
117
+
118
+ resp = @adapter.post(url, body, headers)
119
+
120
+ resp = get_http(resp.headers['location'], nil, headers) if [301, 302, 307].include?(resp.status) && !@options[:no_follow_redirects]
121
+ resp
122
+ end
123
+
124
+ def put_http(url, body, headers: {})
125
+ headers = @headers.merge(headers || {})
126
+
127
+ resp = @adapter.put(url, body, headers)
128
+
129
+ resp = get_http(resp.headers['location'], nil, headers) if [301, 302, 307].include?(resp.status) && !@options[:no_follow_redirects]
130
+ resp
131
+ end
132
+
133
+ def delete_http(url, headers: {})
134
+ headers = @headers.merge(headers || {})
135
+
136
+ resp = @adapter.delete(url, {}, headers)
137
+
138
+ resp = get_http(resp.headers['location'], nil, headers) if [301, 302, 307].include?(resp.status) && !@options[:no_follow_redirects]
139
+ resp
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WCC
4
+ module JsonAPI
5
+ VERSION = '0.1.0'
6
+ end
7
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'wcc/json_api/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'wcc-jsonapi'
9
+ spec.version = WCC::JsonAPI::VERSION
10
+ spec.authors = ['Watermark Dev']
11
+ spec.email = ['dev@watermark.org']
12
+ spec.summary =
13
+ spec.description = 'Generates ruby clients for OpenAPI endpoints conforming'\
14
+ 'to the JsonAPI convention'
15
+ spec.homepage = 'https://github.com/watermarkchurch/wcc-api'
16
+ spec.license = 'MIT'
17
+
18
+ spec.files = `git ls-files -z`.split("\x0")
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
+ spec.require_paths = ['lib']
22
+
23
+ spec.add_dependency "openapi_parser", ">= 0.11.1", "< 1.0"
24
+
25
+ spec.add_development_dependency 'bundler', '~> 1.6'
26
+ spec.add_development_dependency 'dotenv', '~> 0.10.0'
27
+ spec.add_development_dependency 'faraday', '~> 0.9'
28
+ spec.add_development_dependency 'guard', '~> 2.15'
29
+ spec.add_development_dependency 'guard-rspec', '~> 4.7'
30
+ spec.add_development_dependency 'guard-rubocop', '~> 1.3'
31
+ spec.add_development_dependency 'httplog', '~> 1.0'
32
+ spec.add_development_dependency 'rake', '~> 12.3'
33
+ spec.add_development_dependency 'rspec', '~> 3.3'
34
+ spec.add_development_dependency 'rspec_junit_formatter', '~> 0.3.0'
35
+ spec.add_development_dependency 'rubocop', '0.69.0'
36
+ spec.add_development_dependency 'typhoeus', '~> 1.3'
37
+ spec.add_development_dependency 'webmock', '~> 3.0'
38
+ end
metadata ADDED
@@ -0,0 +1,261 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wcc-jsonapi
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Watermark Dev
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-10-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: openapi_parser
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.11.1
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '1.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 0.11.1
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '1.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: bundler
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.6'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.6'
47
+ - !ruby/object:Gem::Dependency
48
+ name: dotenv
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: 0.10.0
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: 0.10.0
61
+ - !ruby/object:Gem::Dependency
62
+ name: faraday
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '0.9'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '0.9'
75
+ - !ruby/object:Gem::Dependency
76
+ name: guard
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '2.15'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '2.15'
89
+ - !ruby/object:Gem::Dependency
90
+ name: guard-rspec
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '4.7'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '4.7'
103
+ - !ruby/object:Gem::Dependency
104
+ name: guard-rubocop
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '1.3'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '1.3'
117
+ - !ruby/object:Gem::Dependency
118
+ name: httplog
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '1.0'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '1.0'
131
+ - !ruby/object:Gem::Dependency
132
+ name: rake
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: '12.3'
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - "~>"
143
+ - !ruby/object:Gem::Version
144
+ version: '12.3'
145
+ - !ruby/object:Gem::Dependency
146
+ name: rspec
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - "~>"
150
+ - !ruby/object:Gem::Version
151
+ version: '3.3'
152
+ type: :development
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: '3.3'
159
+ - !ruby/object:Gem::Dependency
160
+ name: rspec_junit_formatter
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - "~>"
164
+ - !ruby/object:Gem::Version
165
+ version: 0.3.0
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - "~>"
171
+ - !ruby/object:Gem::Version
172
+ version: 0.3.0
173
+ - !ruby/object:Gem::Dependency
174
+ name: rubocop
175
+ requirement: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - '='
178
+ - !ruby/object:Gem::Version
179
+ version: 0.69.0
180
+ type: :development
181
+ prerelease: false
182
+ version_requirements: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - '='
185
+ - !ruby/object:Gem::Version
186
+ version: 0.69.0
187
+ - !ruby/object:Gem::Dependency
188
+ name: typhoeus
189
+ requirement: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - "~>"
192
+ - !ruby/object:Gem::Version
193
+ version: '1.3'
194
+ type: :development
195
+ prerelease: false
196
+ version_requirements: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - "~>"
199
+ - !ruby/object:Gem::Version
200
+ version: '1.3'
201
+ - !ruby/object:Gem::Dependency
202
+ name: webmock
203
+ requirement: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - "~>"
206
+ - !ruby/object:Gem::Version
207
+ version: '3.0'
208
+ type: :development
209
+ prerelease: false
210
+ version_requirements: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - "~>"
213
+ - !ruby/object:Gem::Version
214
+ version: '3.0'
215
+ description: Generates ruby clients for OpenAPI endpoints conformingto the JsonAPI
216
+ convention
217
+ email:
218
+ - dev@watermark.org
219
+ executables: []
220
+ extensions: []
221
+ extra_rdoc_files: []
222
+ files:
223
+ - ".gitignore"
224
+ - Gemfile
225
+ - LICENSE.txt
226
+ - README.md
227
+ - Rakefile
228
+ - lib/generators/wcc/json_api/client_generator.rb
229
+ - lib/wcc/json_api/active_record_shim.rb
230
+ - lib/wcc/json_api/base_client.rb
231
+ - lib/wcc/json_api/base_client/api_error.rb
232
+ - lib/wcc/json_api/base_client/base_response.rb
233
+ - lib/wcc/json_api/base_client/http_adapter.rb
234
+ - lib/wcc/json_api/base_client/typhoeus_adapter.rb
235
+ - lib/wcc/json_api/version.rb
236
+ - wcc-jsonapi.gemspec
237
+ homepage: https://github.com/watermarkchurch/wcc-api
238
+ licenses:
239
+ - MIT
240
+ metadata: {}
241
+ post_install_message:
242
+ rdoc_options: []
243
+ require_paths:
244
+ - lib
245
+ required_ruby_version: !ruby/object:Gem::Requirement
246
+ requirements:
247
+ - - ">="
248
+ - !ruby/object:Gem::Version
249
+ version: '0'
250
+ required_rubygems_version: !ruby/object:Gem::Requirement
251
+ requirements:
252
+ - - ">="
253
+ - !ruby/object:Gem::Version
254
+ version: '0'
255
+ requirements: []
256
+ rubyforge_project:
257
+ rubygems_version: 2.5.2.3
258
+ signing_key:
259
+ specification_version: 4
260
+ summary: Generates ruby clients for OpenAPI endpoints conformingto the JsonAPI convention
261
+ test_files: []