iron_admin 0.4.1 → 0.6.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.
Files changed (456) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +66 -30
  3. data/app/assets/config/iron_admin_manifest.js +12 -0
  4. data/app/components/iron_admin/dashboards/metric_card_component.html.haml +8 -3
  5. data/app/components/iron_admin/dashboards/metric_card_component.rb +21 -1
  6. data/app/components/iron_admin/form/belongs_to_component.rb +60 -6
  7. data/app/components/iron_admin/form/nested_form_component.html.haml +28 -0
  8. data/app/components/iron_admin/form/nested_form_component.rb +81 -0
  9. data/app/components/iron_admin/resources/data_table_component.html.haml +1 -1
  10. data/app/components/iron_admin/resources/data_table_component.rb +6 -0
  11. data/app/components/iron_admin/resources/show_field_component.rb +2 -0
  12. data/app/controllers/iron_admin/application_controller.rb +32 -1
  13. data/app/controllers/iron_admin/concerns/action_executable.rb +44 -0
  14. data/app/controllers/iron_admin/concerns/filterable.rb +84 -0
  15. data/app/controllers/iron_admin/concerns/json_params_coercion.rb +67 -0
  16. data/app/controllers/iron_admin/concerns/nested_permittable.rb +36 -0
  17. data/app/controllers/iron_admin/concerns/scopeable.rb +84 -0
  18. data/app/controllers/iron_admin/concerns/searchable.rb +13 -16
  19. data/app/controllers/iron_admin/exports_controller.rb +15 -11
  20. data/app/controllers/iron_admin/imports_controller.rb +83 -0
  21. data/app/controllers/iron_admin/live_controller.rb +12 -0
  22. data/app/controllers/iron_admin/resources_controller.rb +118 -117
  23. data/app/controllers/iron_admin/search_controller.rb +5 -5
  24. data/app/controllers/iron_admin/tools_controller.rb +63 -4
  25. data/app/helpers/iron_admin/application_helper.rb +33 -14
  26. data/app/helpers/iron_admin/field_display_helper.rb +160 -1
  27. data/app/javascript/iron_admin/controllers/cp_nested_form_controller.js +113 -0
  28. data/app/javascript/iron_admin/controllers/filter_operator_controller.js +10 -0
  29. data/app/javascript/iron_admin/index.js +4 -0
  30. data/app/views/iron_admin/dashboard/index.html.haml +7 -2
  31. data/app/views/iron_admin/form/_nested_row.html.haml +70 -0
  32. data/app/views/iron_admin/imports/new.html.haml +27 -0
  33. data/app/views/iron_admin/imports/preview.html.haml +31 -0
  34. data/app/views/iron_admin/resources/_form.html.haml +81 -5
  35. data/app/views/iron_admin/resources/action_form.html.haml +62 -0
  36. data/app/views/iron_admin/resources/bulk_action_form.html.haml +62 -0
  37. data/app/views/iron_admin/resources/index.html.haml +60 -18
  38. data/app/views/iron_admin/tools/action_form.html.haml +57 -0
  39. data/app/views/iron_admin/tools/show.html.haml +20 -1
  40. data/config/importmap.rb +2 -0
  41. data/config/locales/en.yml +36 -0
  42. data/config/routes.rb +7 -0
  43. data/docs/components/filter-components.md +60 -0
  44. data/docs/getting-started/installation.md +113 -27
  45. data/docs/getting-started/quick-start.md +17 -1
  46. data/docs/guides/authentication.md +7 -6
  47. data/docs/guides/custom-adapters.md +628 -0
  48. data/docs/guides/extending.md +132 -3
  49. data/docs/guides/fields.md +1 -1
  50. data/docs/guides/resources.md +78 -2
  51. data/docs/guides/troubleshooting.md +68 -10
  52. data/docs/reference/routes.md +10 -0
  53. data/lib/generators/iron_admin/install/install_generator.rb +49 -4
  54. data/lib/generators/iron_admin/install/templates/dashboard.rb.tt +5 -1
  55. data/lib/generators/iron_admin/install_audit/install_audit_generator.rb +26 -10
  56. data/lib/generators/iron_admin/resource/resource_generator.rb +1 -1
  57. data/lib/generators/iron_admin/resource/templates/resource.rb.tt +6 -2
  58. data/lib/iron_admin/action_field.rb +56 -0
  59. data/lib/iron_admin/adapters/active_record.rb +237 -0
  60. data/lib/iron_admin/adapters/base.rb +340 -0
  61. data/lib/iron_admin/adapters/http/column_descriptor.rb +10 -0
  62. data/lib/iron_admin/adapters/http/configuration.rb +27 -0
  63. data/lib/iron_admin/adapters/http/connection.rb +117 -0
  64. data/lib/iron_admin/adapters/http/model_proxy.rb +75 -0
  65. data/lib/iron_admin/adapters/http/query.rb +111 -0
  66. data/lib/iron_admin/adapters/http/record.rb +83 -0
  67. data/lib/iron_admin/adapters/http/type_inferrer.rb +51 -0
  68. data/lib/iron_admin/adapters/http.rb +241 -0
  69. data/lib/iron_admin/adapters/mongoid/association_wrapper.rb +74 -0
  70. data/lib/iron_admin/adapters/mongoid/column_descriptor.rb +10 -0
  71. data/lib/iron_admin/adapters/mongoid.rb +284 -0
  72. data/lib/iron_admin/adapters/registry.rb +44 -0
  73. data/lib/iron_admin/concerns/importable.rb +81 -0
  74. data/lib/iron_admin/concerns/live_updatable.rb +38 -0
  75. data/lib/iron_admin/concerns/nestable.rb +69 -0
  76. data/lib/iron_admin/concerns/soft_deletable.rb +61 -0
  77. data/lib/iron_admin/configuration.rb +20 -0
  78. data/lib/iron_admin/dashboard.rb +15 -20
  79. data/lib/iron_admin/engine.rb +35 -22
  80. data/lib/iron_admin/errors.rb +29 -0
  81. data/lib/iron_admin/field_inferrer.rb +61 -22
  82. data/lib/iron_admin/filters/active_record_query_builder.rb +63 -0
  83. data/lib/iron_admin/filters/base_query_builder.rb +55 -0
  84. data/lib/iron_admin/filters/http_query_builder.rb +39 -0
  85. data/lib/iron_admin/filters/mongoid_query_builder.rb +58 -0
  86. data/lib/iron_admin/filters/query_builder.rb +12 -0
  87. data/lib/iron_admin/import/column_mapper.rb +42 -0
  88. data/lib/iron_admin/import/import_preview.rb +10 -0
  89. data/lib/iron_admin/import/import_result.rb +10 -0
  90. data/lib/iron_admin/import/importer.rb +231 -0
  91. data/lib/iron_admin/import/parser/csv.rb +34 -0
  92. data/lib/iron_admin/import/parser/json.rb +36 -0
  93. data/lib/iron_admin/import/type_caster.rb +47 -0
  94. data/lib/iron_admin/live/broadcaster.rb +43 -0
  95. data/lib/iron_admin/live/poll_cache.rb +28 -0
  96. data/lib/iron_admin/live.rb +29 -0
  97. data/lib/iron_admin/nested_association.rb +15 -0
  98. data/lib/iron_admin/nested_attributes_validator.rb +25 -0
  99. data/lib/iron_admin/policy.rb +72 -13
  100. data/lib/iron_admin/resource.rb +149 -91
  101. data/lib/iron_admin/resource_registry.rb +77 -4
  102. data/lib/iron_admin/tool.rb +50 -0
  103. data/lib/iron_admin/tool_action.rb +73 -0
  104. data/lib/iron_admin/tool_context.rb +49 -0
  105. data/lib/iron_admin/version.rb +1 -1
  106. data/lib/iron_admin.rb +46 -10
  107. data/vendor/bundle/ruby/3.2.0/cache/addressable-2.9.0.gem +0 -0
  108. data/vendor/bundle/ruby/3.2.0/cache/crack-1.0.1.gem +0 -0
  109. data/vendor/bundle/ruby/3.2.0/cache/faraday-2.14.1.gem +0 -0
  110. data/vendor/bundle/ruby/3.2.0/cache/faraday-net_http-3.4.2.gem +0 -0
  111. data/vendor/bundle/ruby/3.2.0/cache/hashdiff-1.2.1.gem +0 -0
  112. data/vendor/bundle/ruby/3.2.0/cache/net-http-0.9.1.gem +0 -0
  113. data/vendor/bundle/ruby/3.2.0/cache/public_suffix-7.0.5.gem +0 -0
  114. data/vendor/bundle/ruby/3.2.0/cache/rexml-3.4.4.gem +0 -0
  115. data/vendor/bundle/ruby/3.2.0/cache/webmock-3.26.2.gem +0 -0
  116. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/bigdecimal-4.0.1/bigdecimal.so +0 -0
  117. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/bigdecimal-4.0.1/gem_make.out +6 -6
  118. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/bigdecimal-4.0.1/mkmf.log +25 -25
  119. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/date-3.5.1/date_core.so +0 -0
  120. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/date-3.5.1/gem_make.out +6 -6
  121. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/date-3.5.1/mkmf.log +4 -4
  122. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/erb-6.0.1/erb/escape.so +0 -0
  123. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/erb-6.0.1/gem_make.out +6 -6
  124. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/erb-6.0.1/mkmf.log +2 -2
  125. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/io-console-0.8.2/gem_make.out +6 -6
  126. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/io-console-0.8.2/io/console.so +0 -0
  127. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/io-console-0.8.2/mkmf.log +22 -22
  128. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/json-2.18.1/gem_make.out +6 -6
  129. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/json-2.18.1/json/ext/generator.so +0 -0
  130. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/json-2.18.1/json/ext/parser.so +0 -0
  131. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/json-2.18.1/mkmf.log +9 -9
  132. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/nio4r-2.7.5/gem_make.out +6 -6
  133. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/nio4r-2.7.5/mkmf.log +12 -12
  134. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/nio4r-2.7.5/nio4r_ext.so +0 -0
  135. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/prism-1.9.0/gem_make.out +6 -6
  136. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/prism-1.9.0/mkmf.log +6 -6
  137. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/prism-1.9.0/prism/prism.so +0 -0
  138. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/psych-5.3.1/gem_make.out +6 -6
  139. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/psych-5.3.1/mkmf.log +7 -7
  140. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/psych-5.3.1/psych.so +0 -0
  141. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/racc-1.8.1/gem_make.out +6 -6
  142. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/racc-1.8.1/racc/cparse.so +0 -0
  143. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/redcarpet-3.6.1/gem_make.out +6 -6
  144. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/redcarpet-3.6.1/redcarpet.so +0 -0
  145. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/stringio-3.2.0/gem_make.out +6 -6
  146. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/stringio-3.2.0/mkmf.log +2 -2
  147. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/stringio-3.2.0/stringio.so +0 -0
  148. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/websocket-driver-0.8.0/gem_make.out +6 -6
  149. data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/websocket-driver-0.8.0/websocket_mask.so +0 -0
  150. data/vendor/bundle/ruby/3.2.0/gems/addressable-2.9.0/CHANGELOG.md +326 -0
  151. data/vendor/bundle/ruby/3.2.0/gems/addressable-2.9.0/LICENSE.txt +202 -0
  152. data/vendor/bundle/ruby/3.2.0/gems/addressable-2.9.0/README.md +121 -0
  153. data/vendor/bundle/ruby/3.2.0/gems/addressable-2.9.0/lib/addressable/idna/native.rb +66 -0
  154. data/vendor/bundle/ruby/3.2.0/gems/addressable-2.9.0/lib/addressable/idna/pure.rb +4710 -0
  155. data/vendor/bundle/ruby/3.2.0/gems/addressable-2.9.0/lib/addressable/idna.rb +26 -0
  156. data/vendor/bundle/ruby/3.2.0/gems/addressable-2.9.0/lib/addressable/template.rb +1040 -0
  157. data/vendor/bundle/ruby/3.2.0/gems/addressable-2.9.0/lib/addressable/uri.rb +2602 -0
  158. data/vendor/bundle/ruby/3.2.0/gems/addressable-2.9.0/lib/addressable/version.rb +31 -0
  159. data/vendor/bundle/ruby/3.2.0/gems/addressable-2.9.0/lib/addressable.rb +4 -0
  160. data/vendor/bundle/ruby/3.2.0/gems/bigdecimal-4.0.1/ext/bigdecimal/Makefile +3 -3
  161. data/vendor/bundle/ruby/3.2.0/gems/bigdecimal-4.0.1/lib/bigdecimal.so +0 -0
  162. data/vendor/bundle/ruby/3.2.0/gems/crack-1.0.1/History +58 -0
  163. data/vendor/bundle/ruby/3.2.0/gems/crack-1.0.1/LICENSE +20 -0
  164. data/vendor/bundle/ruby/3.2.0/gems/crack-1.0.1/README.md +43 -0
  165. data/vendor/bundle/ruby/3.2.0/gems/crack-1.0.1/lib/crack/json.rb +113 -0
  166. data/vendor/bundle/ruby/3.2.0/gems/crack-1.0.1/lib/crack/util.rb +17 -0
  167. data/vendor/bundle/ruby/3.2.0/gems/crack-1.0.1/lib/crack/version.rb +3 -0
  168. data/vendor/bundle/ruby/3.2.0/gems/crack-1.0.1/lib/crack/xml.rb +240 -0
  169. data/vendor/bundle/ruby/3.2.0/gems/crack-1.0.1/lib/crack.rb +8 -0
  170. data/vendor/bundle/ruby/3.2.0/gems/date-3.5.1/ext/date/Makefile +3 -3
  171. data/vendor/bundle/ruby/3.2.0/gems/date-3.5.1/lib/date_core.so +0 -0
  172. data/vendor/bundle/ruby/3.2.0/gems/erb-6.0.1/ext/erb/escape/Makefile +3 -3
  173. data/vendor/bundle/ruby/3.2.0/gems/erb-6.0.1/lib/erb/escape.so +0 -0
  174. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/CHANGELOG.md +574 -0
  175. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/LICENSE.md +20 -0
  176. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/README.md +67 -0
  177. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/Rakefile +12 -0
  178. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/examples/client_spec.rb +119 -0
  179. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/examples/client_test.rb +144 -0
  180. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/adapter/test.rb +311 -0
  181. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/adapter.rb +101 -0
  182. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/adapter_registry.rb +30 -0
  183. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/connection.rb +565 -0
  184. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/encoders/flat_params_encoder.rb +105 -0
  185. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/encoders/nested_params_encoder.rb +183 -0
  186. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/error.rb +202 -0
  187. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/logging/formatter.rb +118 -0
  188. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/methods.rb +6 -0
  189. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/middleware.rb +72 -0
  190. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/middleware_registry.rb +83 -0
  191. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/options/connection_options.rb +23 -0
  192. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/options/env.rb +204 -0
  193. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/options/proxy_options.rb +38 -0
  194. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/options/request_options.rb +23 -0
  195. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/options/ssl_options.rb +76 -0
  196. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/options.rb +219 -0
  197. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/parameters.rb +5 -0
  198. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/rack_builder.rb +248 -0
  199. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/request/authorization.rb +54 -0
  200. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/request/instrumentation.rb +58 -0
  201. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/request/json.rb +70 -0
  202. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/request/url_encoded.rb +60 -0
  203. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/request.rb +139 -0
  204. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/response/json.rb +74 -0
  205. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/response/logger.rb +39 -0
  206. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/response/raise_error.rb +83 -0
  207. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/response.rb +95 -0
  208. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/utils/headers.rb +150 -0
  209. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/utils/params_hash.rb +61 -0
  210. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/utils.rb +121 -0
  211. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/version.rb +5 -0
  212. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday.rb +158 -0
  213. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/external_adapters/faraday_specs_setup.rb +14 -0
  214. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/adapter/test_spec.rb +442 -0
  215. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/adapter_registry_spec.rb +28 -0
  216. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/adapter_spec.rb +55 -0
  217. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/connection_spec.rb +841 -0
  218. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/error_spec.rb +175 -0
  219. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/middleware_registry_spec.rb +31 -0
  220. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/middleware_spec.rb +213 -0
  221. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/options/env_spec.rb +76 -0
  222. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/options/options_spec.rb +297 -0
  223. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/options/proxy_options_spec.rb +79 -0
  224. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/options/request_options_spec.rb +19 -0
  225. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/params_encoders/flat_spec.rb +42 -0
  226. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/params_encoders/nested_spec.rb +151 -0
  227. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/rack_builder_spec.rb +317 -0
  228. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/request/authorization_spec.rb +118 -0
  229. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/request/instrumentation_spec.rb +74 -0
  230. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/request/json_spec.rb +199 -0
  231. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/request/url_encoded_spec.rb +93 -0
  232. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/request_spec.rb +110 -0
  233. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/response/json_spec.rb +206 -0
  234. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/response/logger_spec.rb +299 -0
  235. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/response/raise_error_spec.rb +286 -0
  236. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/response_spec.rb +84 -0
  237. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/utils/headers_spec.rb +109 -0
  238. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/utils_spec.rb +120 -0
  239. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday_spec.rb +43 -0
  240. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/spec_helper.rb +133 -0
  241. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/support/disabling_stub.rb +14 -0
  242. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/support/fake_safe_buffer.rb +15 -0
  243. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/support/faraday_middleware_subclasses.rb +18 -0
  244. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/support/helper_methods.rb +96 -0
  245. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/support/shared_examples/adapter.rb +105 -0
  246. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/support/shared_examples/params_encoder.rb +18 -0
  247. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/support/shared_examples/request_method.rb +263 -0
  248. data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/support/streaming_response_checker.rb +35 -0
  249. data/vendor/bundle/ruby/3.2.0/gems/faraday-net_http-3.4.2/LICENSE.md +21 -0
  250. data/vendor/bundle/ruby/3.2.0/gems/faraday-net_http-3.4.2/README.md +57 -0
  251. data/vendor/bundle/ruby/3.2.0/gems/faraday-net_http-3.4.2/lib/faraday/adapter/net_http.rb +206 -0
  252. data/vendor/bundle/ruby/3.2.0/gems/faraday-net_http-3.4.2/lib/faraday/net_http/version.rb +7 -0
  253. data/vendor/bundle/ruby/3.2.0/gems/faraday-net_http-3.4.2/lib/faraday/net_http.rb +10 -0
  254. data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/Gemfile +8 -0
  255. data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/LICENSE +19 -0
  256. data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/README.md +323 -0
  257. data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/Rakefile +18 -0
  258. data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/changelog.md +127 -0
  259. data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/hashdiff.gemspec +39 -0
  260. data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/lib/hashdiff/compare_hashes.rb +101 -0
  261. data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/lib/hashdiff/diff.rb +185 -0
  262. data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/lib/hashdiff/lcs.rb +66 -0
  263. data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/lib/hashdiff/lcs_compare_arrays.rb +32 -0
  264. data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/lib/hashdiff/linear_compare_array.rb +159 -0
  265. data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/lib/hashdiff/patch.rb +88 -0
  266. data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/lib/hashdiff/util.rb +155 -0
  267. data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/lib/hashdiff/version.rb +5 -0
  268. data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/lib/hashdiff.rb +10 -0
  269. data/vendor/bundle/ruby/3.2.0/gems/io-console-0.8.2/ext/io/console/Makefile +3 -3
  270. data/vendor/bundle/ruby/3.2.0/gems/io-console-0.8.2/lib/io/console.so +0 -0
  271. data/vendor/bundle/ruby/3.2.0/gems/json-2.18.1/ext/json/ext/generator/Makefile +3 -3
  272. data/vendor/bundle/ruby/3.2.0/gems/json-2.18.1/ext/json/ext/parser/Makefile +3 -3
  273. data/vendor/bundle/ruby/3.2.0/gems/json-2.18.1/lib/json/ext/generator.so +0 -0
  274. data/vendor/bundle/ruby/3.2.0/gems/json-2.18.1/lib/json/ext/parser.so +0 -0
  275. data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/BSDL +22 -0
  276. data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/COPYING +56 -0
  277. data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/README.md +93 -0
  278. data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/doc/net-http/examples.rdoc +31 -0
  279. data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/doc/net-http/included_getters.rdoc +3 -0
  280. data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/lib/net/http/exceptions.rb +35 -0
  281. data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/lib/net/http/generic_request.rb +429 -0
  282. data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/lib/net/http/header.rb +985 -0
  283. data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/lib/net/http/proxy_delta.rb +17 -0
  284. data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/lib/net/http/request.rb +88 -0
  285. data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/lib/net/http/requests.rb +444 -0
  286. data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/lib/net/http/response.rb +739 -0
  287. data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/lib/net/http/responses.rb +1242 -0
  288. data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/lib/net/http/status.rb +84 -0
  289. data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/lib/net/http.rb +2608 -0
  290. data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/lib/net/https.rb +23 -0
  291. data/vendor/bundle/ruby/3.2.0/gems/nio4r-2.7.5/ext/nio4r/Makefile +3 -3
  292. data/vendor/bundle/ruby/3.2.0/gems/nio4r-2.7.5/lib/nio4r_ext.so +0 -0
  293. data/vendor/bundle/ruby/3.2.0/gems/prism-1.9.0/ext/prism/Makefile +3 -3
  294. data/vendor/bundle/ruby/3.2.0/gems/prism-1.9.0/lib/prism/prism.so +0 -0
  295. data/vendor/bundle/ruby/3.2.0/gems/psych-5.3.1/ext/psych/Makefile +3 -3
  296. data/vendor/bundle/ruby/3.2.0/gems/psych-5.3.1/lib/psych.so +0 -0
  297. data/vendor/bundle/ruby/3.2.0/gems/public_suffix-7.0.5/CHANGELOG.md +649 -0
  298. data/vendor/bundle/ruby/3.2.0/gems/public_suffix-7.0.5/Gemfile +16 -0
  299. data/vendor/bundle/ruby/3.2.0/gems/public_suffix-7.0.5/LICENSE.txt +22 -0
  300. data/vendor/bundle/ruby/3.2.0/gems/public_suffix-7.0.5/README.md +231 -0
  301. data/vendor/bundle/ruby/3.2.0/gems/public_suffix-7.0.5/SECURITY.md +24 -0
  302. data/vendor/bundle/ruby/3.2.0/gems/public_suffix-7.0.5/data/list.txt +16298 -0
  303. data/vendor/bundle/ruby/3.2.0/gems/public_suffix-7.0.5/lib/public_suffix/domain.rb +235 -0
  304. data/vendor/bundle/ruby/3.2.0/gems/public_suffix-7.0.5/lib/public_suffix/errors.rb +41 -0
  305. data/vendor/bundle/ruby/3.2.0/gems/public_suffix-7.0.5/lib/public_suffix/list.rb +247 -0
  306. data/vendor/bundle/ruby/3.2.0/gems/public_suffix-7.0.5/lib/public_suffix/rule.rb +350 -0
  307. data/vendor/bundle/ruby/3.2.0/gems/public_suffix-7.0.5/lib/public_suffix/version.rb +14 -0
  308. data/vendor/bundle/ruby/3.2.0/gems/public_suffix-7.0.5/lib/public_suffix.rb +177 -0
  309. data/vendor/bundle/ruby/3.2.0/gems/racc-1.8.1/ext/racc/cparse/Makefile +3 -3
  310. data/vendor/bundle/ruby/3.2.0/gems/racc-1.8.1/lib/racc/cparse.so +0 -0
  311. data/vendor/bundle/ruby/3.2.0/gems/redcarpet-3.6.1/ext/redcarpet/Makefile +3 -3
  312. data/vendor/bundle/ruby/3.2.0/gems/redcarpet-3.6.1/lib/redcarpet.so +0 -0
  313. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/LICENSE.txt +22 -0
  314. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/NEWS.md +843 -0
  315. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/README.md +57 -0
  316. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/context.rdoc +143 -0
  317. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/child.rdoc +87 -0
  318. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/document.rdoc +276 -0
  319. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/element.rdoc +602 -0
  320. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/node.rdoc +97 -0
  321. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/parent.rdoc +267 -0
  322. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/child_toc.rdoc +12 -0
  323. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/document_toc.rdoc +30 -0
  324. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/element_toc.rdoc +55 -0
  325. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/master_toc.rdoc +135 -0
  326. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/node_toc.rdoc +16 -0
  327. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/parent_toc.rdoc +25 -0
  328. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/tutorial.rdoc +1358 -0
  329. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/attlistdecl.rb +63 -0
  330. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/attribute.rb +210 -0
  331. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/cdata.rb +68 -0
  332. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/child.rb +96 -0
  333. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/comment.rb +80 -0
  334. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/doctype.rb +306 -0
  335. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/document.rb +471 -0
  336. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/dtd/attlistdecl.rb +11 -0
  337. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/dtd/dtd.rb +47 -0
  338. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/dtd/elementdecl.rb +18 -0
  339. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/dtd/entitydecl.rb +57 -0
  340. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/dtd/notationdecl.rb +40 -0
  341. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/element.rb +2578 -0
  342. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/encoding.rb +48 -0
  343. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/entity.rb +142 -0
  344. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/formatters/default.rb +116 -0
  345. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/formatters/pretty.rb +142 -0
  346. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/formatters/transitive.rb +58 -0
  347. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/functions.rb +446 -0
  348. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/instruction.rb +79 -0
  349. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/light/node.rb +188 -0
  350. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/namespace.rb +63 -0
  351. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/node.rb +80 -0
  352. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/output.rb +30 -0
  353. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/parent.rb +166 -0
  354. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/parseexception.rb +53 -0
  355. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/parsers/baseparser.rb +949 -0
  356. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/parsers/lightparser.rb +59 -0
  357. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/parsers/pullparser.rb +213 -0
  358. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/parsers/sax2parser.rb +270 -0
  359. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/parsers/streamparser.rb +67 -0
  360. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/parsers/treeparser.rb +89 -0
  361. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/parsers/ultralightparser.rb +57 -0
  362. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/parsers/xpathparser.rb +739 -0
  363. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/quickpath.rb +267 -0
  364. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/rexml.rb +39 -0
  365. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/sax2listener.rb +98 -0
  366. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/security.rb +28 -0
  367. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/source.rb +388 -0
  368. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/streamlistener.rb +93 -0
  369. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/text.rb +420 -0
  370. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/undefinednamespaceexception.rb +9 -0
  371. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/validation/relaxng.rb +540 -0
  372. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/validation/validation.rb +144 -0
  373. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/validation/validationexception.rb +10 -0
  374. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/xmldecl.rb +130 -0
  375. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/xmltokens.rb +85 -0
  376. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/xpath.rb +70 -0
  377. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/xpath_parser.rb +980 -0
  378. data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml.rb +3 -0
  379. data/vendor/bundle/ruby/3.2.0/gems/stringio-3.2.0/ext/stringio/Makefile +3 -3
  380. data/vendor/bundle/ruby/3.2.0/gems/stringio-3.2.0/lib/stringio.so +0 -0
  381. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/CHANGELOG.md +2148 -0
  382. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/LICENSE +20 -0
  383. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/README.md +1229 -0
  384. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/api.rb +111 -0
  385. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/assertion_failure.rb +13 -0
  386. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/callback_registry.rb +37 -0
  387. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/config.rb +20 -0
  388. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/cucumber.rb +12 -0
  389. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/deprecation.rb +11 -0
  390. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/errors.rb +19 -0
  391. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/async_http_client_adapter.rb +228 -0
  392. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/curb_adapter.rb +354 -0
  393. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +239 -0
  394. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/excon_adapter.rb +167 -0
  395. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/http_lib_adapter.rb +9 -0
  396. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/http_lib_adapter_registry.rb +21 -0
  397. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/http_rb/client.rb +17 -0
  398. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/http_rb/request.rb +28 -0
  399. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/http_rb/response.rb +95 -0
  400. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/http_rb/streamer.rb +44 -0
  401. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/http_rb/webmock.rb +77 -0
  402. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/http_rb_adapter.rb +39 -0
  403. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/httpclient_adapter.rb +260 -0
  404. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/manticore_adapter.rb +147 -0
  405. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/net_http.rb +310 -0
  406. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/net_http_response.rb +36 -0
  407. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/patron_adapter.rb +132 -0
  408. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +190 -0
  409. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/matchers/any_arg_matcher.rb +15 -0
  410. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/matchers/hash_argument_matcher.rb +23 -0
  411. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/matchers/hash_excluding_matcher.rb +17 -0
  412. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/matchers/hash_including_matcher.rb +19 -0
  413. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/minitest.rb +43 -0
  414. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/rack_response.rb +73 -0
  415. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/request_body_diff.rb +66 -0
  416. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/request_execution_verifier.rb +79 -0
  417. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/request_pattern.rb +428 -0
  418. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/request_registry.rb +37 -0
  419. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/request_signature.rb +56 -0
  420. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/request_signature_snippet.rb +63 -0
  421. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/request_stub.rb +134 -0
  422. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/response.rb +161 -0
  423. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/responses_sequence.rb +42 -0
  424. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/rspec/matchers/request_pattern_matcher.rb +80 -0
  425. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/rspec/matchers/webmock_matcher.rb +69 -0
  426. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/rspec/matchers.rb +29 -0
  427. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/rspec.rb +44 -0
  428. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/stub_registry.rb +84 -0
  429. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/stub_request_snippet.rb +40 -0
  430. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/test_unit.rb +22 -0
  431. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/util/hash_counter.rb +45 -0
  432. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/util/hash_keys_stringifier.rb +27 -0
  433. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/util/hash_validator.rb +19 -0
  434. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/util/headers.rb +77 -0
  435. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/util/parsers/json.rb +72 -0
  436. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/util/parsers/parse_error.rb +7 -0
  437. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/util/parsers/xml.rb +16 -0
  438. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/util/query_mapper.rb +283 -0
  439. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/util/uri.rb +113 -0
  440. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/util/values_stringifier.rb +22 -0
  441. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/util/version_checker.rb +113 -0
  442. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/version.rb +5 -0
  443. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/webmock.rb +175 -0
  444. data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock.rb +61 -0
  445. data/vendor/bundle/ruby/3.2.0/gems/websocket-driver-0.8.0/ext/websocket-driver/Makefile +3 -3
  446. data/vendor/bundle/ruby/3.2.0/gems/websocket-driver-0.8.0/lib/websocket_mask.so +0 -0
  447. data/vendor/bundle/ruby/3.2.0/specifications/addressable-2.9.0.gemspec +29 -0
  448. data/vendor/bundle/ruby/3.2.0/specifications/crack-1.0.1.gemspec +27 -0
  449. data/vendor/bundle/ruby/3.2.0/specifications/faraday-2.14.1.gemspec +0 -0
  450. data/vendor/bundle/ruby/3.2.0/specifications/faraday-net_http-3.4.2.gemspec +26 -0
  451. data/vendor/bundle/ruby/3.2.0/specifications/hashdiff-1.2.1.gemspec +30 -0
  452. data/vendor/bundle/ruby/3.2.0/specifications/net-http-0.9.1.gemspec +27 -0
  453. data/vendor/bundle/ruby/3.2.0/specifications/public_suffix-7.0.5.gemspec +24 -0
  454. data/vendor/bundle/ruby/3.2.0/specifications/rexml-3.4.4.gemspec +25 -0
  455. data/vendor/bundle/ruby/3.2.0/specifications/webmock-3.26.2.gemspec +44 -0
  456. metadata +377 -2
