graphiti 2.0.0.beta.7 → 2.0.0.beta.8

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.
Files changed (238) hide show
  1. checksums.yaml +4 -4
  2. data/.git-blame-ignore-revs +2 -0
  3. data/.github/workflows/ci.yml +55 -3
  4. data/.github/workflows/docs.yml +1 -1
  5. data/.github/workflows/notify-example-app.yml +18 -0
  6. data/.gitignore +2 -0
  7. data/.standard.yml +6 -0
  8. data/CHANGELOG.md +45 -0
  9. data/CONTRIBUTING.md +3 -1
  10. data/README.md +13 -206
  11. data/Rakefile +6 -3
  12. data/UPGRADING.md +1 -1
  13. data/graphiti.gemspec +8 -4
  14. data/lib/generators/graphiti/generator_mixin.rb +1 -1
  15. data/lib/generators/graphiti/install_generator.rb +1 -1
  16. data/lib/generators/graphiti/resource_generator.rb +6 -3
  17. data/lib/generators/graphiti/templates/application_resource.rb.erb +19 -0
  18. data/lib/generators/graphiti/templates/controller.rb.erb +26 -8
  19. data/lib/graphiti/audit/report.rb +6 -6
  20. data/lib/graphiti/audit.rb +3 -4
  21. data/lib/graphiti/delegates/pagination.rb +2 -2
  22. data/lib/graphiti/deserializer.rb +3 -3
  23. data/lib/graphiti/errors.rb +6 -6
  24. data/lib/graphiti/extensions/temp_id.rb +1 -1
  25. data/lib/graphiti/query.rb +3 -3
  26. data/lib/graphiti/rails/context.rb +2 -1
  27. data/lib/graphiti/rails/controller.rb +3 -0
  28. data/lib/graphiti/rails/debugging.rb +1 -1
  29. data/lib/graphiti/rails/responders.rb +2 -1
  30. data/lib/graphiti/resource/configuration.rb +1 -0
  31. data/lib/graphiti/resource/dsl.rb +2 -2
  32. data/lib/graphiti/resource/links.rb +1 -1
  33. data/lib/graphiti/resource/persistence.rb +1 -1
  34. data/lib/graphiti/resource/polymorphism.rb +1 -1
  35. data/lib/graphiti/resource.rb +2 -2
  36. data/lib/graphiti/resource_proxy.rb +0 -1
  37. data/lib/graphiti/scoping/filter.rb +5 -3
  38. data/lib/graphiti/scoping/paginate.rb +1 -1
  39. data/lib/graphiti/scoping/sort.rb +1 -1
  40. data/lib/graphiti/sideload/has_many.rb +1 -1
  41. data/lib/graphiti/spec_helpers/errors_proxy.rb +1 -1
  42. data/lib/graphiti/spec_helpers/matchers.rb +1 -1
  43. data/lib/graphiti/types.rb +5 -1
  44. data/lib/graphiti/util/cache_debug.rb +3 -3
  45. data/lib/graphiti/util/hash.rb +1 -1
  46. data/lib/graphiti/util/persistence.rb +6 -6
  47. data/lib/graphiti/util/serializer_relationships.rb +1 -1
  48. data/lib/graphiti/version.rb +1 -1
  49. data/lib/tasks/graphiti.rake +1 -1
  50. metadata +31 -197
  51. data/docs/concepts/backends-and-models.md +0 -122
  52. data/docs/concepts/endpoints.md +0 -183
  53. data/docs/concepts/links.md +0 -212
  54. data/docs/concepts/overview.md +0 -80
  55. data/docs/concepts/persisting.md +0 -376
  56. data/docs/concepts/relationships.md +0 -627
  57. data/docs/concepts/resources.md +0 -677
  58. data/docs/getting-started/first-api.md +0 -289
  59. data/docs/getting-started/installation.md +0 -185
  60. data/docs/intro.md +0 -307
  61. data/docs/js/authentication.md +0 -63
  62. data/docs/js/ddau.md +0 -20
  63. data/docs/js/extra-params.md +0 -41
  64. data/docs/js/index.md +0 -112
  65. data/docs/js/installation.md +0 -120
  66. data/docs/js/middleware.md +0 -72
  67. data/docs/js/models.md +0 -202
  68. data/docs/js/reads.md +0 -494
  69. data/docs/js/state-syncing.md +0 -100
  70. data/docs/js/writes.md +0 -373
  71. data/docs/reference/vandal.md +0 -63
  72. data/docs/reference/why.md +0 -13
  73. data/docs/topics/authorization.md +0 -155
  74. data/docs/topics/caching.md +0 -55
  75. data/docs/topics/customizing-sideloads.md +0 -156
  76. data/docs/topics/debugging.md +0 -242
  77. data/docs/topics/error-handling.md +0 -210
  78. data/docs/topics/etags.md +0 -46
  79. data/docs/topics/hopping-relationships.md +0 -149
  80. data/docs/topics/json-attributes.md +0 -77
  81. data/docs/topics/openstruct-models.md +0 -50
  82. data/docs/topics/remote-resources.md +0 -291
  83. data/docs/topics/testing.md +0 -916
  84. data/docs/topics/without-activerecord.md +0 -324
  85. data/docs/tutorial/index.md +0 -58
  86. data/docs/tutorial/step_0.md +0 -107
  87. data/docs/tutorial/step_1.md +0 -199
  88. data/docs/tutorial/step_2.md +0 -312
  89. data/docs/tutorial/step_3.md +0 -142
  90. data/docs/tutorial/step_4.md +0 -135
  91. data/docs/tutorial/step_5.md +0 -69
  92. data/docs/tutorial/step_6.md +0 -82
  93. data/docs/tutorial/step_7.md +0 -205
  94. data/docs/tutorial/step_8.md +0 -128
  95. data/docs/tutorial/step_9.md +0 -171
  96. data/docs/upgrading.md +0 -267
  97. data/website/.gitignore +0 -20
  98. data/website/README.md +0 -43
  99. data/website/docusaurus.config.js +0 -197
  100. data/website/package-lock.json +0 -19474
  101. data/website/package.json +0 -46
  102. data/website/sidebars.js +0 -82
  103. data/website/src/css/custom.css +0 -85
  104. data/website/src/pages/markdown-page.mdx +0 -7
  105. data/website/static/.nojekyll +0 -0
  106. data/website/static/1.13/2019/03/31/graphiti-1-0.html +0 -205
  107. data/website/static/1.13/2019/05/08/graphiti-1-1.html +0 -212
  108. data/website/static/1.13/2019/05/20/graphiti-1-2.html +0 -214
  109. data/website/static/1.13/2019/10/14/tutorial.html +0 -198
  110. data/website/static/1.13/CNAME +0 -1
  111. data/website/static/1.13/README.md +0 -16
  112. data/website/static/1.13/assets/css/syntax.css +0 -60
  113. data/website/static/1.13/assets/favicons/android-chrome-192x192.png +0 -0
  114. data/website/static/1.13/assets/favicons/android-chrome-256x256.png +0 -0
  115. data/website/static/1.13/assets/favicons/apple-touch-icon.png +0 -0
  116. data/website/static/1.13/assets/favicons/browserconfig.xml +0 -9
  117. data/website/static/1.13/assets/favicons/favicon-16x16.png +0 -0
  118. data/website/static/1.13/assets/favicons/favicon-32x32.png +0 -0
  119. data/website/static/1.13/assets/favicons/favicon.ico +0 -0
  120. data/website/static/1.13/assets/favicons/mstile-150x150.png +0 -0
  121. data/website/static/1.13/assets/favicons/safari-pinned-tab.svg +0 -1
  122. data/website/static/1.13/assets/favicons/site.webmanifest +0 -19
  123. data/website/static/1.13/assets/img/backend.gif +0 -0
  124. data/website/static/1.13/assets/img/conformity.png +0 -0
  125. data/website/static/1.13/assets/img/error_payload.png +0 -0
  126. data/website/static/1.13/assets/img/fancy-cushion.png +0 -0
  127. data/website/static/1.13/assets/img/gh.png +0 -0
  128. data/website/static/1.13/assets/img/home-bg.jpg +0 -0
  129. data/website/static/1.13/assets/img/lifecycle.gif +0 -0
  130. data/website/static/1.13/assets/img/logo-500.png +0 -0
  131. data/website/static/1.13/assets/img/logo.png +0 -0
  132. data/website/static/1.13/assets/img/love-graffiti.jpg +0 -0
  133. data/website/static/1.13/assets/img/meta_total_count.png +0 -0
  134. data/website/static/1.13/assets/img/persist.jpg +0 -0
  135. data/website/static/1.13/assets/img/resource.gif +0 -0
  136. data/website/static/1.13/assets/img/rest-graffiti.jpg +0 -0
  137. data/website/static/1.13/assets/img/rest1.gif +0 -0
  138. data/website/static/1.13/assets/img/rest2.gif +0 -0
  139. data/website/static/1.13/assets/img/rest3.gif +0 -0
  140. data/website/static/1.13/assets/img/rethink-rest-graffiti.jpg +0 -0
  141. data/website/static/1.13/assets/img/sunrise.png +0 -0
  142. data/website/static/1.13/assets/img/why.png +0 -0
  143. data/website/static/1.13/assets/js/highlight.pack.js +0 -2
  144. data/website/static/1.13/assets/main.css +0 -15518
  145. data/website/static/1.13/assets/main.css.map +0 -1
  146. data/website/static/1.13/bin/bundle +0 -109
  147. data/website/static/1.13/bin/jekyll +0 -27
  148. data/website/static/1.13/bin/kramdown +0 -27
  149. data/website/static/1.13/bin/listen +0 -27
  150. data/website/static/1.13/bin/rake +0 -27
  151. data/website/static/1.13/bin/rougify +0 -27
  152. data/website/static/1.13/bin/safe_yaml +0 -27
  153. data/website/static/1.13/bin/sass +0 -27
  154. data/website/static/1.13/bin/sass-convert +0 -27
  155. data/website/static/1.13/bin/scss +0 -27
  156. data/website/static/1.13/blog.html +0 -259
  157. data/website/static/1.13/cheatsheet.html +0 -316
  158. data/website/static/1.13/cookbooks/authorization.md +0 -0
  159. data/website/static/1.13/cookbooks/caching.md +0 -0
  160. data/website/static/1.13/cookbooks/customizing-sideloads.html +0 -325
  161. data/website/static/1.13/cookbooks/etags.md +0 -0
  162. data/website/static/1.13/cookbooks/hopping-relationships.html +0 -324
  163. data/website/static/1.13/cookbooks/json_attributes.md +0 -0
  164. data/website/static/1.13/cookbooks/openstruct-models.md +0 -0
  165. data/website/static/1.13/cookbooks/remote-resources.md +0 -0
  166. data/website/static/1.13/cookbooks/without-activerecord.html +0 -510
  167. data/website/static/1.13/features.html +0 -249
  168. data/website/static/1.13/feed.xml +0 -106
  169. data/website/static/1.13/guides/concepts/backends-and-models.html +0 -467
  170. data/website/static/1.13/guides/concepts/debugging.html +0 -440
  171. data/website/static/1.13/guides/concepts/endpoints.html +0 -432
  172. data/website/static/1.13/guides/concepts/error-handling.html +0 -396
  173. data/website/static/1.13/guides/concepts/links.html +0 -501
  174. data/website/static/1.13/guides/concepts/remote-resources.html +0 -536
  175. data/website/static/1.13/guides/concepts/resources.html +0 -2176
  176. data/website/static/1.13/guides/concepts/testing.html +0 -1469
  177. data/website/static/1.13/guides/getting-started/installation.html +0 -420
  178. data/website/static/1.13/guides/graphiti-rails-migration.html +0 -242
  179. data/website/static/1.13/guides/index.html +0 -269
  180. data/website/static/1.13/guides/overview.html +0 -325
  181. data/website/static/1.13/guides/upgrading-2-0.html +0 -193
  182. data/website/static/1.13/guides/upgrading.html +0 -314
  183. data/website/static/1.13/guides/vandal.html +0 -282
  184. data/website/static/1.13/guides/why.html +0 -1121
  185. data/website/static/1.13/index.html +0 -72
  186. data/website/static/1.13/js/authentication.html +0 -295
  187. data/website/static/1.13/js/ddau.html +0 -238
  188. data/website/static/1.13/js/extra-params.html +0 -270
  189. data/website/static/1.13/js/index.html +0 -321
  190. data/website/static/1.13/js/installation.html +0 -637
  191. data/website/static/1.13/js/introduction.html +0 -257
  192. data/website/static/1.13/js/middleware.html +0 -318
  193. data/website/static/1.13/js/reads/fieldsets.html +0 -271
  194. data/website/static/1.13/js/reads/filtering.html +0 -289
  195. data/website/static/1.13/js/reads/includes.html +0 -260
  196. data/website/static/1.13/js/reads/index.html +0 -497
  197. data/website/static/1.13/js/reads/nested-queries.html +0 -353
  198. data/website/static/1.13/js/reads/pagination.html +0 -260
  199. data/website/static/1.13/js/reads/sorting.html +0 -265
  200. data/website/static/1.13/js/reads/statistics.html +0 -289
  201. data/website/static/1.13/js/state-syncing.html +0 -340
  202. data/website/static/1.13/js/writes/deferred.html +0 -296
  203. data/website/static/1.13/js/writes/dirty-tracking.html +0 -399
  204. data/website/static/1.13/js/writes/index.html +0 -391
  205. data/website/static/1.13/js/writes/nested.html +0 -330
  206. data/website/static/1.13/js/writes/validations.html +0 -272
  207. data/website/static/1.13/quickstart.html +0 -660
  208. data/website/static/1.13/template +0 -161
  209. data/website/static/1.13/tutorial/index.html +0 -250
  210. data/website/static/1.13/tutorial/step_0.html +0 -292
  211. data/website/static/1.13/tutorial/step_1.html +0 -517
  212. data/website/static/1.13/tutorial/step_2.html +0 -481
  213. data/website/static/1.13/tutorial/step_3.html +0 -323
  214. data/website/static/1.13/tutorial/step_4.html +0 -318
  215. data/website/static/1.13/tutorial/step_5.html +0 -265
  216. data/website/static/1.13/tutorial/step_6.html +0 -276
  217. data/website/static/1.13/tutorial/step_7.html +0 -390
  218. data/website/static/1.13/tutorial/step_8.html +0 -316
  219. data/website/static/1.13/tutorial/step_9.html +0 -365
  220. data/website/static/CNAME +0 -1
  221. data/website/static/assets/img/error_payload.png +0 -0
  222. data/website/static/assets/img/legacy/legacy-0378a3bb39.png +0 -0
  223. data/website/static/assets/img/legacy/legacy-05bbd3e5fd.png +0 -0
  224. data/website/static/assets/img/legacy/legacy-07aa104495.png +0 -0
  225. data/website/static/assets/img/legacy/legacy-0c75a16b3a.gif +0 -0
  226. data/website/static/assets/img/legacy/legacy-3076df6209.png +0 -0
  227. data/website/static/assets/img/legacy/legacy-7f6889bc89.png +0 -0
  228. data/website/static/assets/img/legacy/legacy-a2cc4363c3.png +0 -0
  229. data/website/static/assets/img/legacy/legacy-f67cfa89ab.png +0 -0
  230. data/website/static/assets/img/meta_total_count.png +0 -0
  231. data/website/static/img/docusaurus-social-card.jpg +0 -0
  232. data/website/static/img/docusaurus.png +0 -0
  233. data/website/static/img/favicon.ico +0 -0
  234. data/website/static/img/logo.png +0 -0
  235. data/website/static/img/logo.svg +0 -1
  236. data/website/static/img/undraw_docusaurus_mountain.svg +0 -171
  237. data/website/static/img/undraw_docusaurus_react.svg +0 -170
  238. data/website/static/img/undraw_docusaurus_tree.svg +0 -40
