introspective_grape 0.4.3 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/lint.yml +23 -0
  3. data/.github/workflows/test.yml +18 -0
  4. data/.rubocop.yml +84 -1173
  5. data/.ruby-version +1 -1
  6. data/CHANGELOG.md +19 -0
  7. data/Gemfile +3 -5
  8. data/README.md +95 -63
  9. data/Rakefile +1 -6
  10. data/introspective_grape.gemspec +63 -51
  11. data/lib/introspective_grape/api.rb +167 -136
  12. data/lib/introspective_grape/camel_snake.rb +5 -3
  13. data/lib/introspective_grape/create_helpers.rb +3 -5
  14. data/lib/introspective_grape/doc.rb +19 -5
  15. data/lib/introspective_grape/filters.rb +98 -83
  16. data/lib/introspective_grape/formatter/camel_json.rb +2 -3
  17. data/lib/introspective_grape/helpers.rb +55 -48
  18. data/lib/introspective_grape/snake_params.rb +1 -2
  19. data/lib/introspective_grape/traversal.rb +33 -31
  20. data/lib/introspective_grape/validators.rb +23 -23
  21. data/lib/introspective_grape/version.rb +3 -1
  22. data/spec/dummy/Gemfile +5 -4
  23. data/spec/dummy/app/api/api_helpers.rb +1 -1
  24. data/spec/dummy/app/api/dummy/company_api.rb +1 -1
  25. data/spec/dummy/app/api/dummy/project_api.rb +1 -0
  26. data/spec/dummy/app/api/dummy/sessions.rb +1 -1
  27. data/spec/dummy/app/api/dummy_api.rb +8 -2
  28. data/spec/dummy/app/assets/config/manifest.js +4 -0
  29. data/spec/dummy/app/models/user.rb +1 -1
  30. data/spec/dummy/config/database.yml +1 -1
  31. data/spec/rails_helper.rb +1 -1
  32. metadata +147 -42
  33. data/.coveralls.yml +0 -2
  34. data/.travis.yml +0 -40
  35. data/bin/rails +0 -12
  36. data/gemfiles/Gemfile.rails.5.0.0 +0 -14
  37. data/gemfiles/Gemfile.rails.5.0.1 +0 -14
  38. data/gemfiles/Gemfile.rails.5.1.0 +0 -14
  39. data/gemfiles/Gemfile.rails.5.2.0 +0 -14
  40. data/gemfiles/Gemfile.rails.master +0 -14
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.3.0
1
+ 2.5.0
data/CHANGELOG.md CHANGED
@@ -1,3 +1,22 @@
1
+ 0.5.0 10/20/2021
2
+ ================
3
+
4
+ Bring support up to Rails 5.2.6 and ruby 2.6.2.
5
+
6
+ All Virtus::Attribute::Boolean parameters should be declared Grape::API::Boolean instead.
7
+
8
+ Change the filters on unique identifiers to Array[String] to support non-integer indeces,
9
+ which is backwards compat with Array[Integer] as ActiveRecord's find coerces strings properly.
10
+
11
+ Update Kaminari pagination declarations from
12
+
13
+ ``` paginate per_page: klass.pagination[:per_page]||25, max_per_page: klass.pagination[:max_per_page], offset: klass.pagination[:offset]||0```
14
+
15
+ to
16
+
17
+ ``` use :pagination, per_page: klass.pagination[:per_page]||25, max_per_page: klass.pagination[:max_per_page], offset: klass.pagination[:offset]||0```
18
+
19
+
1
20
  0.4.1 10/20/2020
2
21
  ================
3
22
 
data/Gemfile CHANGED
@@ -1,20 +1,18 @@
1
1
  source 'https://rubygems.org'
2
+ gemspec
2
3
 
3
4
  # Declare your gem's dependencies in introspective_grape.gemspec.
4
5
  # Bundler will treat runtime dependencies like base dependencies, and
5
6
  # development dependencies will be added by default to the :development group.
6
- gemspec
7
-
8
- gem 'grape-kaminari', :github => 'alexey-klimuk/grape-kaminari'
9
7
 