@@ -20,6 +20,11 @@ module IronAdmin
20
20
  #
21
21
  # @see IronAdmin::Resource
22
22
  class ResourcesController < ApplicationController
23
+ include Concerns::ActionExecutable
24
+ include Concerns::Filterable
25
+ include Concerns::JsonParamsCoercion
26
+ include Concerns::NestedPermittable
27
+ include Concerns::Scopeable
23
28
  include Concerns::Searchable
24
29
 
25
30
  before_action :set_resource_class
@@ -29,12 +34,7 @@ module IronAdmin
29
34
  #
30
35
  # @return [void]
31
36
  def index
32
- scope = apply_scopes(apply_filters(base_scope))
33
- scope = apply_search(scope)
34
- scope = apply_sorting(scope)
35
- scope = apply_preloading(scope)
36
-
37
- @pagy, @records = pagy(scope, limit: IronAdmin.configuration.per_page)
37
+ @pagy, @records = pagy(collection_scope, limit: IronAdmin.configuration.per_page)
38
38
  @fields = index_fields
39
39
  @current_scope = current_scope_name
40
40
  end
@@ -42,9 +42,9 @@ module IronAdmin
42
42
  # Shows a single record.
43
43
  #
44
44
  # @return [void]
45
- # @raise [ActiveRecord::RecordNotFound] if record doesn't exist
45
+ # @raise [IronAdmin::RecordNotFound] if record doesn't exist
46
46
  def show