@@ -60,7 +60,7 @@ module Graphiti
60
60
 
61
61
  section_heading(label, color, ISSUE_HEADINGS.fetch(check, check.to_s.tr("_", " "))) +
62
62
  lines_grouped_by_resource(group.map { |row, finding| [row, finding.message] }) +
63
- (fixes.size == 1 ? [fix_line(fixes.first), ""] : [])
63
+ ((fixes.size == 1) ? [fix_line(fixes.first), ""] : [])
64
64
  end
65
65
 
66
66
  def loading_section
@@ -71,7 +71,7 @@ module Graphiti
71
71
  lines_grouped_by_resource(rows.map { |row| [row, nil] }) +
72
72
  [" #{paint("That is a query per record rendered.", :dim)}",
73
73
  fix_line("preload the association in base_scope, or drop `resource_ids`"),
74
- " #{paint("See www.graphiti.dev/concepts/relationships#customizing-relationships", :dim)}",
74
+ " #{paint("See graphiti.dev/concepts/relationships#customizing-relationships", :dim)}",
75
75
  ""]
76
76
  end
77
77
 
@@ -83,7 +83,7 @@ module Graphiti
83
83
  rows = @rows.select(&:would_start_loading?)
84
84
  return [] if rows.empty?
85
85
 
86
- verb = rows.size == 1 ? "renders" : "render"
86
+ verb = (rows.size == 1) ? "renders" : "render"
87
87
 