10
- gem 'coveralls', require: false
11
8
 
12
9
  # Declare any dependencies that are still in development here instead of in
13
10
  # your gemspec. These might include edge Rails or gems from your path or
14
11
  # Git. Remember to move these dependencies to your gemspec before releasing
15
12
  # your gem to rubygems.org.
16
13
 
17
- group :development do
14
+ group :development, :test do
18
15
  gem 'byebug'
19
16
  gem 'rb-readline'
17
+ gem 'coveralls_reborn', require: false
20
18
  end
data/README.md CHANGED
@@ -1,79 +1,64 @@
1
1
  # IntrospectiveGrape
2
2
 
3
3
  [![Gem Version][GV img]][Gem Version]
4
- [![Build Status][BS img]][Build Status]
5
- [![Dependency Status][DS img]][Dependency Status]
6
4
  [![Coverage Status][CS img]][Coverage Status]
5
+ [![Tests](https://github.com/buermann/introspective_grape/actions/workflows/test.yml/badge.svg)][Tests]
6
+ [![Lints](https://github.com/buermann/introspective_grape/actions/workflows/lint.yml/badge.svg)][Lints]
7
7
 
8
+ [Tests]: https://github.com/buermann/introspective_grape/actions
9
+ [Lints]: https://github.com/buermann/introspective_grape/actions
8
10
  [Gem Version]: https://rubygems.org/gems/introspective_grape
9
- [Build Status]: https://travis-ci.org/buermann/introspective_grape
10
- [travis pull requests]: https://travis-ci.org/buermann/introspective_grape/pull_requests
11
- [Dependency Status]: https://gemnasium.com/buermann/introspective_grape
12
11
  [Coverage Status]: https://coveralls.io/r/buermann/introspective_grape
13
12
 
14
13
  [GV img]: https://badge.fury.io/rb/introspective_grape.png
15
- [BS img]: https://travis-ci.org/buermann/introspective_grape.png
16
- [DS img]: https://gemnasium.com/buermann/introspective_grape.png
17
14
  [CS img]: https://coveralls.io/repos/buermann/introspective_grape/badge.png?branch=master
18
15
 
16
+ IntrospectiveGrape is a rails plugin for DRYing up
17
+ [Grape APIs](https://github.com/ruby-grape/grape) by laying out simple
18
+ (or, if you like, very complex) RESTful defaults based on the introspection of your database by
19
+ [SchemaPlusValidations](https://github.com/SchemaPlus/schema_validations).
19
20
 
20
- IntrospectiveGrape is a Rails Plugin for DRYing up Grape APIs by laying out simple
21
- RESTful defaults based on the model definitions. If you use a schema validator
22
- like [SchemaPlus](https://github.com/SchemaPlus/schema_plus) it will, by
23
- extension, define your endpoints according to your database schema.
24
-
25
- It provides handling for deeply nested relations according to the models'
21
+ IntrospectiveGrape provides handling for deeply nested relations according to the models'
26
22
  `accepts_nested_attributes_for` declarations, generating all the necessary
27
23
  boilerplate for flexible and consistent bulk endpoints on plural associations,
28
24
  and building nested routes for the same.
29
25
 
30
- It also snake cases everything coming in and camelizes parameters in your swagger docs
31
- by default if you `require 'introspective_grape/camel_snake'` in your API.
32
- This behavior can be disabled.
26
+ It relies on [Kaminari](https://github.com/kaminari/kaminari) for pagination and [Pundit](https://github.com/varvet/pundit) for authorization, both of which are semi-optional.
27
+
28
+ To facilitate idiomatic ruby and javascript, respectively, it also makes it easy to snakecase incoming parameters and camelize outputs, all the way through to your swagger docs.
33
29
 
34
- In addition it provides a `IntrospectiveGrape::Formatter::CamelJson` json formatter to
35
- recursively camelize the keys of all your outputs, so ruby and javascript developers
36
- can speak in their own idioms.
30
+ NOTE: SchemaPlus is not currently being maintained and is unavailable for Rails > 2.5, and thus so is
31
+ IntrospectiveGrape. Which is too bad! I don't know how anybody with a relational database gets by
32
+ without it. We're working on it when we get the chance.
37
33
 
38
34
  ## Documentation
39
35
 
40
36
  In your Gemfile:
41
37
 
42
38
  ```
43
- gem 'grape-kaminari', :github => 'alexey-klimuk/grape-kaminari' # some middleware has fallen into deep disrepair
44
39
  gem 'introspective_grape'
45
40
  ```
46
41
 
47
42
  And bundle install.
48
43
 
49
-
50
44
  ## Grape Configuration
51
45
 
52
46
  ### Camelization
53
47
 
54
- IntrospectiveGrape's default behavior is to camelize all outputs and snake case all inputs. To camel case all your json output you'll need to use its formatter in your API:
48
+ To camelcase your JSON outputs you'll need to use IntrospectiveGrape's formatter in your API:
55
49
 
56
50
  ```
57
- formatter :json, IntrospectiveGrape::Formatter::CamelJson
51
+ require 'introspective_grape/camel_snake'
52
+ class MyAPI < Grape::API
53
+ formatter :json, IntrospectiveGrape::Formatter::CamelJson
54
+ end
58
55
  ```
59
56
 
60
- It also defaults to monkey patching Grape::Swagger to camelize the API's parameters in the swagger docs and, vice-versa, snake casing the parameters that are sent to your API.
61
-
62
- You can disable this behavior by setting `IntrospectiveGrape.config.camelize_parameters = false`.
57
+ This also monkey patches Grape::Swagger to camelize your API's self-documentation, while snakecasing parameters passed to your API.
63
58
 
64
59
  To include this behavior in your test coverage you need to either access the API's params hash or you can format the response body to `JSON.parse(response.body).with_snake_keys` in a helper method with the `using CamelSnakeKeys` refinement.
65
60
 
66
- ### Reloading an object after an update request
67
-
68
- By default the gem reloads the object instance before presenting the updated model, a lazy but
69
- effective workaround to updates that may not propagate in the working instance due to actions
70
- a user may take in hooks, or some updates to has_many :through associations. We want to put up
71
- APIs with haste rather than digging our way out of tricky minutae that can be handled later as
72
- technical debt.
73
-
74
- This behavior can be disabled by setting `IntrospectiveGrape.config.skip_object_reload = true`,
75
- when you have time for technical debt you can toggle it and work on fixing broken tests (you
76
- did take the time to write comprehensive test coverage, didn't you?).
61
+ If you need to disable all camel-snake transliteration set `IntrospectiveGrape.config.camelize_parameters = false` down in `config/initializers` and do not `require` or `formatter` those patches.
77
62
 
78
63
  ## Authentication and authorization
79
64
 
@@ -88,7 +73,7 @@ Pundit authorization is invoked against index?, show?, update?, create?, and des
88
73
  The joke goes that you may find you need to allow an unauthenticated user to attempt a log in, which can be handled with something like:
89
74
 
90
75
  ```
91
- def authorize!
76
+ def authorize!
92
77
  unauthorized! unless current_user || login_request?
93
78
  end
94
79
 
@@ -98,7 +83,9 @@ The joke goes that you may find you need to allow an unauthenticated user to att
98
83
  end
99
84
  ```
100
85
 
101
- ## Generate End Points for Models
86
+ ## Generating End Points for Models
87
+
88
+ IntrospectiveGrape's parameterization of a model begins with the `restful` declaration, which expects an array of parameters that can be passed on to the model for update and create actions, including its nested models.
102
89
 
103
90
  The simplest app/api/v1/my_model_api.rb with the broadest functionality would look like:
104
91
 
@@ -117,17 +104,18 @@ class MyModelAPI < IntrospectiveGrape::API
117
104
  expose :nested, using: <NestedModel>Entity>
118
105
  end
119
106
  end
107
+
120
108
  ```
121
109
 
122
110
  This would set up all the basic RESTFUL actions with nested routes for the associated model and its association, providing a good deal of flexibility for API consumers out of the box.
123
111
 
124
112
  IntrospectiveGrape looks in the MyModelAPI class for grape-entity definitions. If you prefer to define your entities elsewhere you could inherit them here instead.
125
113
 
126
- Note that nested entities must be defined before their parents.
114
+ NOTE: Nested entities must be defined before their parents, inside-out, or you'll run into loading errors.
127
115
 
128
116
  ## Customizing End Points
129
117
 
130
- Many simple customizations are available to carve out from the default behaviors:
118
+ Many simple customizations are available to carve out behaviors from the expansive defaults:
131
119
 
132
120
  ```
133
121
  class MyModelAPI < IntrospectiveGrape::API
@@ -144,7 +132,7 @@ class MyModelAPI < IntrospectiveGrape::API
144
132
  filter_on :param
145
133
 
146
134
  restful MyModel, [:strong, :param, :fields, :and, { nested_model_attributes: [:nested,:fields, :_destroy] }] do
147
- # Add additional end points to the model's namespace
135
+ # Here you can add additional end points to the model's namespace, or customize one you've recently excluded so you can implement a caching strategy.
148
136
  end
149
137
 
150
138
  class <NestedModel>Entity < Grape::Entity
@@ -158,10 +146,11 @@ class MyModelAPI < IntrospectiveGrape::API
158
146
  end
159
147
  ```
160
148
 
149
+ Please note, again, that the nested Grape::Entity is declared before its parent.
161
150
 
162
151
  ## Skipping a Presence Validation for a Required Field
163
152
 
164
- If a model has, say, a procedurally generated default for a not-null field
153
+ If a model has, say, a procedurally generated default for a not-null field in the database
165
154
  `skip_presence_validations` will make IntrospectiveGrape declare the parameter
166
155
  optional rather than required.
167
156
 
@@ -169,28 +158,48 @@ optional rather than required.
169
158
 
170
159
  By default any association included in the strong params argument will have all
171
160
  RESTful (`:index,:show,:create,:update, :destroy`) endpoints defined. These can
172
- be excluded (or conversely included) with the `exclude_actions` or `include_actions`
173
- declarations in the API class. You can also include or exclude :all or :none as shorthand.
161
+ be excluded (or conversely included) with the `exclude_actions` (or `include_actions`)
162
+ declarations in the API class.
163
+
164
+ ```
165
+ include_actions NestedModel, <:index,:show,:create,:update,:destroy>
166
+ ```
167
+
168
+ You can also include or exclude `:all` or `:none` on the association as shorthand.
174
169
 
175
170
  ## Eager Loading
176
171
 
177
172
  Declaring `default_includes` on an activerecord class will tell IntrospectiveGrape which associations to eager load when fetching a collection or instance.
178
173
 
174
+ If you can diagnose an N+1 problem then this ought to fix it.
175
+
176
+ You can also eager load nested associations, if necessary:
177
+
178
+ ```
179
+ default_includes NestedModel, <associations for eager loading>
180
+ ```
181
+
179
182
  ## Pagination
180
183
 
181
- The index action by default will not be paginated, simply declared `paginate` before the `restful` declaration will enable [Kaminari](https://github.com/amatsuda/kaminari) pagination on the index results using a default 25 results per page with an offset of 0. You can pass Kaminari's options to the paginate declaration, `per_page`, `max_per_page`, etc.
184
+ The index action by default will not be paginated. Simply declaring `paginate` before the `restful` declaration will enable [Kaminari](https://github.com/amatsuda/kaminari) pagination on the index results using a default 25 results per page with an offset of 0. You can pass Kaminari's options to the paginate declaration, `per_page`, `max_per_page`, etc.
185
+
186
+ This will likewise add Kaminari's "X-" pagination headers to the response.
182
187
 
183
188
  ## Validating Virtual Attributes and Overriding Grape Validations
184
189
 
185
- To define a Grape param type for a virtual attribute or override the defaut param
186
- type from database introspection, define a class method in the model with the param
190
+ Sometimes you need to break out of IntrospectiveGrape to handle behavior that is outside
191
+ its scope, sometimes you just need to add an override or virtual attribute on the
192
+ represented model to handled that behavior. Consider the latter first!
193
+
194
+ To define a Grape param type for a virtual attribute or override the defaut param type
195
+ from database introspection, define a class method in the model with the param
187
196
  types for the attributes specified in a hash, e.g.:
188
197
 
189
198
  ```
190
199
  def self.grape_param_types
191
200
  { "<attribute name 1>" => String,
192
201
  "<attribute name 2>" => Integer,
193
- "<attribute name 3>" => Virtus::Attribute::Boolean }
202
+ "<attribute name 3>" => Grape::API::Boolean }
194
203
  end
195
204
  ```
196
205
 
@@ -205,6 +214,8 @@ class method ("grape_validations") that will be applied to that field's param de
205
214
  end
206
215
  ```
207
216
 
217
+ Many bespoke behaviors can be relegated to the model via virtual attributes in this way.
218
+
208
219
  ## Validating JSON Parameters
209
220
 
210
221
  IntrospectiveGrape provides the following custom grape validators for JSON string parameters:
@@ -216,7 +227,7 @@ json_hash: true # validates that the JSON string parses and returns a Hash
216
227
  ```
217
228
 
218
229
 
219
- ## Filtering and Searching
230
+ ## Filtering and Searching on GET :index
220
231
 
221
232
  Simple filters on field values (and start and end values for timestamps) can be added with the `filter_on` declaration. Declaring `filter_on :all` will add filters for every attribute of the model.
222
233
 
@@ -226,7 +237,7 @@ class MyModelAPI < IntrospectiveGrape::API
226
237
  end
227
238
  ```
228
239
 
229
- Multiple values can be specified at once for Integer attributes that end in "id" (i.e.
240
+ Multiple values can be queried for at once for attributes that end in "id" (i.e.
230
241
  conventional primary and foreign keys) by passing a comma separated list of IDs.
231
242
 
232
243
  For timestamp attributes it will generate `<name_of_timestamp>_start` and
@@ -237,7 +248,9 @@ this allows more complex filtering if one is familiar with ActiveRecord's query
237
248
 
238
249
  ### Overriding Filter Queries
239
250
 
240
- If, e.g., a field is some sort of complex composite rather than a simple field value you can override the default behavior (`where(field: params[field])`) by adding a query method on the model class:
251
+ If, e.g., a field is some sort of complex composite rather than a simple field value you can
252
+ override the default behavior (`where(field: params[field])`) by adding a query method on the
253
+ model class:
241
254
 
242
255
  ```
243
256
  class MyAPI < IntrospectiveGrape::API
@@ -274,29 +287,48 @@ class MyModel
274
287
  end
275
288
  ```
276
289
 
290
+ ### Performance Tuning: IntrospectiveGrape defaults to reloading an object after any update!
291
+
292
+ By default the gem reloads the object instance before presenting the updated model, a lazy but
293
+ effective workaround to updates that may not propagate in the working instance due to actions
294
+ a user may take in hooks or some updates to has_many :through associations. We want to put up
295
+ APIs with haste rather than digging our way out of tricky minutae that can be handled later as
296
+ technical debt.
297
+
298
+ This behavior can be disabled by setting `IntrospectiveGrape.config.skip_object_reload = true`,
299
+ when you have time for technical debt you can toggle it and work on fixing broken tests (you
300
+ did take the time to write comprehensive test coverage, didn't you?).
301
+
302
+ It is presently only an application wide configuration setting, not having made much use of it
303
+ myself, but would be trivial to make more atomistic.
304
+
277
305
  ## Documenting Endpoints
278
306
 
279
307
  If you wish to provide additional documentation for end points you can define
280
- `self.<action>_documentation` class methods in the API class (or extend them from a module).
308
+ `self.<index,show,update,create,destroy>_documentation` class methods in the API class (or extend them
309
+ from a documentation module, which would be preferable).
281
310
 
282
- ## Grape Hooks
311
+ ## Grape Hooks - The Precedence of Declaration Matters
283
312
 
284
313
  Grape only applies hooks in the order they were declared, so to hook into the default
285
314
  RESTful actions defined by IntrospectiveGrape you need to declare any hooks before the
286
315
  `restful` declaration, rather than inside its block, where the hook will only apply to
287
316
  your own subsequently declared endpoints.
288
317
 
289
-
290
318
  ## Dependencies
291
319
 
292
- Tool | Description
293
- --------------------- | -----------
294
- [Grape] | An opinionated micro-framework for creating REST-like APIs in Ruby
295
- [GrapeEntity] | Adds Entity support to API frameworks, such as Grape.
296
- [GrapeSwagger] | Swagger docs.
297
- [GrapeKaminari] | Pagination.
298
- [Pundit] | Minimal authorization through OO design and pure Ruby classes
299
-
320
+ Tool | Description
321
+ --------------------- | -----------
322
+ [Rails] | A web-application framework using a Model-View-Controller pattern
323
+ [SchemaValidations] | Automatically defining validations based on the database schema
324
+ [Grape] | An opinionated micro-framework for creating REST-like APIs in Ruby
325
+ [GrapeEntity] | Adds Entity support to API frameworks, such as Grape.
326
+ [GrapeSwagger] | Swagger docs.
327
+ [GrapeKaminari] | Pagination.
328
+ [Pundit] | Minimal authorization through OO design and pure Ruby classes
329
+
330
+ [Rails]: https://github.com/rails/rails
331
+ [SchemaValidations]: https://github.com/SchemaPlus/schema_validations
300
332
  [Grape]: https://github.com/ruby-grape/grape
301
333
  [GrapeEntity]: https://github.com/ruby-grape/grape-entity
302
334
  [GrapeSwagger]: https://github.com/ruby-grape/grape-swagger
data/Rakefile CHANGED
@@ -14,13 +14,8 @@ RDoc::Task.new(:rdoc) do |rdoc|
14
14
  rdoc.rdoc_files.include('lib/**/*.rb')
15
15
  end
16
16
 
17
- APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
17
+ APP_RAKEFILE = File.expand_path('spec/dummy/Rakefile', __dir__)
18
18
  load 'rails/tasks/engine.rake'
19
-
20
-
21
19
  load 'rails/tasks/statistics.rake'
22
20
 
23
-
24
-
25
21
  Bundler::GemHelper.install_tasks
26
-
@@ -1,51 +1,63 @@
1
- $:.push File.expand_path("../lib", __FILE__)
2
-
3
- # Maintain your gem's version:
4
- require "introspective_grape/version"
5
- #require "introspective_grape/api"
6
-
7
- # Describe your gem and declare its dependencies:
8
- Gem::Specification.new do |s|
9
- s.name = "introspective_grape"
10
- s.version = IntrospectiveGrape::VERSION
11
- s.authors = ["Josh Buermann"]
12
- s.email = ["buermann@gmail.com"]
13
- s.homepage = "https://github.com/buermann/introspective_grape"
14
- s.summary = "Introspectively configure deeply nested RESTful Grape APIs for ActiveRecord models."
15
- s.description = "Introspectively configure deeply nested RESTful Grape APIs for ActiveRecord models."
16
- s.license = "MIT"
17
-
18
- s.files = `git ls-files`.split("\n").sort
19
- s.test_files = `git ls-files -- spec/*`.split("\n")
20
-
21
- s.required_ruby_version = '>= 2.3'
22
-
23
- s.add_runtime_dependency "rails", '> 5.0.0'
24
- s.add_runtime_dependency "rack", '< 2.0.9' # grape < 1.3.0 is incompatible with rack 2.1.0
25
- s.add_runtime_dependency 'grape', ['~> 1.2.0', '< 1.2.5']
26
- s.add_runtime_dependency 'grape-entity'
27
- s.add_runtime_dependency 'grape-swagger'
28
- s.add_runtime_dependency 'kaminari' #, '< 1.0' # version 1.0.0 breaks
29
- #s.add_dependency 'grape-kaminari', :github => 'alexey-klimuk/grape-kaminari'
30
- # Pundit 2.0 mysteriously made authorize a protected method...
31
- s.add_runtime_dependency 'pundit' #, '<2.0'
32
- s.add_runtime_dependency 'camel_snake_keys', '>0.0.4'
33
-
34
- if RUBY_PLATFORM == 'java'
35
- #s.add_development_dependency "jdbc-sqlite3"
36
- s.add_development_dependency "activerecord-jdbcsqlite3-adapter"
37
- else
38
- s.add_development_dependency "sqlite3", '<1.4.0' #'< 1.3.14'
39
- end
40
-
41
- #s.add_development_dependency "byebug"
42
- #s.add_development_dependency "rb-readline"
43
- s.add_development_dependency "rspec-rails", '>= 3.0'
44
- s.add_development_dependency 'devise'
45
- #s.add_development_dependency 'devise-async'
46
- s.add_development_dependency 'paperclip', ">= 5.2.0" #'< 5.0'
47
- s.add_development_dependency 'machinist_redux'
48
- s.add_development_dependency 'simplecov'
49
- s.add_development_dependency 'rufus-mnemo'
50
-
51
- end
1
+ $LOAD_PATH.push File.expand_path('lib', __dir__)
2
+
3
+ # Maintain your gem's version:
4
+ require 'introspective_grape/version'
5
+
6
+ # Describe your gem and declare its dependencies:
7
+ Gem::Specification.new do |s|
8
+ s.name = 'introspective_grape'
9
+ s.version = IntrospectiveGrape::VERSION
10
+ s.authors = ['Josh Buermann']
11
+ s.email = ['buermann@gmail.com']
12
+ s.homepage = 'https://github.com/buermann/introspective_grape'
13
+ s.summary = 'Quickly configure Grape APIs around your database schema and models.'
14
+ s.description = <<-DESC
15
+ IntrospectiveGrape provides handling for deeply nested relations according to the models'
16
+ `accepts_nested_attributes_for` declarations, generating all the necessary
17
+ boilerplate for flexible and consistent bulk endpoints on plural associations,
18
+ and building nested routes for the same.
19
+ DESC
20
+ s.license = 'MIT'
21
+
22
+ s.files = `git ls-files`.split("\n").sort
23
+ s.test_files = `git ls-files -- spec/*`.split("\n")
24
+
25
+ s.required_ruby_version = '>= 2.5'
26
+
27
+ s.add_runtime_dependency 'rails', '~> 5.2'
28
+ s.add_runtime_dependency 'schema_validations'
29
+ s.add_runtime_dependency 'rack'
30
+
31
+ s.add_runtime_dependency 'grape'
32
+ s.add_runtime_dependency 'dry-types'
33
+ s.add_runtime_dependency 'grape-entity'
34
+ s.add_runtime_dependency 'grape-swagger'
35
+
36
+ s.add_runtime_dependency 'kaminari'
37
+ s.add_runtime_dependency 'grape-kaminari'
38
+
39
+ s.add_runtime_dependency 'pundit'
40
+
41
+ s.add_runtime_dependency 'camel_snake_keys', '>0.0.4'
42
+
43
+ if RUBY_PLATFORM == 'java'
44
+ s.add_development_dependency 'activerecord-jdbcsqlite3-adapter'
45
+ else
46
+ s.add_development_dependency 'sqlite3'
47
+ end
48
+
49
+ # testing gems
50
+ s.add_development_dependency 'rspec-rails', '>= 3.0'
51
+ s.add_development_dependency 'coveralls_reborn'
52
+ s.add_development_dependency 'simplecov'
53
+ s.add_development_dependency 'bundler-audit'
54
+ s.add_development_dependency 'brakeman'
55
+ s.add_development_dependency 'rubocop'
56
+ s.add_development_dependency 'byebug'
57
+ s.add_development_dependency 'machinist_redux'
58
+
59
+ # dummy app dependencies
60
+ s.add_development_dependency 'paperclip'
61
+ s.add_development_dependency 'rufus-mnemo'
62
+ s.add_development_dependency 'devise'
63
+ end