47
- @record = record_scope.find(params[:id])
47
+ @record = find_record(record_scope, params[:id])
48
48
  @fields = @resource_class.resolved_fields
49
49
  end
50
50
 
@@ -52,16 +52,16 @@ module IronAdmin
52
52
  #
53
53
  # @return [void]
54
54
  def new
55
- @record = @resource_class.model.new
55
+ @record = adapter.build
56
56
  @fields = form_fields
57
57
  end
58
58
 
59
59
  # Renders the edit form for an existing record.
60
60
  #
61
61
  # @return [void]
62
- # @raise [ActiveRecord::RecordNotFound] if record doesn't exist
62
+ # @raise [IronAdmin::RecordNotFound] if record doesn't exist
63
63
  def edit
64
- @record = record_scope.find(params[:id])
64
+ @record = find_record(record_scope, params[:id])
65
65
  @fields = form_fields
66
66
  end
67
67
 
@@ -69,12 +69,12 @@ module IronAdmin
69
69
  #
70
70
  # @return [void]
71
71
  def create
72
- @record = @resource_class.model.new(resource_params)
72
+ @record = adapter.build(resource_params)
73
73
 
74
- if @record.save
74
+ if adapter.save(@record)
75
75
  emit_event(:create, @record)
76
76
  redirect_to resource_path(@resource_class.resource_name, @record),