88
88
  section_heading("FYI", :blue, "#{count(rows.size, "belongs_to relationship")} #{verb} no resource ids") +
89
89
  lines_grouped_by_resource(rows.map { |row| [row, nil] }) +
@@ -95,7 +95,7 @@ module Graphiti
95
95
  ["",
96
96
  " #{paint("Either would load the association on every render. That potential performance cost is why ids are opt-in.", :dim)}",
97
97
  " #{paint("Preloading the association in base_scope keeps that load cheap.", :dim)}",
98
- " #{paint("See www.graphiti.dev/concepts/relationships#belongs-to-resource-ids", :dim)}",
98
+ " #{paint("See graphiti.dev/concepts/relationships#belongs-to-resource-ids", :dim)}",
99
99
  ""]
100
100
  end
101
101
 
@@ -189,7 +189,7 @@ module Graphiti
189
189
 
190
190
  rows.map do |cells|
191
191
  line = cells.each_with_index.map { |cell, index|
192
- index == cells.size - 1 ? cell.painted : cell.pad_to(widths[index])
192
+ (index == cells.size - 1) ? cell.painted : cell.pad_to(widths[index])
193
193
  }.join(" ")
194
194
  indent + line
195
195
  end
@@ -203,7 +203,7 @@ module Graphiti
203
203
  counts = [
204
204
  count(@rows.group_by(&:resource).size, "resource"),
205
205
  count(@rows.size, "relationship"),
206
- paint(count(errors, "error"), errors > 0 ? :red : nil)
206
+ paint(count(errors, "error"), (errors > 0) ? :red : nil)
207
207
  ]