77
- notice: I18n.t("iron_admin.resources.create.success", model: @resource_class.model.model_name.human)
77
+ notice: I18n.t("iron_admin.resources.create.success", model: adapter.human_name)
78
78
  else
79
79
  @fields = form_fields
80
80
  render :new, status: :unprocessable_content
@@ -84,15 +84,15 @@ module IronAdmin
84
84
  # Updates an existing record.
85
85
  #
86
86
  # @return [void]
87
- # @raise [ActiveRecord::RecordNotFound] if record doesn't exist
87
+ # @raise [IronAdmin::RecordNotFound] if record doesn't exist
88
88
  def update
89
- @record = record_scope.find(params[:id])
89
+ @record = find_record(record_scope, params[:id])
90
90
  purge_attachments(@record)
91
91
 
92
- if @record.update(resource_params)
92
+ if adapter.update(@record, resource_params)
93
93
  emit_event(:update, @record)
94
94
  redirect_to resource_path(@resource_class.resource_name, @record),
95
- notice: I18n.t("iron_admin.resources.update.success", model: @resource_class.model.model_name.human)
95
+ notice: I18n.t("iron_admin.resources.update.success", model: adapter.human_name)
96
96
  else
97
97
  @fields = form_fields
98
98
  render :edit, status: :unprocessable_content
@@ -102,34 +102,63 @@ module IronAdmin
102
102
  # Deletes a record.
103
103
  #
104
104
  # @return [void]
105
- # @raise [ActiveRecord::RecordNotFound] if record doesn't exist
105
+ # @raise [IronAdmin::RecordNotFound] if record doesn't exist
106
106
  def destroy
107
- @record = record_scope.find(params[:id])
108
- @record.destroy!
107
+ @record = find_record(record_scope, params[:id])
108
+ adapter.destroy!(@record)
109
109
  emit_event(:destroy, @record)
110
110
  redirect_to resources_path(@resource_class.resource_name),
111
- notice: I18n.t("iron_admin.resources.destroy.success", model: @resource_class.model.model_name.human)
111
+ notice: I18n.t("iron_admin.resources.destroy.success", model: adapter.human_name)
112
112
  end
113
113
 
114
- # Executes a custom action on a single record.
114
+ # Renders the action form for a single record action with form_fields.
115
115
  #
116
116
  # @return [void]
117
- def execute_action
118
- action = @resource_class.defined_actions.find { |a| a[:name].to_s == params[:action_name] }
117
+ def action_form
118
+ @action = find_single_record_action
119
+ return unless @action
120
+
121
+ return unless prepare_action_record?(@action)
122
+
123
+ @form_fields = @action[:form_fields]
124
+ @form_url = resource_action_path(@resource_class.resource_name, @record, @action[:name])
125
+ end
126
+
127
+ # Renders the action form for a bulk action with form_fields.
128
+ #
129
+ # @return [void]
130
+ def bulk_action_form
131
+ action = find_bulk_action
119
132
  return head(:not_found) unless action