208
208
  counts << paint("#{loading} loading ids without preloading", :yellow) if loading > 0
209
209
  counts << "#{no_ids} without resource ids" if no_ids > 0
@@ -1,7 +1,7 @@
1
1
  module Graphiti
2
2
  # Resources register themselves as they load, so eager load before auditing.
3
3
  class Audit
4
- Finding = Struct.new(:severity, :check, :message, :remedy, keyword_init: true) do
4
+ Finding = Struct.new(:severity, :check, :message, :remedy) do
5
5
  def error?
6
6
  severity == :error
7
7
  end
@@ -18,8 +18,7 @@ module Graphiti
18
18
  :resource_ids_blocker,
19
19
  :preloaded,
20
20
  :options,
21
- :findings,
22
- keyword_init: true
21
+ :findings
23
22
  ) do
24
23
  def would_start_loading?
25
24
  return false if resource_ids_default == :never
@@ -75,7 +74,7 @@ module Graphiti
75
74
  resource_ids_source_if_always: resource_ids_source_if_always(resource_class, sideload),
76
75
  resource_ids_default: resource_class.belongs_to_resource_ids_by_default,
77
76
  resource_ids_blocker: sideload.resource_ids_blocker,
78
- preloaded: source == :load ? association_preloaded?(resource_class, sideload) : nil,
77
+ preloaded: (source == :load) ? association_preloaded?(resource_class, sideload) : nil,
79
78
  options: declaration_options(sideload),