120
133
  return head(:forbidden) unless action_authorized?(action[:name])
121
134
 
122
- @record = record_scope.find(params[:id])
135
+ @action = action
136
+ @form_fields = action[:form_fields]
137
+ @form_url = resource_bulk_action_path(@resource_class.resource_name, action[:name])
138
+ end
139
+
140
+ # Executes a custom action on a single record.
141
+ #
142
+ # @return [void]
143
+ def execute_action
144
+ action = find_single_record_action
145
+ return unless action
146
+
147
+ return unless prepare_action_record?(action)
123
148
 
124
- ActiveRecord::Base.transaction do
125
- result = action[:block].call(@record)
126
- emit_event(params[:action_name], @record)
127
- raise ActiveRecord::Rollback if result == false
149
+ collected = action_form_params(action)
150
+
151
+ adapter.transaction do
152
+ adapter.wrap_rollback do
153
+ result = call_action_block(action[:block], @record, collected)
154
+ emit_event(params[:action_name], @record)
155
+ raise IronAdmin::Rollback if result == false
156
+ end
128
157
  end
129
158
 
130
159
  redirect_to resource_path(@resource_class.resource_name, @record),
131
160
  notice: I18n.t("iron_admin.resources.action.success")
132
- rescue ActiveRecord::RecordNotFound
161
+ rescue IronAdmin::RecordNotFound
133
162
  head(:not_found)
134
163
  rescue StandardError => e
135
164
  redirect_to resources_path(@resource_class.resource_name),
@@ -146,7 +175,7 @@ module IronAdmin
146
175
  ids = bulk_action_ids
147
176
  return redirect_bulk(:alert, I18n.t("iron_admin.resources.bulk_action.no_records")) if ids.empty?
148
177
 
149
- records = base_scope.where(id: ids)
178
+ records = adapter.filter(base_scope, :id, ids)
150
179
  action = find_bulk_action
151
180
 
152
181
  return head(:not_found) unless action
@@ -169,31 +198,20 @@ module IronAdmin
169
198
  return render json: [] if query.blank?
170
199
 
171
200
  display = @resource_class.display_attribute
172
- conn = @resource_class.model.connection
173
- table = conn.quote_table_name(@resource_class.model.table_name)
174
- column = conn.quote_column_name(display)
175
- like_operator = conn.adapter_name.downcase.include?("postgresql") ? "ILIKE" : "LIKE"
201
+ display = searchable_display_attribute unless adapter.has_column?(display)
202
+ return render json: [] unless display
176
203
 
177
- records = base_scope
178
- .where("#{table}.#{column} #{like_operator} ?", "%#{query}%")
179
- .limit(20)
180
- .map { |r| { id: r.id, label: r.public_send(display) } }
204
+ scope = adapter.search_column(base_scope, display, query)
205
+ records = adapter.limit(scope, 20)
206
+ .map { |record| { id: record.to_param.to_s, label: record.public_send(display).to_s } }
181
207
 
182
208
  render json: records
183
209
  end
184
210
 
185
211
  private
186
212
 
187
- def base_scope
188
- scope = @resource_class.model.all
189
- scope = IronAdmin.configuration.tenant_scope_block.call(scope) if IronAdmin.configuration.tenant_scope_block
190
- scope
191
- end
192
-
193
- def record_scope
194
- scope = base_scope
195
- scope = scope.unscope(where: @resource_class.soft_delete_column.to_sym) if @resource_class.soft_delete?
196
- scope
213
+ def adapter
214
+ @resource_class.adapter
197
215
  end
198
216
 
199
217
  def set_resource_class
@@ -229,7 +247,21 @@ module IronAdmin
229
247
  end
230
248
 
231
249
  def bulk_action_ids
232
- Array(params[:ids]).map(&:to_i).reject(&:zero?)
250
+ Array(params[:ids]).compact_blank
251
+ end
252
+
253
+ def find_single_record_action
254
+ action = @resource_class.defined_actions.find { |defined| defined[:name].to_s == params[:action_name] }
255
+ unless action
256
+ head(:not_found)
257
+ return nil
258
+ end
259
+ unless action_authorized?(action[:name])
260
+ head(:forbidden)
261
+ return nil
262
+ end
263
+
264
+ action
233
265
  end
234
266
 
235
267
  def find_bulk_action
@@ -245,12 +277,34 @@ module IronAdmin
245
277
  end
246
278
 
247
279
  def run_bulk_action_in_transaction(action, records)
248
- ActiveRecord::Base.transaction do
249
- result = action[:block].call(records)
250
- raise ActiveRecord::Rollback if result == false
280
+ collected = action_form_params(action)
281
+ adapter.transaction do
282
+ adapter.wrap_rollback do
283
+ result = call_action_block(action[:block], records, collected)
284
+ raise IronAdmin::Rollback if result == false
285
+ end
251
286
  end
252
287
  end
253
288
 
289
+ def searchable_display_attribute
290
+ @resource_class.searchable_columns.find { |column| adapter.has_column?(column) }
291
+ end
292
+
293
+ def action_condition_met?(action, record)
294
+ condition = action[:condition]
295
+ return true unless condition
296
+
297
+ condition.call(record)
298
+ end
299
+
300
+ def prepare_action_record?(action)
301
+ @record = find_record(record_scope, params[:id])
302
+ return true if action_condition_met?(action, @record)
303
+
304
+ head(:forbidden)
305
+ false
306
+ end
307
+
254
308
  def index_fields
255
309
  base_fields = if @resource_class.index_field_names
256
310
  fields_by_name = @resource_class.resolved_fields.index_by(&:name)
@@ -274,7 +328,7 @@ module IronAdmin
274
328
 
275
329
  def purge_attachments(record)
276
330
  form_fields.select { |f| f.type == :file }.each do |field|
277
- next unless params.dig(:record, :"#{field.name}_purge") == "1" && record.respond_to?(field.name)
331
+ next unless iron_admin_param_dig(params[:record], :"#{field.name}_purge") == "1" && record.respond_to?(field.name)
278
332
 
279
333
  record.public_send(field.name).then { |a| a.purge if a.attached? }
280
334
  end
@@ -291,70 +345,17 @@ module IronAdmin
291
345
  end
292
346
 
293
347
  @resource_class.habtm_associations.each { |a| permitted << { "#{a[:name].to_s.singularize}_ids": [] } }
294
- params.require(:record).permit(*permitted) # rubocop:disable Rails/StrongParametersExpect
295
- end
296
-
297
- def apply_filters(scope)
298
- @resource_class.all_filters.each do |filter|
299
- if filter[:type] == :date_range
300
- from = params.dig(:filters, "#{filter[:name]}_from")
301
- to = params.dig(:filters, "#{filter[:name]}_to")
302
- scope = scope.where(filter[:name] => parse_date(from)..) if from.present? && parse_date(from)
303
- scope = scope.where(filter[:name] => ..parse_date(to)&.end_of_day) if to.present? && parse_date(to)
304
- next
305
- end
306
-
307
- value = params.dig(:filters, filter[:name])
308
- next if value.blank?
309
- next unless value.is_a?(String)
310
348
 
311
- value = ActiveModel::Type::Boolean.new.cast(value) if filter[:type] == :boolean
312
-
313
- scope = if filter[:scope]
314
- filter[:scope].call(value, scope)
315
- else
316
- scope.where(filter[:name] => value)
317
- end
349
+ @resource_class.nested_associations.each do |nested|
350
+ permitted << { "#{nested.name}_attributes": build_nested_permit_list(nested) }
318
351
  end
319
- scope
320
- end
321
-
322
- def parse_date(value)
323
- return nil if value.blank?
324
-
325
- Date.parse(value)
326
- rescue ArgumentError, TypeError
327
- nil
328
- end
329
-
330
- def current_scope_name
331
- scope_name = params[:scope]
332
- defined_scope = @resource_class.all_scopes.find { |s| s[:name].to_s == scope_name }
333
- defined_scope ||= @resource_class.all_scopes.find { |s| s[:default] }
334
- defined_scope&.dig(:name)&.to_s
335
- end
336
-
337
- def apply_scopes(scope)
338
- defined_scope = @resource_class.all_scopes.find { |s| s[:name].to_s == params[:scope] }
339
- defined_scope ||= @resource_class.all_scopes.find { |s| s[:default] }
340
-
341
- return scope unless defined_scope
342
352
 
343
- scope.merge(defined_scope[:scope])
344
- end
345
-
346
- def apply_sorting(scope)
347
- sort_col = params[:sort].to_s
348
- valid_columns = @resource_class.model.column_names
349
- sort_col = IronAdmin.configuration.default_sort.to_s unless valid_columns.include?(sort_col)
350
- valid_dir = %w[asc desc].include?(params[:direction].to_s.downcase)
351
- sort_dir = valid_dir ? params[:direction] : IronAdmin.configuration.default_sort_direction
352
- scope.order(sort_col => sort_dir)
353
- end
353
+ record_params = params.require(:record)
354
+ raise ActionController::ParameterMissing, :record unless record_params.respond_to?(:permit)
354
355
 
355
- def apply_preloading(scope)
356
- preloads = @resource_class.preload_associations
357
- preloads.any? ? scope.includes(*preloads) : scope
356
+ parsed = record_params.permit(*permitted)
357
+ coerce_json_field_params!(parsed)
358
+ parsed
358
359
  end
359
360
 
360
361
  def emit_event(action, record)
@@ -362,8 +363,8 @@ module IronAdmin
362
363
  user: iron_admin_current_user,
363
364
  action: action,
364
365
  resource: @resource_class.name,
365
- record_id: record.id,
366
- changes: record.saved_changes,
366
+ record_id: record.id.to_s,
367
+ changes: adapter.record_changes(record),
367
368
  ip_address: request.remote_ip
368
369
  )
369
370
 
@@ -19,11 +19,11 @@ module IronAdmin
19
19
  columns = resource_class.searchable_columns
20
20
  next if columns.empty?
21
21
 
22
- conn = resource_class.model.connection
23
- table = conn.quote_table_name(resource_class.model.table_name)
24
- like_operator = conn.adapter_name.downcase.include?("postgresql") ? "ILIKE" : "LIKE"
25
- conditions = columns.map { |col| "#{table}.#{conn.quote_column_name(col)} #{like_operator} :q" }
26
- records = resource_class.model.where(conditions.join(" OR "), q: "%#{@query}%").limit(5)
22
+ resource_adapter = resource_class.adapter
23
+ scope = resource_adapter.all
24
+ scope = IronAdmin.configuration.tenant_scope_block.call(scope) if IronAdmin.configuration.tenant_scope_block
25
+ records = resource_adapter.search_columns(scope, columns, @query)
26
+ records = resource_adapter.limit(records, 5)
27
27
 
28
28
  next if records.empty?
29
29
 