80
79
  findings: [
81
80
  missing_association_method(sideload, model),
@@ -32,7 +32,7 @@ module Graphiti
32
32
  private
33
33
 
34
34
  def pagination_params
35
- @pagination_params ||= @proxy.query.params.reject { |key, _| [:action, :controller, :format].include?(key) }
35
+ @pagination_params ||= @proxy.query.params.except(:action, :controller, :format)
36
36
  end
37
37
 
38
38
  def pagination_link(page)
@@ -109,7 +109,7 @@ module Graphiti
109
109
  end
110
110
 
111
111
  def page_param
112
- @page_param ||= (@proxy.query.hash[:page] || {})
112
+ @page_param ||= @proxy.query.hash[:page] || {}
113
113
  end
114
114
  end
115
115
  end
@@ -85,7 +85,7 @@ class Graphiti::Deserializer
85
85
  def meta(action: :update)
86
86
  {
87
87
  type: data[:type],
88
- temp_id: data[:'temp-id'],
88
+ temp_id: data[:"temp-id"],
89
89
  method: action,
90
90
  payload_path: ["data"]
91
91
  }
@@ -162,12 +162,12 @@ class Graphiti::Deserializer
162
162
  end
163
163
 
164
164
  def process_relationship_datum(datum)
165
- temp_id = datum[:'temp-id']
165
+ temp_id = datum[:"temp-id"]
166
166
  included_object = included.find { |i|
167
167
  next unless i[:type] == datum[:type]
168
168
 
169
169
  (i[:id] && i[:id] == datum[:id]) ||
170
- (i[:'temp-id'] && i[:'temp-id'] == temp_id)
170
+ (i[:"temp-id"] && i[:"temp-id"] == temp_id)
171
171
  }
172
172
  included_idx = included.index(included_object)
173
173
 
@@ -270,7 +270,7 @@ module Graphiti
270
270
  #{@resource_class.name}: error occurred while sideloading "#{@sideload_name}"!
271
271
 
272
272
  The error was raised while attempting to build query parameters for the associated Resource.
273
- Read more about sideload scoping here: www.graphiti.dev/concepts/relationships#customizing-scope
273
+ Read more about sideload scoping here: graphiti.dev/concepts/relationships#customizing-scope
274
274
 
275
275
  A good way to debug is to put a debugger within the 'params' block.
276
276
 
@@ -294,7 +294,7 @@ module Graphiti
294
294
 
295
295
  The error was raised while attempting to build the scope for the associated Resource.
296
296
 
297
- Read more about sideload scoping here: www.graphiti.dev/concepts/relationships#customizing-scope
297
+ Read more about sideload scoping here: graphiti.dev/concepts/relationships#customizing-scope
298
298
 
299
299
  Here's the original, underlying error:
300
300
 
@@ -315,7 +315,7 @@ module Graphiti
315
315
  #{@resource_class.name}: error occurred while sideloading "#{@sideload_name}"!
316
316
 
317
317
  The error was raised while attempting to assign relevant model instances. Read
318
- more about sideload assignment here: www.graphiti.dev/concepts/relationships#customizing-assignment
318
+ more about sideload assignment here: graphiti.dev/concepts/relationships#customizing-assignment
319
319
 
320
320
  A good way to debug is to put a debugger within the 'assign' block.
321
321
 
@@ -449,7 +449,7 @@ module Graphiti
449
449
 
450
450
  self.validate_endpoints = false
451
451
 
452
- See https://www.graphiti.dev/concepts/links for more information.
452
+ See https://graphiti.dev/concepts/links for more information.
453
453
 
454
454
  The current endpoints allowed for this resource are: #{@resource_class.endpoints.inspect}
455
455
  MSG
@@ -731,7 +731,7 @@ module Graphiti
731
731
 
732
732
  <<~MSG
733
733
 
734
- resource_ids is set on this relationship, so every render reads the association, not just requests that include it. See www.graphiti.dev/concepts/relationships#customizing-relationships.
734
+ resource_ids is set on this relationship, so every render reads the association, not just requests that include it. See graphiti.dev/concepts/relationships#customizing-relationships.
735
735
  MSG
736
736
  end
737
737
  end
@@ -909,7 +909,7 @@ module Graphiti
909
909
  def initialize(resource, filter_names, required)
910
910
  @resource = resource
911
911
  @filter_names = filter_names
912
- @required_label = required == :all ? "All" : "One"
912
+ @required_label = (required == :all) ? "All" : "One"
913
913
  end
914
914
 
915
915
  def message
@@ -14,7 +14,7 @@ module Graphiti
14
14
  def as_jsonapi(*)
15
15
  super.tap do |hash|
16
16
  if (temp_id = @object.instance_variable_get(:@_jsonapi_temp_id))
17
- hash[:'temp-id'] = temp_id
17
+ hash[:"temp-id"] = temp_id
18
18
  end
19
19
  end
20
20
  end
@@ -235,7 +235,7 @@ module Graphiti
235
235
 
236
236
  scrubbed.filter do |key, value|
237
237
  sideload = @resource.class.sideload(key)
238
- sideload.nil? ? true : sideload.readable?
238
+ sideload.nil? || sideload.readable?
239
239
  end
240
240
  end
241
241
  end
@@ -311,7 +311,7 @@ module Graphiti
311
311
  return false unless association?
312
312
 
313
313
  split = name.to_s.split(".")
314
- query_names = split[0..split.length - 2].map(&:to_sym)
314
+ query_names = split[0..-2].map(&:to_sym)
315
315
  my_names = parents.map(&:association_name).compact + [association_name].compact
316
316
  query_names == my_names
317
317
  end
@@ -343,7 +343,7 @@ module Graphiti
343
343
  end
344
344
 
345
345
  def sort_hash(attr)
346
- value = attr[0] == "-" ? :desc : :asc
346
+ value = (attr[0] == "-") ? :desc : :asc
347
347
  key = attr.sub("-", "").to_sym
348
348
 
349
349
  {key => value}
@@ -1,11 +1,12 @@
1
1
  module Graphiti
2
2
  module Rails
3
- # Wraps controller actions in a [Graphiti Context](https://www.graphiti.dev/concepts/resources#context) which points to the
3
+ # Wraps controller actions in a [Graphiti Context](https://graphiti.dev/concepts/resources#context) which points to the
4
4
  # controller instance by default.
5
5
  module Context
6
6
  def self.included(klass)
7
7
  klass.class_eval do
8
8
  include Graphiti::Context
9
+
9
10
  around_action :wrap_graphiti_context
10
11
  end
11
12
  end
@@ -17,6 +17,9 @@ module Graphiti
17
17
  included do
18
18
  include Graphiti::Rails::Context
19
19
  include Graphiti::Rails::Debugging
20
+ # ActionController::API strips this out, but Graphiti serves multiple
21
+ # formats (jsonapi/json/xml), so respond_to has to work everywhere.
22
+ include ActionController::MimeResponds
20
23
 
21
24
  # Broad, but the handler only renders formats listed in
22
25
  # config.graphiti.handled_exception_formats and hands everything else
@@ -1,6 +1,6 @@
1
1
  module Graphiti
2
2
  module Rails
3
- # Wraps controller actions in a [Graphiti Debugger](https://www.graphiti.dev/topics/debugging#debugger).
3
+ # Wraps controller actions in a [Graphiti Debugger](https://graphiti.dev/topics/debugging#debugger).
4
4
  module Debugging
5
5
  def self.included(klass)
6
6
  klass.around_action :debug_graphiti
@@ -6,6 +6,7 @@ module Graphiti
6
6
 
7
7
  included do
8
8
  include ActionController::MimeResponds
9
+
9
10
  respond_to(*Graphiti::Rails.respond_to_formats)
10
11
  end
11
12
 
@@ -14,7 +15,7 @@ module Graphiti
14
15
  opts = args.extract_options!
15
16
  opts[:location] = nil
16
17
  args << opts
17
- super(*args, &blk)
18
+ super
18
19
  end
19
20
  end
20
21
  end
@@ -60,6 +60,7 @@ module Graphiti
60
60
  def remote=(val)
61
61
  super
62
62
  include ::Graphiti::Resource::Remote
63
+
63
64
  self.endpoint = {
64
65
  path: val,
65
66
  full_path: val,
@@ -9,7 +9,7 @@ module Graphiti
9
9
  opts = args.extract_options!
10
10
  type_override = args[0]
11
11
 
12
- if (att = (attributes[name] || extra_attributes[name]))
12
+ if (att = attributes[name] || extra_attributes[name])
13
13
  # We're opting in to filtering, so force this
14
14
  # UNLESS the filter is guarded at the attribute level
15
15
  att[:filterable] = true if att[:filterable] == false
@@ -27,7 +27,7 @@ module Graphiti
27
27
  end
28
28
 
29
29
  required = att[:filterable] == :required || !!opts[:required]
30
- schema = !!opts[:via_attribute_dsl] ? att[:schema] : opts[:schema] != false
30
+ schema = (!!opts[:via_attribute_dsl]) ? att[:schema] : opts[:schema] != false
31
31
 
32
32
  config[:filters][name.to_sym] = {
33
33
  aliases: aliases,
@@ -41,7 +41,7 @@ module Graphiti
41
41
  def infer_endpoint
42
42
  return unless name
43
43
 
44
- path = "/#{name.gsub("Resource", "").pluralize.underscore}".to_sym
44
+ path = :"/#{name.gsub("Resource", "").pluralize.underscore}"
45
45
  {
46
46
  path: path,
47
47
  full_path: full_path_for(path),
@@ -65,7 +65,7 @@ module Graphiti
65
65
  def add_callback(kind, lifecycle, method, only, &blk)
66
66
  config[:callbacks][kind] ||= {}
67
67
  config[:callbacks][kind][lifecycle] ||= []
68
- config[:callbacks][kind][lifecycle] << {callback: (method || blk), only: Array(only)}
68
+ config[:callbacks][kind][lifecycle] << {callback: method || blk, only: Array(only)}
69
69
  end
70
70
  end
71
71
 
@@ -56,7 +56,7 @@ module Graphiti
56
56
  on_type, name = split_on[1].split("--").map(&:to_sym)
57
57
  end
58
58
 
59
- sl = super(name)
59
+ sl = super
60
60
  if !polymorphic_child? && sl.nil?
61
61
  children.each do |c|
62
62
  next if on_type && c.type != on_type
@@ -137,14 +137,14 @@ module Graphiti
137
137
 
138
138
  # TODO: make foreign_key a keyword once the satellite gems are rolled in - they call these positionally
139
139
  def assign_with_relationships(meta, attributes, relationships, caller_model = nil, foreign_key = nil, model_instance: nil)
140
- persistence = Graphiti::Util::Persistence \
140
+ persistence = Graphiti::Util::Persistence
141
141
  .new(self, meta, attributes, relationships, caller_model, foreign_key,
142
142
  assigned_model: model_instance)
143
143
  persistence.assign
144
144
  end
145
145
 
146
146
  def persist_with_relationships(meta, attributes, relationships, caller_model = nil, foreign_key = nil, assigned_model: nil)
147
- persistence = Graphiti::Util::Persistence \
147
+ persistence = Graphiti::Util::Persistence
148
148
  .new(self, meta, attributes, relationships, caller_model, foreign_key,
149
149
  assigned_model: assigned_model)
150
150
  persistence.run
@@ -16,7 +16,6 @@ module Graphiti
16
16
  cache_expires_in: nil,
17
17
  cache_tag: nil
18
18
  )
19
-
20
19
  @resource = resource
21
20
  @scope = scope
22
21
  @query = query
@@ -82,7 +82,7 @@ module Graphiti
82
82
  if is_array
83
83
  @resource.typecast(name, value, :filterable)
84
84
  else
85
- value = value.nil? || value.is_a?(Hash) ? [value] : Array(value)
85
+ value = (value.nil? || value.is_a?(Hash)) ? [value] : Array(value)
86
86
  value.map { |v| @resource.typecast(name, v, :filterable) }
87
87
  end
88
88
  end
@@ -100,7 +100,7 @@ module Graphiti
100
100
 
101
101
  param_value.map do |operator, value|
102
102
  if type == :hash
103
- value, operator = \
103
+ value, operator =
104
104
  parse_hash_value(filter, param_value, value, operator)
105
105
  end
106
106
 
@@ -209,7 +209,9 @@ module Graphiti
209
209
  end
210
210
 
211
211
  def parse_string_null(filter, value)
212
- return if value == "null" && filter[:allow_nil]
212
+ return value unless filter[:allow_nil]
213
+ return value.map { |item| (item == "null") ? nil : item } if value.is_a?(Array)
214
+ return if value == "null"
213
215
 
214
216
  value
215
217
  end
@@ -61,7 +61,7 @@ module Graphiti
61
61
  end
62
62
 
63
63
  def page_param
64
- @page_param ||= (query_hash[:page] || {})
64
+ @page_param ||= query_hash[:page] || {}
65
65
  end
66
66
 
67
67
  def offset
@@ -75,7 +75,7 @@ module Graphiti
75
75
  end
76
76
 
77
77
  def sort_hash(attr)
78
- value = attr[0] == "-" ? :desc : :asc
78
+ value = (attr[0] == "-") ? :desc : :asc
79
79
  key = attr.sub("-", "").to_sym
80
80
 
81
81
  {key => value}
@@ -2,7 +2,7 @@ class Graphiti::Sideload::HasMany < Graphiti::Sideload
2
2
  def initialize(name, opts)
3
3
  @inverse_filter = opts[:inverse_filter]
4
4
 
5
- super(name, opts)
5
+ super
6
6
  end
7
7
 
8
8
  def type
@@ -62,7 +62,7 @@ module Graphiti
62
62
 
63
63
  def method_missing(id, *args, &blk)
64
64
  matches = @errors.select { |e| e.attribute.to_sym == id }
65
- matches.length == 1 ? matches[0] : matches
65
+ (matches.length == 1) ? matches[0] : matches
66
66
  end
67
67
 
68
68
  # Any name is answered: an attribute with no matching error yields an empty
@@ -73,7 +73,7 @@ module Graphiti
73
73
  attr_reader :target, :opts, :resource
74
74
 
75
75
  def assert_opt(opt)
76
- asserted_opt = opt == :resource ? :resource_class : opt
76
+ asserted_opt = (opt == :resource) ? :resource_class : opt
77
77
  return true if config.send(asserted_opt) == opts[opt]
78
78
 
79
79
  @opt_failures << opt_failure_message(opt, opts[opt], config.send(asserted_opt))
@@ -82,6 +82,10 @@ module Graphiti
82
82
  Dry::Types["params.hash"][input]
83
83
  }
84
84
 
85
+ ParamArray = Dry::Types["strict.array"].constructor { |input|
86
+ input.is_a?(String) ? [input] : input
87
+ }
88
+
85
89
  REQUIRED_KEYS = [:params, :read, :write, :kind, :description]
86
90
 
87
91
  def self.map
@@ -193,7 +197,7 @@ module Graphiti
193
197
 
194
198
  arrays[:"array_of_#{name.to_s.pluralize}"] = {
195
199
  canonical_name: name,
196
- params: Dry::Types["strict.array"].of(map[:params]),
200
+ params: ParamArray.of(map[:params]),
197
201
  read: Dry::Types["strict.array"].of(map[:read]),
198
202
  test: Dry::Types["strict.array"].of(map[:test]),
199
203
  write: Dry::Types["strict.array"].of(map[:write]),
@@ -28,7 +28,7 @@ module Graphiti
28
28
  expires_in: proxy.cache_expires_in,
29
29
  etag: proxy.etag,
30
30
  miss_count: last_version[:miss_count].to_i + (changed_key? ? 1 : 0),
31
- hit_count: last_version[:hit_count].to_i + (!changed_key? && !new_key? ? 1 : 0),
31
+ hit_count: last_version[:hit_count].to_i + ((!changed_key? && !new_key?) ? 1 : 0),
32
32
  request_count: last_version[:request_count].to_i + (last_version.present? ? 1 : 0)
33
33
  }
34
34
  end
@@ -76,8 +76,8 @@ module Graphiti
76
76
  end
77
77
 
78
78
  def changes
79
- sub_keys_old = last_version[:cache_key]&.scan(/\w+\/query-[a-z0-9-]+\/args-[a-z0-9-]+/).to_a || []
80
- sub_keys_new = current_version[:cache_key]&.scan(/\w+\/query-[a-z0-9-]+\/args-[a-z0-9-]+/).to_a || []
79
+ sub_keys_old = last_version[:cache_key]&.scan(/\w+\/query-[a-z0-9-]+\/args-[a-z0-9-]+/).to_a
80
+ sub_keys_new = current_version[:cache_key]&.scan(/\w+\/query-[a-z0-9-]+\/args-[a-z0-9-]+/).to_a
81
81
 
82
82
  [sub_keys_old, sub_keys_new]
83
83
  end
@@ -43,7 +43,7 @@ module Graphiti
43
43
  # @return [Hash] the merged hash
44
44
  # @api private
45
45
  def self.deep_merge!(hash, other)
46
- merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
46
+ merger = proc { |key, v1, v2| (Hash === v1 && Hash === v2) ? v1.merge(v2, &merger) : v2 }
47
47
  hash.merge!(other, &merger)
48
48
  end
49
49
 
@@ -156,12 +156,12 @@ class Graphiti::Util::Persistence
156
156
 
157
157
  def persist_object(method, attributes)
158
158
  case method
159
- when :destroy
160
- call_resource_method(:destroy, attributes[:id], @caller_model)
161
- when :update, nil, :disassociate
162
- call_resource_method(:update, attributes, @caller_model)
163
- else
164
- call_resource_method(:create, attributes, @caller_model)
159
+ when :destroy
160
+ call_resource_method(:destroy, attributes[:id], @caller_model)
161
+ when :update, nil, :disassociate
162
+ call_resource_method(:update, attributes, @caller_model)
163
+ else
164
+ call_resource_method(:create, attributes, @caller_model)
165
165
  end
166
166
  end
167
167
 
@@ -173,7 +173,7 @@ module Graphiti
173
173
  def validate_link_for_sideload!(sideload)
174
174
  return if sideload.resource.remote?
175
175
 
176
- action = sideload.type == :belongs_to ? :show : :index
176
+ action = (sideload.type == :belongs_to) ? :show : :index
177
177
  cache_key = :"#{@sideload.object_id}-#{action}"
178
178
  return if self.class.validated_link_cache.include?(cache_key)
179
179
  prc = Graphiti.config.context_for_endpoint
@@ -1,3 +1,3 @@
1
1
  module Graphiti
2
- VERSION = "2.0.0.beta.7"
2
+ VERSION = "2.0.0.beta.8"
3
3
  end
@@ -20,7 +20,7 @@ namespace :graphiti do
20
20
  task audit: [:environment] do
21
21
  helpers.setup_rails!
22
22
  rows = Graphiti::Audit.run
23
- puts Graphiti::Audit::Report.new(rows).to_s
23
+ puts Graphiti::Audit::Report.new(rows)
24
24
 
25
25
  exit 1 if rows.any?(&:error?)
26
26
  end