@@ -1,6 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module IronAdmin
4
+ # Controller for rendering and executing admin tools.
5
+ #
6
+ # Supports both legacy bare-method tools and enhanced tools with
7
+ # tool_action declarations, context injection, and authorization.
4
8
  class ToolsController < ApplicationController
5
9
  before_action :set_tool
6
10
 
@@ -10,19 +14,74 @@ module IronAdmin
10
14
  end
11
15
 
12
16
  def execute
13
- action = params[:action_name]
14
- return head(:not_found) unless @tool_class.method_defined?(action)
17
+ action_name = params[:action_name]
18
+ declared = @tool_class.find_tool_action(action_name)
19
+
20
+ if declared
21
+ return head(:forbidden) unless declared.allowed?(iron_admin_current_user)
22
+ return unless run_tool_action(declared)
23
+ elsif @tool_class.method_defined?(action_name)
24
+ run_legacy_action(action_name)
25
+ else
26
+ return head(:not_found)
27
+ end
15
28
 
16
- tool_instance = @tool_class.new
17
- tool_instance.public_send(action)
18
29
  redirect_to tool_path(@tool_class.tool_name)
19
30
  end
20
31
 
32
+ # Renders the form for a tool action with form_fields.
33
+ def action_form
34
+ @declared_action = @tool_class.find_tool_action(params[:action_name])
35
+ return head(:not_found) unless @declared_action&.has_form?
36
+ return head(:forbidden) unless @declared_action.allowed?(iron_admin_current_user)
37
+
38
+ @form_fields = @declared_action.form_fields
39
+ @form_url = tool_action_path(@tool_class.tool_name, @declared_action.name)
40
+ end
41
+
21
42
  private
22
43
 
23
44
  def set_tool
24
45
  @tool_class = ToolRegistry.find(params[:tool_name])
25
46
  head(:not_found) and return unless @tool_class
26
47
  end
48
+
49
+ def run_tool_action(declared)
50
+ unless @tool_class.method_defined?(declared.name)
51
+ head(:not_found)
52
+ return nil
53
+ end
54
+
55
+ tool_instance = build_tool_instance
56
+ dispatch_with_arity(tool_instance, declared.name)
57
+ true
58
+ end
59
+
60
+ def run_legacy_action(action_name)
61
+ tool_instance = build_tool_instance
62
+ dispatch_with_arity(tool_instance, action_name)
63
+ end
64
+
65
+ def build_tool_instance
66
+ tool = @tool_class.new
67
+ tool.context = build_context
68
+ tool
69
+ end
70
+
71
+ def dispatch_with_arity(tool_instance, method_name)
72
+ if tool_instance.method(method_name).arity.zero?
73
+ tool_instance.public_send(method_name)
74
+ else
75
+ tool_instance.public_send(method_name, tool_instance.context)
76
+ end
77
+ end
78
+
79
+ def build_context
80
+ ToolContext.new(
81
+ params: params,
82
+ current_user: iron_admin_current_user,
83
+ flash: flash
84
+ )
85
+ end
27
86
  end
28
87
  end
@@ -17,6 +17,9 @@ module IronAdmin
17
17
  # Field types that should be truncated on index pages.
18
18
  TRUNCATABLE_TYPES = %i[text textarea].freeze
19
19
 
20
+ # Field types that show compact summaries on index pages.
21
+ INDEX_COMPACT_TYPES = %i[key_value boolean_group].freeze
22
+
20
23
  # Maps field types to their display method names.
21
24
  # @return [Hash{Symbol => Symbol}]
22
25
  FIELD_DISPLAY_METHODS = {
@@ -36,6 +39,13 @@ module IronAdmin
36
39
  date: :display_date,
37
40
  datetime: :display_datetime,
38
41
  polymorphic_belongs_to: :display_polymorphic_belongs_to,
42
+ hidden: :display_hidden,
43
+ radio: :display_radio,
44
+ code: :display_code,
45
+ progress_bar: :display_progress_bar,
46
+ external_image: :display_external_image,
47
+ boolean_group: :display_boolean_group,
48
+ key_value: :display_key_value,
39
49
  }.freeze
40
50
 
41
51
  # Displays a field value with appropriate formatting.
@@ -61,15 +71,9 @@ module IronAdmin
61
71
  # @return [String, nil] Formatted value (truncated for text fields)
62
72
  def display_index_field_value(record, field)
63
73
  if TRUNCATABLE_TYPES.include?(field.type)
64
- value = record.public_send(field.name)
65
- return if value.blank?
66
-
67
- truncated = truncate(value.to_s, length: INDEX_TRUNCATION_LENGTH)
68
- if value.to_s.length > INDEX_TRUNCATION_LENGTH
69
- content_tag(:span, truncated, title: value.to_s)
70
- else
71
- truncated
72
- end
74
+ display_truncated_index_value(record, field)
75
+ elsif INDEX_COMPACT_TYPES.include?(field.type)
76
+ display_compact_field_value(record, field)
73
77
  elsif (custom = IronAdmin::FieldTypeRegistry.find(field.type))
74
78
  custom.render_index_display(record, field)
75
79
  else
@@ -100,17 +104,18 @@ module IronAdmin
100
104
  # @param filter [Hash] Filter configuration
101
105
  # @return [Array<Array(String, String)>] Options for select tag
102
106
  def filter_options_for(resource_class, filter)
103
- model = resource_class.model
107
+ resource_adapter = resource_class.adapter
104
108
  column_name = filter[:name].to_s
105
109
 
106
110
  case filter[:type]
107
111
  when :select
108
- if model.defined_enums.key?(column_name)
109
- model.defined_enums[column_name].keys.map { |k| [k.humanize, k] }
112
+ enums = resource_adapter.enums
113
+ if enums.key?(column_name)
114
+ enums[column_name].keys.map { |k| [k.humanize, k] }
110
115
  elsif filter[:options]
111
- filter[:options]
116
+ normalize_filter_options(filter[:options])
112
117
  else
113
- model.distinct.pluck(column_name).compact.sort.map { |v| [v.to_s.humanize, v] }
118
+ resource_adapter.distinct_values(column_name).map { |v| [v.to_s.humanize, v] }
114
119
  end
115
120
  when :boolean
116
121
  [[I18n.t("iron_admin.filters.true"), "true"], [I18n.t("iron_admin.filters.false"), "false"]]
@@ -118,5 +123,19 @@ module IronAdmin
118
123
  []
119
124
  end
120
125
  end
126
+
127
+ def normalize_filter_options(options)
128
+ options.map do |option|
129
+ option.is_a?(Array) ? option : [option.to_s.humanize, option]
130
+ end
131
+ end
132
+
133
+ def association_resource_for(field, association_class)
134
+ resource = field.options[:resource]
135
+ return resource.constantize if resource.is_a?(String)
136
+ return resource if resource
137
+
138
+ IronAdmin::ResourceRegistry.find(association_class.model_name.plural)
139
+ end
121
140
  end
122
141
  end