iron_admin 0.5.0 → 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.
- checksums.yaml +4 -4
- data/app/assets/config/iron_admin_manifest.js +12 -0
- data/app/components/iron_admin/dashboards/metric_card_component.html.haml +8 -3
- data/app/components/iron_admin/dashboards/metric_card_component.rb +21 -1
- data/app/components/iron_admin/form/belongs_to_component.rb +60 -6
- data/app/components/iron_admin/form/nested_form_component.html.haml +28 -0
- data/app/components/iron_admin/form/nested_form_component.rb +81 -0
- data/app/components/iron_admin/resources/data_table_component.html.haml +1 -1
- data/app/components/iron_admin/resources/data_table_component.rb +6 -0
- data/app/components/iron_admin/resources/show_field_component.rb +2 -0
- data/app/controllers/iron_admin/application_controller.rb +32 -1
- data/app/controllers/iron_admin/concerns/action_executable.rb +44 -0
- data/app/controllers/iron_admin/concerns/filterable.rb +84 -0
- data/app/controllers/iron_admin/concerns/json_params_coercion.rb +67 -0
- data/app/controllers/iron_admin/concerns/nested_permittable.rb +36 -0
- data/app/controllers/iron_admin/concerns/scopeable.rb +84 -0
- data/app/controllers/iron_admin/concerns/searchable.rb +13 -16
- data/app/controllers/iron_admin/exports_controller.rb +15 -11
- data/app/controllers/iron_admin/imports_controller.rb +83 -0
- data/app/controllers/iron_admin/live_controller.rb +12 -0
- data/app/controllers/iron_admin/resources_controller.rb +118 -117
- data/app/controllers/iron_admin/search_controller.rb +5 -5
- data/app/controllers/iron_admin/tools_controller.rb +63 -4
- data/app/helpers/iron_admin/application_helper.rb +33 -14
- data/app/helpers/iron_admin/field_display_helper.rb +160 -1
- data/app/javascript/iron_admin/controllers/cp_nested_form_controller.js +113 -0
- data/app/javascript/iron_admin/controllers/filter_operator_controller.js +10 -0
- data/app/javascript/iron_admin/index.js +4 -0
- data/app/views/iron_admin/dashboard/index.html.haml +7 -2
- data/app/views/iron_admin/form/_nested_row.html.haml +70 -0
- data/app/views/iron_admin/imports/new.html.haml +27 -0
- data/app/views/iron_admin/imports/preview.html.haml +31 -0
- data/app/views/iron_admin/resources/_form.html.haml +81 -5
- data/app/views/iron_admin/resources/action_form.html.haml +62 -0
- data/app/views/iron_admin/resources/bulk_action_form.html.haml +62 -0
- data/app/views/iron_admin/resources/index.html.haml +60 -18
- data/app/views/iron_admin/tools/action_form.html.haml +57 -0
- data/app/views/iron_admin/tools/show.html.haml +20 -1
- data/config/importmap.rb +2 -0
- data/config/locales/en.yml +36 -0
- data/config/routes.rb +7 -0
- data/docs/components/filter-components.md +60 -0
- data/docs/getting-started/quick-start.md +17 -1
- data/docs/guides/authentication.md +7 -6
- data/docs/guides/custom-adapters.md +628 -0
- data/docs/guides/extending.md +132 -3
- data/docs/guides/fields.md +1 -1
- data/docs/guides/resources.md +78 -2
- data/docs/guides/troubleshooting.md +29 -0
- data/docs/reference/routes.md +10 -0
- data/lib/generators/iron_admin/install/install_generator.rb +28 -4
- data/lib/generators/iron_admin/install_audit/install_audit_generator.rb +26 -10
- data/lib/iron_admin/action_field.rb +56 -0
- data/lib/iron_admin/adapters/active_record.rb +237 -0
- data/lib/iron_admin/adapters/base.rb +340 -0
- data/lib/iron_admin/adapters/http/column_descriptor.rb +10 -0
- data/lib/iron_admin/adapters/http/configuration.rb +27 -0
- data/lib/iron_admin/adapters/http/connection.rb +117 -0
- data/lib/iron_admin/adapters/http/model_proxy.rb +75 -0
- data/lib/iron_admin/adapters/http/query.rb +111 -0
- data/lib/iron_admin/adapters/http/record.rb +83 -0
- data/lib/iron_admin/adapters/http/type_inferrer.rb +51 -0
- data/lib/iron_admin/adapters/http.rb +241 -0
- data/lib/iron_admin/adapters/mongoid/association_wrapper.rb +74 -0
- data/lib/iron_admin/adapters/mongoid/column_descriptor.rb +10 -0
- data/lib/iron_admin/adapters/mongoid.rb +284 -0
- data/lib/iron_admin/adapters/registry.rb +44 -0
- data/lib/iron_admin/concerns/importable.rb +81 -0
- data/lib/iron_admin/concerns/live_updatable.rb +38 -0
- data/lib/iron_admin/concerns/nestable.rb +69 -0
- data/lib/iron_admin/concerns/soft_deletable.rb +61 -0
- data/lib/iron_admin/configuration.rb +20 -0
- data/lib/iron_admin/dashboard.rb +15 -20
- data/lib/iron_admin/engine.rb +28 -1
- data/lib/iron_admin/errors.rb +29 -0
- data/lib/iron_admin/field_inferrer.rb +61 -22
- data/lib/iron_admin/filters/active_record_query_builder.rb +63 -0
- data/lib/iron_admin/filters/base_query_builder.rb +55 -0
- data/lib/iron_admin/filters/http_query_builder.rb +39 -0
- data/lib/iron_admin/filters/mongoid_query_builder.rb +58 -0
- data/lib/iron_admin/filters/query_builder.rb +12 -0
- data/lib/iron_admin/import/column_mapper.rb +42 -0
- data/lib/iron_admin/import/import_preview.rb +10 -0
- data/lib/iron_admin/import/import_result.rb +10 -0
- data/lib/iron_admin/import/importer.rb +231 -0
- data/lib/iron_admin/import/parser/csv.rb +34 -0
- data/lib/iron_admin/import/parser/json.rb +36 -0
- data/lib/iron_admin/import/type_caster.rb +47 -0
- data/lib/iron_admin/live/broadcaster.rb +43 -0
- data/lib/iron_admin/live/poll_cache.rb +28 -0
- data/lib/iron_admin/live.rb +29 -0
- data/lib/iron_admin/nested_association.rb +15 -0
- data/lib/iron_admin/nested_attributes_validator.rb +25 -0
- data/lib/iron_admin/policy.rb +72 -13
- data/lib/iron_admin/resource.rb +148 -90
- data/lib/iron_admin/resource_registry.rb +77 -4
- data/lib/iron_admin/tool.rb +50 -0
- data/lib/iron_admin/tool_action.rb +73 -0
- data/lib/iron_admin/tool_context.rb +49 -0
- data/lib/iron_admin/version.rb +1 -1
- data/lib/iron_admin.rb +28 -0
- data/vendor/bundle/ruby/3.2.0/cache/addressable-2.9.0.gem +0 -0
- data/vendor/bundle/ruby/3.2.0/cache/crack-1.0.1.gem +0 -0
- data/vendor/bundle/ruby/3.2.0/cache/faraday-2.14.1.gem +0 -0
- data/vendor/bundle/ruby/3.2.0/cache/faraday-net_http-3.4.2.gem +0 -0
- data/vendor/bundle/ruby/3.2.0/cache/hashdiff-1.2.1.gem +0 -0
- data/vendor/bundle/ruby/3.2.0/cache/net-http-0.9.1.gem +0 -0
- data/vendor/bundle/ruby/3.2.0/cache/public_suffix-7.0.5.gem +0 -0
- data/vendor/bundle/ruby/3.2.0/cache/rexml-3.4.4.gem +0 -0
- data/vendor/bundle/ruby/3.2.0/cache/webmock-3.26.2.gem +0 -0
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/bigdecimal-4.0.1/bigdecimal.so +0 -0
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/bigdecimal-4.0.1/gem_make.out +6 -6
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/bigdecimal-4.0.1/mkmf.log +25 -25
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/date-3.5.1/date_core.so +0 -0
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/date-3.5.1/gem_make.out +6 -6
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/date-3.5.1/mkmf.log +4 -4
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/erb-6.0.1/erb/escape.so +0 -0
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/erb-6.0.1/gem_make.out +6 -6
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/erb-6.0.1/mkmf.log +2 -2
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/io-console-0.8.2/gem_make.out +6 -6
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/io-console-0.8.2/io/console.so +0 -0
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/io-console-0.8.2/mkmf.log +22 -22
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/json-2.18.1/gem_make.out +6 -6
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/json-2.18.1/json/ext/generator.so +0 -0
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/json-2.18.1/json/ext/parser.so +0 -0
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/json-2.18.1/mkmf.log +9 -9
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/nio4r-2.7.5/gem_make.out +6 -6
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/nio4r-2.7.5/mkmf.log +12 -12
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/nio4r-2.7.5/nio4r_ext.so +0 -0
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/prism-1.9.0/gem_make.out +6 -6
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/prism-1.9.0/mkmf.log +6 -6
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/prism-1.9.0/prism/prism.so +0 -0
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/psych-5.3.1/gem_make.out +6 -6
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/psych-5.3.1/mkmf.log +7 -7
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/psych-5.3.1/psych.so +0 -0
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/racc-1.8.1/gem_make.out +6 -6
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/racc-1.8.1/racc/cparse.so +0 -0
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/redcarpet-3.6.1/gem_make.out +6 -6
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/redcarpet-3.6.1/redcarpet.so +0 -0
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/stringio-3.2.0/gem_make.out +6 -6
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/stringio-3.2.0/mkmf.log +2 -2
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/stringio-3.2.0/stringio.so +0 -0
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/websocket-driver-0.8.0/gem_make.out +6 -6
- data/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux/3.2.0/websocket-driver-0.8.0/websocket_mask.so +0 -0
- data/vendor/bundle/ruby/3.2.0/gems/addressable-2.9.0/CHANGELOG.md +326 -0
- data/vendor/bundle/ruby/3.2.0/gems/addressable-2.9.0/LICENSE.txt +202 -0
- data/vendor/bundle/ruby/3.2.0/gems/addressable-2.9.0/README.md +121 -0
- data/vendor/bundle/ruby/3.2.0/gems/addressable-2.9.0/lib/addressable/idna/native.rb +66 -0
- data/vendor/bundle/ruby/3.2.0/gems/addressable-2.9.0/lib/addressable/idna/pure.rb +4710 -0
- data/vendor/bundle/ruby/3.2.0/gems/addressable-2.9.0/lib/addressable/idna.rb +26 -0
- data/vendor/bundle/ruby/3.2.0/gems/addressable-2.9.0/lib/addressable/template.rb +1040 -0
- data/vendor/bundle/ruby/3.2.0/gems/addressable-2.9.0/lib/addressable/uri.rb +2602 -0
- data/vendor/bundle/ruby/3.2.0/gems/addressable-2.9.0/lib/addressable/version.rb +31 -0
- data/vendor/bundle/ruby/3.2.0/gems/addressable-2.9.0/lib/addressable.rb +4 -0
- data/vendor/bundle/ruby/3.2.0/gems/bigdecimal-4.0.1/ext/bigdecimal/Makefile +3 -3
- data/vendor/bundle/ruby/3.2.0/gems/bigdecimal-4.0.1/lib/bigdecimal.so +0 -0
- data/vendor/bundle/ruby/3.2.0/gems/crack-1.0.1/History +58 -0
- data/vendor/bundle/ruby/3.2.0/gems/crack-1.0.1/LICENSE +20 -0
- data/vendor/bundle/ruby/3.2.0/gems/crack-1.0.1/README.md +43 -0
- data/vendor/bundle/ruby/3.2.0/gems/crack-1.0.1/lib/crack/json.rb +113 -0
- data/vendor/bundle/ruby/3.2.0/gems/crack-1.0.1/lib/crack/util.rb +17 -0
- data/vendor/bundle/ruby/3.2.0/gems/crack-1.0.1/lib/crack/version.rb +3 -0
- data/vendor/bundle/ruby/3.2.0/gems/crack-1.0.1/lib/crack/xml.rb +240 -0
- data/vendor/bundle/ruby/3.2.0/gems/crack-1.0.1/lib/crack.rb +8 -0
- data/vendor/bundle/ruby/3.2.0/gems/date-3.5.1/ext/date/Makefile +3 -3
- data/vendor/bundle/ruby/3.2.0/gems/date-3.5.1/lib/date_core.so +0 -0
- data/vendor/bundle/ruby/3.2.0/gems/erb-6.0.1/ext/erb/escape/Makefile +3 -3
- data/vendor/bundle/ruby/3.2.0/gems/erb-6.0.1/lib/erb/escape.so +0 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/CHANGELOG.md +574 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/LICENSE.md +20 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/README.md +67 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/Rakefile +12 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/examples/client_spec.rb +119 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/examples/client_test.rb +144 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/adapter/test.rb +311 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/adapter.rb +101 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/adapter_registry.rb +30 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/connection.rb +565 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/encoders/flat_params_encoder.rb +105 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/encoders/nested_params_encoder.rb +183 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/error.rb +202 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/logging/formatter.rb +118 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/methods.rb +6 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/middleware.rb +72 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/middleware_registry.rb +83 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/options/connection_options.rb +23 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/options/env.rb +204 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/options/proxy_options.rb +38 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/options/request_options.rb +23 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/options/ssl_options.rb +76 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/options.rb +219 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/parameters.rb +5 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/rack_builder.rb +248 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/request/authorization.rb +54 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/request/instrumentation.rb +58 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/request/json.rb +70 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/request/url_encoded.rb +60 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/request.rb +139 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/response/json.rb +74 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/response/logger.rb +39 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/response/raise_error.rb +83 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/response.rb +95 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/utils/headers.rb +150 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/utils/params_hash.rb +61 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/utils.rb +121 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday/version.rb +5 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/lib/faraday.rb +158 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/external_adapters/faraday_specs_setup.rb +14 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/adapter/test_spec.rb +442 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/adapter_registry_spec.rb +28 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/adapter_spec.rb +55 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/connection_spec.rb +841 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/error_spec.rb +175 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/middleware_registry_spec.rb +31 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/middleware_spec.rb +213 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/options/env_spec.rb +76 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/options/options_spec.rb +297 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/options/proxy_options_spec.rb +79 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/options/request_options_spec.rb +19 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/params_encoders/flat_spec.rb +42 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/params_encoders/nested_spec.rb +151 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/rack_builder_spec.rb +317 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/request/authorization_spec.rb +118 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/request/instrumentation_spec.rb +74 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/request/json_spec.rb +199 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/request/url_encoded_spec.rb +93 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/request_spec.rb +110 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/response/json_spec.rb +206 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/response/logger_spec.rb +299 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/response/raise_error_spec.rb +286 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/response_spec.rb +84 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/utils/headers_spec.rb +109 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday/utils_spec.rb +120 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/faraday_spec.rb +43 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/spec_helper.rb +133 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/support/disabling_stub.rb +14 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/support/fake_safe_buffer.rb +15 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/support/faraday_middleware_subclasses.rb +18 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/support/helper_methods.rb +96 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/support/shared_examples/adapter.rb +105 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/support/shared_examples/params_encoder.rb +18 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/support/shared_examples/request_method.rb +263 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-2.14.1/spec/support/streaming_response_checker.rb +35 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-net_http-3.4.2/LICENSE.md +21 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-net_http-3.4.2/README.md +57 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-net_http-3.4.2/lib/faraday/adapter/net_http.rb +206 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-net_http-3.4.2/lib/faraday/net_http/version.rb +7 -0
- data/vendor/bundle/ruby/3.2.0/gems/faraday-net_http-3.4.2/lib/faraday/net_http.rb +10 -0
- data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/Gemfile +8 -0
- data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/LICENSE +19 -0
- data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/README.md +323 -0
- data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/Rakefile +18 -0
- data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/changelog.md +127 -0
- data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/hashdiff.gemspec +39 -0
- data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/lib/hashdiff/compare_hashes.rb +101 -0
- data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/lib/hashdiff/diff.rb +185 -0
- data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/lib/hashdiff/lcs.rb +66 -0
- data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/lib/hashdiff/lcs_compare_arrays.rb +32 -0
- data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/lib/hashdiff/linear_compare_array.rb +159 -0
- data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/lib/hashdiff/patch.rb +88 -0
- data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/lib/hashdiff/util.rb +155 -0
- data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/lib/hashdiff/version.rb +5 -0
- data/vendor/bundle/ruby/3.2.0/gems/hashdiff-1.2.1/lib/hashdiff.rb +10 -0
- data/vendor/bundle/ruby/3.2.0/gems/io-console-0.8.2/ext/io/console/Makefile +3 -3
- data/vendor/bundle/ruby/3.2.0/gems/io-console-0.8.2/lib/io/console.so +0 -0
- data/vendor/bundle/ruby/3.2.0/gems/json-2.18.1/ext/json/ext/generator/Makefile +3 -3
- data/vendor/bundle/ruby/3.2.0/gems/json-2.18.1/ext/json/ext/parser/Makefile +3 -3
- data/vendor/bundle/ruby/3.2.0/gems/json-2.18.1/lib/json/ext/generator.so +0 -0
- data/vendor/bundle/ruby/3.2.0/gems/json-2.18.1/lib/json/ext/parser.so +0 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/BSDL +22 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/COPYING +56 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/README.md +93 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/doc/net-http/examples.rdoc +31 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/doc/net-http/included_getters.rdoc +3 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/lib/net/http/exceptions.rb +35 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/lib/net/http/generic_request.rb +429 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/lib/net/http/header.rb +985 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/lib/net/http/proxy_delta.rb +17 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/lib/net/http/request.rb +88 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/lib/net/http/requests.rb +444 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/lib/net/http/response.rb +739 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/lib/net/http/responses.rb +1242 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/lib/net/http/status.rb +84 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/lib/net/http.rb +2608 -0
- data/vendor/bundle/ruby/3.2.0/gems/net-http-0.9.1/lib/net/https.rb +23 -0
- data/vendor/bundle/ruby/3.2.0/gems/nio4r-2.7.5/ext/nio4r/Makefile +3 -3
- data/vendor/bundle/ruby/3.2.0/gems/nio4r-2.7.5/lib/nio4r_ext.so +0 -0
- data/vendor/bundle/ruby/3.2.0/gems/prism-1.9.0/ext/prism/Makefile +3 -3
- data/vendor/bundle/ruby/3.2.0/gems/prism-1.9.0/lib/prism/prism.so +0 -0
- data/vendor/bundle/ruby/3.2.0/gems/psych-5.3.1/ext/psych/Makefile +3 -3
- data/vendor/bundle/ruby/3.2.0/gems/psych-5.3.1/lib/psych.so +0 -0
- data/vendor/bundle/ruby/3.2.0/gems/public_suffix-7.0.5/CHANGELOG.md +649 -0
- data/vendor/bundle/ruby/3.2.0/gems/public_suffix-7.0.5/Gemfile +16 -0
- data/vendor/bundle/ruby/3.2.0/gems/public_suffix-7.0.5/LICENSE.txt +22 -0
- data/vendor/bundle/ruby/3.2.0/gems/public_suffix-7.0.5/README.md +231 -0
- data/vendor/bundle/ruby/3.2.0/gems/public_suffix-7.0.5/SECURITY.md +24 -0
- data/vendor/bundle/ruby/3.2.0/gems/public_suffix-7.0.5/data/list.txt +16298 -0
- data/vendor/bundle/ruby/3.2.0/gems/public_suffix-7.0.5/lib/public_suffix/domain.rb +235 -0
- data/vendor/bundle/ruby/3.2.0/gems/public_suffix-7.0.5/lib/public_suffix/errors.rb +41 -0
- data/vendor/bundle/ruby/3.2.0/gems/public_suffix-7.0.5/lib/public_suffix/list.rb +247 -0
- data/vendor/bundle/ruby/3.2.0/gems/public_suffix-7.0.5/lib/public_suffix/rule.rb +350 -0
- data/vendor/bundle/ruby/3.2.0/gems/public_suffix-7.0.5/lib/public_suffix/version.rb +14 -0
- data/vendor/bundle/ruby/3.2.0/gems/public_suffix-7.0.5/lib/public_suffix.rb +177 -0
- data/vendor/bundle/ruby/3.2.0/gems/racc-1.8.1/ext/racc/cparse/Makefile +3 -3
- data/vendor/bundle/ruby/3.2.0/gems/racc-1.8.1/lib/racc/cparse.so +0 -0
- data/vendor/bundle/ruby/3.2.0/gems/redcarpet-3.6.1/ext/redcarpet/Makefile +3 -3
- data/vendor/bundle/ruby/3.2.0/gems/redcarpet-3.6.1/lib/redcarpet.so +0 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/LICENSE.txt +22 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/NEWS.md +843 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/README.md +57 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/context.rdoc +143 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/child.rdoc +87 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/document.rdoc +276 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/element.rdoc +602 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/node.rdoc +97 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/parent.rdoc +267 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/child_toc.rdoc +12 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/document_toc.rdoc +30 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/element_toc.rdoc +55 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/master_toc.rdoc +135 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/node_toc.rdoc +16 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/parent_toc.rdoc +25 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/doc/rexml/tutorial.rdoc +1358 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/attlistdecl.rb +63 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/attribute.rb +210 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/cdata.rb +68 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/child.rb +96 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/comment.rb +80 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/doctype.rb +306 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/document.rb +471 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/dtd/attlistdecl.rb +11 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/dtd/dtd.rb +47 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/dtd/elementdecl.rb +18 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/dtd/entitydecl.rb +57 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/dtd/notationdecl.rb +40 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/element.rb +2578 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/encoding.rb +48 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/entity.rb +142 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/formatters/default.rb +116 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/formatters/pretty.rb +142 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/formatters/transitive.rb +58 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/functions.rb +446 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/instruction.rb +79 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/light/node.rb +188 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/namespace.rb +63 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/node.rb +80 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/output.rb +30 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/parent.rb +166 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/parseexception.rb +53 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/parsers/baseparser.rb +949 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/parsers/lightparser.rb +59 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/parsers/pullparser.rb +213 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/parsers/sax2parser.rb +270 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/parsers/streamparser.rb +67 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/parsers/treeparser.rb +89 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/parsers/ultralightparser.rb +57 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/parsers/xpathparser.rb +739 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/quickpath.rb +267 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/rexml.rb +39 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/sax2listener.rb +98 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/security.rb +28 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/source.rb +388 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/streamlistener.rb +93 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/text.rb +420 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/undefinednamespaceexception.rb +9 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/validation/relaxng.rb +540 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/validation/validation.rb +144 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/validation/validationexception.rb +10 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/xmldecl.rb +130 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/xmltokens.rb +85 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/xpath.rb +70 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml/xpath_parser.rb +980 -0
- data/vendor/bundle/ruby/3.2.0/gems/rexml-3.4.4/lib/rexml.rb +3 -0
- data/vendor/bundle/ruby/3.2.0/gems/stringio-3.2.0/ext/stringio/Makefile +3 -3
- data/vendor/bundle/ruby/3.2.0/gems/stringio-3.2.0/lib/stringio.so +0 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/CHANGELOG.md +2148 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/LICENSE +20 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/README.md +1229 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/api.rb +111 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/assertion_failure.rb +13 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/callback_registry.rb +37 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/config.rb +20 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/cucumber.rb +12 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/deprecation.rb +11 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/errors.rb +19 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/async_http_client_adapter.rb +228 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/curb_adapter.rb +354 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +239 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/excon_adapter.rb +167 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/http_lib_adapter.rb +9 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/http_lib_adapter_registry.rb +21 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/http_rb/client.rb +17 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/http_rb/request.rb +28 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/http_rb/response.rb +95 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/http_rb/streamer.rb +44 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/http_rb/webmock.rb +77 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/http_rb_adapter.rb +39 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/httpclient_adapter.rb +260 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/manticore_adapter.rb +147 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/net_http.rb +310 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/net_http_response.rb +36 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/patron_adapter.rb +132 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +190 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/matchers/any_arg_matcher.rb +15 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/matchers/hash_argument_matcher.rb +23 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/matchers/hash_excluding_matcher.rb +17 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/matchers/hash_including_matcher.rb +19 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/minitest.rb +43 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/rack_response.rb +73 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/request_body_diff.rb +66 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/request_execution_verifier.rb +79 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/request_pattern.rb +428 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/request_registry.rb +37 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/request_signature.rb +56 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/request_signature_snippet.rb +63 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/request_stub.rb +134 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/response.rb +161 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/responses_sequence.rb +42 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/rspec/matchers/request_pattern_matcher.rb +80 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/rspec/matchers/webmock_matcher.rb +69 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/rspec/matchers.rb +29 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/rspec.rb +44 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/stub_registry.rb +84 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/stub_request_snippet.rb +40 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/test_unit.rb +22 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/util/hash_counter.rb +45 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/util/hash_keys_stringifier.rb +27 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/util/hash_validator.rb +19 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/util/headers.rb +77 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/util/parsers/json.rb +72 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/util/parsers/parse_error.rb +7 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/util/parsers/xml.rb +16 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/util/query_mapper.rb +283 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/util/uri.rb +113 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/util/values_stringifier.rb +22 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/util/version_checker.rb +113 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/version.rb +5 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock/webmock.rb +175 -0
- data/vendor/bundle/ruby/3.2.0/gems/webmock-3.26.2/lib/webmock.rb +61 -0
- data/vendor/bundle/ruby/3.2.0/gems/websocket-driver-0.8.0/ext/websocket-driver/Makefile +3 -3
- data/vendor/bundle/ruby/3.2.0/gems/websocket-driver-0.8.0/lib/websocket_mask.so +0 -0
- data/vendor/bundle/ruby/3.2.0/specifications/addressable-2.9.0.gemspec +29 -0
- data/vendor/bundle/ruby/3.2.0/specifications/crack-1.0.1.gemspec +27 -0
- data/vendor/bundle/ruby/3.2.0/specifications/faraday-2.14.1.gemspec +0 -0
- data/vendor/bundle/ruby/3.2.0/specifications/faraday-net_http-3.4.2.gemspec +26 -0
- data/vendor/bundle/ruby/3.2.0/specifications/hashdiff-1.2.1.gemspec +30 -0
- data/vendor/bundle/ruby/3.2.0/specifications/net-http-0.9.1.gemspec +27 -0
- data/vendor/bundle/ruby/3.2.0/specifications/public_suffix-7.0.5.gemspec +24 -0
- data/vendor/bundle/ruby/3.2.0/specifications/rexml-3.4.4.gemspec +25 -0
- data/vendor/bundle/ruby/3.2.0/specifications/webmock-3.26.2.gemspec +44 -0
- metadata +377 -2
data/lib/iron_admin/resource.rb
CHANGED
|
@@ -40,6 +40,11 @@ module IronAdmin
|
|
|
40
40
|
# @see IronAdmin::Field For field configuration options
|
|
41
41
|
# @see IronAdmin::Policy For authorization options
|
|
42
42
|
class Resource
|
|
43
|
+
include Concerns::Nestable
|
|
44
|
+
include Concerns::SoftDeletable
|
|
45
|
+
include Concerns::Importable
|
|
46
|
+
include Concerns::LiveUpdatable
|
|
47
|
+
|
|
43
48
|
class_attribute :field_overrides, default: {}
|
|
44
49
|
class_attribute :_searchable_columns, default: nil
|
|
45
50
|
class_attribute :_unsearchable_columns, default: []
|
|
@@ -57,6 +62,7 @@ module IronAdmin
|
|
|
57
62
|
class_attribute :denied_crud_actions, default: []
|
|
58
63
|
class_attribute :defined_associations, default: {}
|
|
59
64
|
class_attribute :model_class_override, default: nil
|
|
65
|
+
class_attribute :adapter_class, default: :active_record
|
|
60
66
|
class_attribute :_soft_delete_scopes, default: []
|
|
61
67
|
|
|
62
68
|
class << self
|
|
@@ -72,6 +78,25 @@ module IronAdmin
|
|
|
72
78
|
end
|
|
73
79
|
end
|
|
74
80
|
|
|
81
|
+
# Returns the adapter instance for this resource's model.
|
|
82
|
+
#
|
|
83
|
+
# The adapter provides a uniform interface for schema introspection,
|
|
84
|
+
# query building, and CRUD operations regardless of the underlying
|
|
85
|
+
# data source (ActiveRecord, Mongoid, HTTP, etc.).
|
|
86
|
+
#
|
|
87
|
+
# Defensively re-resolves when the cached `@adapter` doesn't match
|
|
88
|
+
# the currently configured `adapter_class`. This catches the case
|
|
89
|
+
# where the eager `Resource.inherited` flow memoized an
|
|
90
|
+
# `Adapters::ActiveRecord` built before the subclass body's
|
|
91
|
+
# `self.adapter_class = :mongoid` (or `:http`) took effect.
|
|
92
|
+
#
|
|
93
|
+
# @return [IronAdmin::Adapters::Base] The adapter instance
|
|
94
|
+
def adapter
|
|
95
|
+
wanted = resolve_adapter_class
|
|
96
|
+
@adapter = nil if @adapter && !@adapter.instance_of?(wanted)
|
|
97
|
+
@adapter ||= wanted.new(model)
|
|
98
|
+
end
|
|
99
|
+
|
|
75
100
|
# Returns the ActiveRecord model class for this resource.
|
|
76
101
|
#
|
|
77
102
|
# By default, infers the model from the resource class name
|
|
@@ -83,8 +108,17 @@ module IronAdmin
|
|
|
83
108
|
# class LegacyUserResource < IronAdmin::Resource
|
|
84
109
|
# self.model_class_override = OldUser
|
|
85
110
|
# end
|
|
111
|
+
#
|
|
112
|
+
# @example HTTP adapter — no Ruby model required
|
|
113
|
+
# class ProductResource < IronAdmin::Resource
|
|
114
|
+
# self.adapter_class = :http
|
|
115
|
+
# # `model` returns `Adapters::Http::ModelProxy.new(self)` — no
|
|
116
|
+
# # `Product` constant required; fields come from the API
|
|
117
|
+
# # response on first access.
|
|
118
|
+
# end
|
|
86
119
|
def model
|
|
87
120
|
return model_class_override if model_class_override
|
|
121
|
+
return Adapters::Http::ModelProxy.new(self) if adapter_class == :http
|
|
88
122
|
|
|
89
123
|
name.sub(/Resource\z/, "").sub(/\AIronAdmin::Resources::/, "").constantize
|
|
90
124
|
end
|
|
@@ -162,7 +196,7 @@ module IronAdmin
|
|
|
162
196
|
def searchable_columns
|
|
163
197
|
return _searchable_columns if _searchable_columns
|
|
164
198
|
|
|
165
|
-
|
|
199
|
+
adapter.columns.select { |c| c.type.in?(%i[string text]) }
|
|
166
200
|
.map { |c| c.name.to_sym }
|
|
167
201
|
.reject { |name| name.to_s.end_with?("_digest") }
|
|
168
202
|
.reject { |name| _unsearchable_columns.include?(name) }
|
|
@@ -206,19 +240,16 @@ module IronAdmin
|
|
|
206
240
|
end
|
|
207
241
|
|
|
208
242
|
# @api private
|
|
209
|
-
# Returns filters automatically inferred from enum columns.
|
|
243
|
+
# Returns filters automatically inferred from enum columns and database column types.
|
|
244
|
+
#
|
|
245
|
+
# String/text columns auto-infer as :string filters.
|
|
246
|
+
# Integer/float/decimal columns auto-infer as :number filters.
|
|
247
|
+
# Enum columns auto-infer as :select filters.
|
|
210
248
|
#
|
|
211
249
|
# @return [Array<Hash>] Auto-generated filter configurations
|
|
212
250
|
def auto_inferred_filters
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
model.defined_enums.map do |name, values|
|
|
216
|
-
{
|
|
217
|
-
name: name.to_sym,
|
|
218
|
-
type: :select,
|
|
219
|
-
options: values.keys,
|
|
220
|
-
}
|
|
221
|
-
end
|
|
251
|
+
enum_filters = enum_auto_filters
|
|
252
|
+
enum_filters + infer_column_filters(enum_filters)
|
|
222
253
|
end
|
|
223
254
|
|
|
224
255
|
# Returns all filters (auto-inferred + manually defined).
|
|
@@ -281,8 +312,9 @@ module IronAdmin
|
|
|
281
312
|
# end
|
|
282
313
|
#
|
|
283
314
|
# @return [void]
|
|
284
|
-
def action(name, **options, &block)
|
|
285
|
-
|
|
315
|
+
def action(name, form_fields: [], **options, &block)
|
|
316
|
+
coerced = coerce_action_fields(form_fields)
|
|
317
|
+
self.defined_actions = defined_actions + [{ name: name, block: block, form_fields: coerced, **options }]
|
|
286
318
|
end
|
|
287
319
|
|
|
288
320
|
# Defines a bulk action for multiple selected records.
|
|
@@ -310,8 +342,27 @@ module IronAdmin
|
|
|
310
342
|
# end
|
|
311
343
|
#
|
|
312
344
|
# @return [void]
|
|
313
|
-
def bulk_action(name, **options, &block)
|
|
314
|
-
|
|
345
|
+
def bulk_action(name, form_fields: [], **options, &block)
|
|
346
|
+
coerced = coerce_action_fields(form_fields)
|
|
347
|
+
self.defined_bulk_actions = defined_bulk_actions + [{ name: name, block: block, form_fields: coerced, **options }]
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
# Convenience constructor for ActionField instances.
|
|
351
|
+
#
|
|
352
|
+
# @param name [Symbol] The field name
|
|
353
|
+
# @param opts [Hash] Options passed to ActionField.new
|
|
354
|
+
# @return [IronAdmin::ActionField]
|
|
355
|
+
#
|
|
356
|
+
# @example
|
|
357
|
+
# action :suspend,
|
|
358
|
+
# form_fields: [
|
|
359
|
+
# action_field(:reason, type: :textarea, required: true),
|
|
360
|
+
# action_field(:notify, type: :boolean)
|
|
361
|
+
# ] do |record, params|
|
|
362
|
+
# # ...
|
|
363
|
+
# end
|
|
364
|
+
def action_field(name, **)
|
|
365
|
+
ActionField.new(name: name, **)
|
|
315
366
|
end
|
|
316
367
|
|
|
317
368
|
# Specifies which fields appear on the index (list) page.
|
|
@@ -350,13 +401,25 @@ module IronAdmin
|
|
|
350
401
|
# @option options [String] :icon Heroicon name for the menu item
|
|
351
402
|
# @option options [String] :label Custom label (defaults to pluralized model name)
|
|
352
403
|
# @option options [Integer] :priority Sort order (lower = higher in menu)
|
|
353
|
-
# @option options [String] :
|
|
404
|
+
# @option options [String] :group Group name for the sidebar section
|
|
405
|
+
# (sibling resources sharing the same `:group` are listed together;
|
|
406
|
+
# resources without a `:group` fall under "Resources"). `:section`
|
|
407
|
+
# is also accepted as an alias for `:group` for backward
|
|
408
|
+
# compatibility with earlier docs.
|
|
354
409
|
#
|
|
355
410
|
# @example
|
|
356
|
-
# menu icon: "users", label: "Team Members", priority: 10
|
|
411
|
+
# menu icon: "users", label: "Team Members", priority: 10, group: "People"
|
|
357
412
|
#
|
|
358
413
|
# @return [void]
|
|
359
414
|
def menu(**options)
|
|
415
|
+
if options.key?(:section)
|
|
416
|
+
legacy = options.delete(:section)
|
|
417
|
+
# Preserve `:group` precedence based on key presence so that
|
|
418
|
+
# explicitly passing `group: nil` (or `group: false`) still
|
|
419
|
+
# wins over `section:`. Using `||=` would clobber falsey
|
|
420
|
+
# explicit values.
|
|
421
|
+
options[:group] = legacy unless options.key?(:group)
|
|
422
|
+
end
|
|
360
423
|
self.menu_options = options
|
|
361
424
|
end
|
|
362
425
|
|
|
@@ -498,24 +561,7 @@ module IronAdmin
|
|
|
498
561
|
# has_many :orders
|
|
499
562
|
# has_many :comments, fields: [:id, :body, :created_at]
|
|
500
563
|
#
|
|
501
|
-
#
|
|
502
|
-
def has_many(name, **options)
|
|
503
|
-
self.defined_associations = defined_associations.merge(name => { kind: :has_many, **options })
|
|
504
|
-
end
|
|
505
|
-
|
|
506
|
-
# Declares a has_one association for this resource.
|
|
507
|
-
#
|
|
508
|
-
# @param name [Symbol] The association name
|
|
509
|
-
# @param options [Hash] Configuration options
|
|
510
|
-
# @option options [Class] :resource The associated resource class
|
|
511
|
-
#
|
|
512
|
-
# @example
|
|
513
|
-
# has_one :profile
|
|
514
|
-
#
|
|
515
|
-
# @return [void]
|
|
516
|
-
def has_one(name, **options)
|
|
517
|
-
self.defined_associations = defined_associations.merge(name => { kind: :has_one, **options })
|
|
518
|
-
end
|
|
564
|
+
# has_many and has_one are defined in Concerns::Nestable
|
|
519
565
|
|
|
520
566
|
# Declares a has_and_belongs_to_many association for this resource.
|
|
521
567
|
#
|
|
@@ -541,7 +587,7 @@ module IronAdmin
|
|
|
541
587
|
#
|
|
542
588
|
# @return [Array<IronAdmin::Field>] Configured field objects
|
|
543
589
|
def resolved_fields
|
|
544
|
-
inferred = FieldInferrer.call(
|
|
590
|
+
inferred = FieldInferrer.call(adapter)
|
|
545
591
|
|
|
546
592
|
inferred.map do |field|
|
|
547
593
|
overrides = field_overrides[field.name] || {}
|
|
@@ -587,13 +633,13 @@ module IronAdmin
|
|
|
587
633
|
defined_associations.filter_map do |assoc_name, config|
|
|
588
634
|
next unless config[:kind] == :has_many
|
|
589
635
|
|
|
590
|
-
reflection =
|
|
636
|
+
reflection = adapter.association(assoc_name)
|
|
591
637
|
next unless reflection
|
|
592
638
|
|
|
593
|
-
resource =
|
|
639
|
+
resource = resolve_association_resource(config, reflection)
|
|
594
640
|
next unless resource
|
|
595
641
|
|
|
596
|
-
{ name: assoc_name, reflection: reflection, resource: resource, **config.except(:kind) }
|
|
642
|
+
{ name: assoc_name, reflection: reflection, resource: resource, **config.except(:kind, :resource) }
|
|
597
643
|
end
|
|
598
644
|
end
|
|
599
645
|
|
|
@@ -604,13 +650,13 @@ module IronAdmin
|
|
|
604
650
|
defined_associations.filter_map do |assoc_name, config|
|
|
605
651
|
next unless config[:kind] == :has_one
|
|
606
652
|
|
|
607
|
-
reflection =
|
|
653
|
+
reflection = adapter.association(assoc_name)
|
|
608
654
|
next unless reflection
|
|
609
655
|
|
|
610
|
-
resource =
|
|
656
|
+
resource = resolve_association_resource(config, reflection)
|
|
611
657
|
next unless resource
|
|
612
658
|
|
|
613
|
-
{ name: assoc_name, reflection: reflection, resource: resource, **config.except(:kind) }
|
|
659
|
+
{ name: assoc_name, reflection: reflection, resource: resource, **config.except(:kind, :resource) }
|
|
614
660
|
end
|
|
615
661
|
end
|
|
616
662
|
|
|
@@ -621,27 +667,25 @@ module IronAdmin
|
|
|
621
667
|
defined_associations.filter_map do |assoc_name, config|
|
|
622
668
|
next unless config[:kind] == :has_and_belongs_to_many
|
|
623
669
|
|
|
624
|
-
reflection =
|
|
670
|
+
reflection = adapter.association(assoc_name)
|
|
625
671
|
next unless reflection
|
|
626
672
|
|
|
627
|
-
resource =
|
|
673
|
+
resource = resolve_association_resource(config, reflection)
|
|
628
674
|
|
|
629
|
-
{ name: assoc_name, reflection: reflection, resource: resource, **config.except(:kind) }
|
|
675
|
+
{ name: assoc_name, reflection: reflection, resource: resource, **config.except(:kind, :resource) }
|
|
630
676
|
end
|
|
631
677
|
end
|
|
632
678
|
|
|
633
679
|
# Returns the URL-friendly resource name (pluralized model name).
|
|
634
680
|
#
|
|
635
681
|
# @return [String] The resource name (e.g., "users", "orders")
|
|
636
|
-
|
|
637
|
-
model.model_name.plural
|
|
638
|
-
end
|
|
682
|
+
delegate :resource_name, to: :adapter
|
|
639
683
|
|
|
640
684
|
# Returns the human-readable label for this resource.
|
|
641
685
|
#
|
|
642
686
|
# @return [String] Pluralized, humanized model name
|
|
643
687
|
def label
|
|
644
|
-
|
|
688
|
+
adapter.human_name.pluralize
|
|
645
689
|
end
|
|
646
690
|
|
|
647
691
|
# Returns the attribute used to display individual records.
|
|
@@ -652,57 +696,71 @@ module IronAdmin
|
|
|
652
696
|
# @return [Symbol] The display attribute name
|
|
653
697
|
def display_attribute
|
|
654
698
|
ApplicationHelper::DISPLAY_METHODS.find do |method|
|
|
655
|
-
|
|
699
|
+
adapter.has_column?(method)
|
|
656
700
|
end || :id
|
|
657
701
|
end
|
|
658
702
|
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
703
|
+
SKIP_FILTER_COLUMNS = %w[id created_at updated_at].freeze
|
|
704
|
+
private_constant :SKIP_FILTER_COLUMNS
|
|
705
|
+
|
|
706
|
+
private
|
|
707
|
+
|
|
708
|
+
# Resolves the adapter class from a symbol or class.
|
|
709
|
+
# Symbols are resolved via the Adapters::Registry (lazy loading).
|
|
710
|
+
# Classes are used directly (for custom adapters).
|
|
711
|
+
def resolve_adapter_class
|
|
712
|
+
return adapter_class unless adapter_class.is_a?(Symbol)
|
|
713
|
+
|
|
714
|
+
Adapters::Registry.resolve(adapter_class)
|
|
664
715
|
end
|
|
665
716
|
|
|
666
|
-
#
|
|
667
|
-
#
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
717
|
+
# Resolves the resource class for an association configuration.
|
|
718
|
+
# Accepts Class, String, or falls back to ResourceRegistry lookup.
|
|
719
|
+
def resolve_association_resource(config, reflection)
|
|
720
|
+
resource = config[:resource]
|
|
721
|
+
return resource.constantize if resource.is_a?(String)
|
|
722
|
+
return resource if resource
|
|
723
|
+
|
|
724
|
+
ResourceRegistry.find(reflection.klass.model_name.plural)
|
|
671
725
|
end
|
|
672
726
|
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
# - :only_deleted scope - Show only soft-deleted records
|
|
681
|
-
# - :restore action - Restore a soft-deleted record
|
|
682
|
-
#
|
|
683
|
-
# @return [void]
|
|
684
|
-
def register_soft_delete_features
|
|
685
|
-
return unless soft_delete?
|
|
686
|
-
|
|
687
|
-
# Capture the column name for use in lambdas
|
|
688
|
-
column = soft_delete_column
|
|
689
|
-
column_sym = column.to_sym
|
|
690
|
-
|
|
691
|
-
# Store soft delete scopes separately so they always appear after user-defined scopes
|
|
692
|
-
self._soft_delete_scopes = [
|
|
693
|
-
{ name: :with_deleted, scope: -> { unscope(where: column_sym) }, default: false },
|
|
694
|
-
{ name: :only_deleted, scope: -> { unscope(where: column_sym).where.not(column => nil) }, default: false },
|
|
695
|
-
]
|
|
696
|
-
|
|
697
|
-
# Register restore action (only visible on soft-deleted records)
|
|
698
|
-
action :restore, icon: "arrow-path", condition: ->(record) { record.public_send(column).present? } do |record|
|
|
699
|
-
record.update(column => nil)
|
|
727
|
+
def enum_auto_filters
|
|
728
|
+
adapter.enums.map do |name, values|
|
|
729
|
+
{
|
|
730
|
+
name: name.to_sym,
|
|
731
|
+
type: :select,
|
|
732
|
+
options: values.keys,
|
|
733
|
+
}
|
|
700
734
|
end
|
|
701
|
-
rescue ActiveRecord::NoDatabaseError, ActiveRecord::StatementInvalid
|
|
702
|
-
nil
|
|
703
735
|
end
|
|
704
736
|
|
|
705
|
-
|
|
737
|
+
def infer_column_filters(enum_filters)
|
|
738
|
+
already_defined = (defined_filters + enum_filters).map { |f| f[:name].to_sym }
|
|
739
|
+
|
|
740
|
+
adapter.columns.filter_map do |col|
|
|
741
|
+
next if already_defined.include?(col.name.to_sym)
|
|
742
|
+
next if SKIP_FILTER_COLUMNS.include?(col.name)
|
|
743
|
+
|
|
744
|
+
infer_filter_from_column(col)
|
|
745
|
+
end
|
|
746
|
+
end
|
|
747
|
+
|
|
748
|
+
def infer_filter_from_column(col)
|
|
749
|
+
case col.type
|
|
750
|
+
when :string, :text
|
|
751
|
+
{ name: col.name.to_sym, type: :string, label: col.name.humanize }
|
|
752
|
+
when :integer, :float, :decimal
|
|
753
|
+
return nil if col.name.end_with?("_id")
|
|
754
|
+
|
|
755
|
+
{ name: col.name.to_sym, type: :number, label: col.name.humanize }
|
|
756
|
+
end
|
|
757
|
+
end
|
|
758
|
+
|
|
759
|
+
def coerce_action_fields(fields)
|
|
760
|
+
Array(fields).map do |f|
|
|
761
|
+
f.is_a?(ActionField) ? f : ActionField.new(**f)
|
|
762
|
+
end
|
|
763
|
+
end
|
|
706
764
|
|
|
707
765
|
# @api private
|
|
708
766
|
def infer_preload_associations
|
|
@@ -21,14 +21,68 @@ module IronAdmin
|
|
|
21
21
|
class << self
|
|
22
22
|
# Registers a resource class in the registry.
|
|
23
23
|
#
|
|
24
|
-
# Called automatically
|
|
25
|
-
#
|
|
24
|
+
# Called automatically by `Resource.inherited`. The class is added to
|
|
25
|
+
# the registry hash **before** any model introspection so that even
|
|
26
|
+
# if soft-delete registration raises, the resource is still
|
|
27
|
+
# discoverable (and will be retried by {.finalize!}).
|
|
28
|
+
#
|
|
29
|
+
# The eager soft-delete call fires with whatever `adapter_class` is
|
|
30
|
+
# set at inheritance time, which for non-AR resources is the parent
|
|
31
|
+
# default (`:active_record`) — that's wrong but expected. The error
|
|
32
|
+
# is swallowed and {.finalize!} re-runs with the correct adapter
|
|
33
|
+
# after the class body has finished evaluating.
|
|
26
34
|
#
|
|
27
35
|
# @param resource_class [Class] The resource class to register
|
|
28
36
|
# @return [Class] The registered resource class
|
|
29
37
|
def register(resource_class)
|
|
30
|
-
|
|
31
|
-
|
|
38
|
+
# Stage the registry key first so the resource is discoverable
|
|
39
|
+
# even if `register_soft_delete_features` raises. We use a key
|
|
40
|
+
# derived from the class name (no adapter/model lookup) so HTTP
|
|
41
|
+
# resources without a Ruby model class — and any other case where
|
|
42
|
+
# `resource_name` would touch a not-yet-loaded adapter — still
|
|
43
|
+
# land in the registry.
|
|
44
|
+
resources[registry_key_for(resource_class)] = resource_class
|
|
45
|
+
begin
|
|
46
|
+
resource_class.register_soft_delete_features
|
|
47
|
+
rescue StandardError
|
|
48
|
+
# Swallow eager-registration failures silently — `finalize!`
|
|
49
|
+
# retries with the correct adapter once the class body has
|
|
50
|
+
# fully evaluated, and logs there.
|
|
51
|
+
nil
|
|
52
|
+
end
|
|
53
|
+
resource_class
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Runs every post-load registration step on every registered resource.
|
|
57
|
+
#
|
|
58
|
+
# Called by the engine's `to_prepare` block once all resource classes
|
|
59
|
+
# have been eager-loaded and their bodies have fully evaluated. By
|
|
60
|
+
# then `adapter_class`, `model_class_override`, etc. are set
|
|
61
|
+
# correctly, so model introspection through the adapter is safe.
|
|
62
|
+
#
|
|
63
|
+
# Soft-delete registration is idempotent; resources that succeeded
|
|
64
|
+
# eagerly during {.register} are skipped here. Failures are logged
|
|
65
|
+
# and swallowed per resource so a single broken resource (missing
|
|
66
|
+
# model class, unreachable DB, etc.) doesn't take down the boot.
|
|
67
|
+
#
|
|
68
|
+
# The cached `@adapter` instance is invalidated for every resource
|
|
69
|
+
# before re-running registration. The eager `Resource.adapter` call
|
|
70
|
+
# at inheritance time memoized an `Adapters::ActiveRecord.new(model)`
|
|
71
|
+
# — built with whatever `adapter_class` defaulted to before the
|
|
72
|
+
# class body's `self.adapter_class = :mongoid` (or `:http`) had
|
|
73
|
+
# taken effect. Without this invalidation, every subsequent
|
|
74
|
+
# `Resource.adapter` would keep returning that stale AR adapter
|
|
75
|
+
# and Mongoid/HTTP resources would 500 with `undefined method
|
|
76
|
+
# 'columns' for <MongoidModel>`.
|
|
77
|
+
#
|
|
78
|
+
# @return [void]
|
|
79
|
+
def finalize!
|
|
80
|
+
all.each do |resource_class|
|
|
81
|
+
resource_class.instance_variable_set(:@adapter, nil)
|
|
82
|
+
resource_class.register_soft_delete_features
|
|
83
|
+
rescue StandardError => e
|
|
84
|
+
warn_finalize_failure(resource_class, e)
|
|
85
|
+
end
|
|
32
86
|
end
|
|
33
87
|
|
|
34
88
|
# Returns all registered resource classes.
|
|
@@ -89,6 +143,25 @@ module IronAdmin
|
|
|
89
143
|
def resources
|
|
90
144
|
@resources ||= {}
|
|
91
145
|
end
|
|
146
|
+
|
|
147
|
+
# Builds the registry key without touching the adapter or model.
|
|
148
|
+
# Falls back from `resource_class.resource_name` (which delegates
|
|
149
|
+
# to the adapter and may raise on HTTP/Mongoid resources before
|
|
150
|
+
# `to_prepare` finalizes the lifecycle) to a name derived purely
|
|
151
|
+
# from the class identifier.
|
|
152
|
+
def registry_key_for(resource_class)
|
|
153
|
+
resource_class.resource_name
|
|
154
|
+
rescue StandardError
|
|
155
|
+
resource_class.name.demodulize.sub(/Resource\z/, "").underscore.pluralize
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def warn_finalize_failure(resource_class, error)
|
|
159
|
+
return unless defined?(Rails) && Rails.respond_to?(:logger) && Rails.logger
|
|
160
|
+
|
|
161
|
+
Rails.logger.warn(
|
|
162
|
+
"[IronAdmin] Could not finalize #{resource_class.name}: #{error.class} (#{error.message})"
|
|
163
|
+
)
|
|
164
|
+
end
|
|
92
165
|
end
|
|
93
166
|
end
|
|
94
167
|
end
|
data/lib/iron_admin/tool.rb
CHANGED
|
@@ -1,12 +1,40 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module IronAdmin
|
|
4
|
+
# Base class for admin tools (custom pages in the admin panel).
|
|
5
|
+
#
|
|
6
|
+
# Tools are standalone pages that don't map to a database model.
|
|
7
|
+
# External gems can subclass Tool to add custom admin functionality.
|
|
8
|
+
#
|
|
9
|
+
# @example Simple tool with declarative actions
|
|
10
|
+
# class CacheManagerTool < IronAdmin::Tool
|
|
11
|
+
# menu icon: "server", label: "Cache Manager", group: "System"
|
|
12
|
+
#
|
|
13
|
+
# tool_action :clear_all, icon: "trash", confirm: true
|
|
14
|
+
# tool_action :flush_key,
|
|
15
|
+
# form_fields: [{ name: :cache_key, type: :text, required: true }]
|
|
16
|
+
#
|
|
17
|
+
# def clear_all(ctx)
|
|
18
|
+
# Rails.cache.clear
|
|
19
|
+
# ctx.flash[:notice] = "Cache cleared!"
|
|
20
|
+
# end
|
|
21
|
+
#
|
|
22
|
+
# def flush_key(ctx)
|
|
23
|
+
# key = ctx.action_params(:cache_key)[:cache_key]
|
|
24
|
+
# Rails.cache.delete(key)
|
|
25
|
+
# end
|
|
26
|
+
# end
|
|
4
27
|
class Tool
|
|
5
28
|
class_attribute :menu_options, default: {}
|
|
29
|
+
class_attribute :defined_tool_actions, default: []
|
|
30
|
+
|
|
31
|
+
# @return [ToolContext, nil] Request context, set by ToolsController before action execution
|
|
32
|
+
attr_accessor :context
|
|
6
33
|
|
|
7
34
|
class << self
|
|
8
35
|
def inherited(subclass)
|
|
9
36
|
super
|
|
37
|
+
subclass.defined_tool_actions = defined_tool_actions.dup
|
|
10
38
|
return if subclass.name.nil?
|
|
11
39
|
|
|
12
40
|
begin
|
|
@@ -16,6 +44,28 @@ module IronAdmin
|
|
|
16
44
|
end
|
|
17
45
|
end
|
|
18
46
|
|
|
47
|
+
# Declares a tool action with metadata.
|
|
48
|
+
#
|
|
49
|
+
# @param name [Symbol] Method name to call when action is executed
|
|
50
|
+
# @param options [Hash] Action options passed to ToolAction.new
|
|
51
|
+
# @option options [String] :label Display label
|
|
52
|
+
# @option options [String] :icon Heroicon name
|
|
53
|
+
# @option options [Boolean] :confirm Show confirmation dialog
|
|
54
|
+
# @option options [String] :confirm_message Custom confirmation text
|
|
55
|
+
# @option options [Array<Hash, ActionField>] :form_fields Fields to collect before execution
|
|
56
|
+
# @option options [Proc] :condition Proc receiving user, returns boolean
|
|
57
|
+
def tool_action(name, **)
|
|
58
|
+
self.defined_tool_actions = defined_tool_actions + [ToolAction.new(name: name, **)]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Finds a declared tool action by name.
|
|
62
|
+
#
|
|
63
|
+
# @param name [Symbol, String] Action name
|
|
64
|
+
# @return [ToolAction, nil]
|
|
65
|
+
def find_tool_action(name)
|
|
66
|
+
defined_tool_actions.find { |a| a.name == name.to_sym }
|
|
67
|
+
end
|
|
68
|
+
|
|
19
69
|
def menu(**options)
|
|
20
70
|
self.menu_options = options
|
|
21
71
|
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module IronAdmin
|
|
4
|
+
# Value object representing a declared action on a Tool.
|
|
5
|
+
#
|
|
6
|
+
# Stores action metadata: display label, icon, confirmation settings,
|
|
7
|
+
# form fields to collect before execution, and authorization condition.
|
|
8
|
+
#
|
|
9
|
+
# @example
|
|
10
|
+
# ToolAction.new(
|
|
11
|
+
# name: :run_task,
|
|
12
|
+
# label: "Run Task",
|
|
13
|
+
# icon: "play",
|
|
14
|
+
# confirm: true,
|
|
15
|
+
# form_fields: [{ name: :task_name, type: :select, options: %w[db:migrate db:seed] }],
|
|
16
|
+
# condition: ->(user) { user.admin? }
|
|
17
|
+
# )
|
|
18
|
+
class ToolAction
|
|
19
|
+
# @return [Symbol] Action method name
|
|
20
|
+
attr_reader :name
|
|
21
|
+
|
|
22
|
+
# @return [String] Display label
|
|
23
|
+
attr_reader :label
|
|
24
|
+
|
|
25
|
+
# @return [String, nil] Heroicon name
|
|
26
|
+
attr_reader :icon
|
|
27
|
+
|
|
28
|
+
# @return [Boolean] Whether to show confirmation dialog
|
|
29
|
+
attr_reader :confirm
|
|
30
|
+
|
|
31
|
+
# @return [String, nil] Custom confirmation message
|
|
32
|
+
attr_reader :confirm_message
|
|
33
|
+
|
|
34
|
+
# @return [Array<ActionField>] Form fields to collect before execution
|
|
35
|
+
attr_reader :form_fields
|
|
36
|
+
|
|
37
|
+
# @return [Proc, nil] Condition proc that receives current_user, returns boolean
|
|
38
|
+
attr_reader :condition
|
|
39
|
+
|
|
40
|
+
def initialize(name:, label: nil, icon: nil, confirm: false, confirm_message: nil, form_fields: [], condition: nil)
|
|
41
|
+
@name = name.to_sym
|
|
42
|
+
@label = label || name.to_s.humanize
|
|
43
|
+
@icon = icon
|
|
44
|
+
@confirm = confirm
|
|
45
|
+
@confirm_message = confirm_message
|
|
46
|
+
@form_fields = coerce_form_fields(form_fields)
|
|
47
|
+
@condition = condition
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# @return [Boolean] Whether this action has form fields to collect
|
|
51
|
+
def has_form? # rubocop:disable Naming/PredicatePrefix
|
|
52
|
+
form_fields.any?
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Checks if the action is allowed for the given user.
|
|
56
|
+
#
|
|
57
|
+
# @param user [Object, nil] Current user
|
|
58
|
+
# @return [Boolean]
|
|
59
|
+
def allowed?(user)
|
|
60
|
+
return true if condition.nil?
|
|
61
|
+
|
|
62
|
+
condition.call(user)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
|
|
67
|
+
def coerce_form_fields(fields)
|
|
68
|
+
Array(fields).map do |f|
|
|
69
|
+
f.is_a?(ActionField) ? f : ActionField.new(**f)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module IronAdmin
|
|
4
|
+
# Lightweight request context injected into Tool instances before action execution.
|
|
5
|
+
#
|
|
6
|
+
# Provides tools with access to request params, the current user, and flash messages
|
|
7
|
+
# without coupling them to the controller.
|
|
8
|
+
#
|
|
9
|
+
# @example Accessing context in a tool action
|
|
10
|
+
# class ReportTool < IronAdmin::Tool
|
|
11
|
+
# tool_action :generate
|
|
12
|
+
#
|
|
13
|
+
# def generate(ctx)
|
|
14
|
+
# user = ctx.current_user
|
|
15
|
+
# format = ctx.action_params(:format)[:format]
|
|
16
|
+
# ctx.flash[:notice] = "Report generated for #{user.name}"
|
|
17
|
+
# end
|
|
18
|
+
# end
|
|
19
|
+
class ToolContext
|
|
20
|
+
# @return [ActionController::Parameters] Raw request params
|
|
21
|
+
attr_reader :params
|
|
22
|
+
|
|
23
|
+
# @return [Object, nil] Current authenticated user
|
|
24
|
+
attr_reader :current_user
|
|
25
|
+
|
|
26
|
+
# @return [ActionDispatch::Flash::FlashHash] Flash messages
|
|
27
|
+
attr_reader :flash
|
|
28
|
+
|
|
29
|
+
# @param params [ActionController::Parameters]
|
|
30
|
+
# @param current_user [Object, nil]
|
|
31
|
+
# @param flash [ActionDispatch::Flash::FlashHash]
|
|
32
|
+
def initialize(params:, current_user:, flash:)
|
|
33
|
+
@params = params
|
|
34
|
+
@current_user = current_user
|
|
35
|
+
@flash = flash
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Extracts and permits only the specified keys from tool_action params.
|
|
39
|
+
#
|
|
40
|
+
# @param keys [Array<Symbol>] Keys to permit
|
|
41
|
+
# @return [Hash] Permitted params as a symbolized hash
|
|
42
|
+
def action_params(*keys)
|
|
43
|
+
raw = params.fetch(:tool_action, {})
|
|
44
|
+
return {} unless raw.respond_to?(:permit)
|
|
45
|
+
|
|
46
|
+
raw.permit(*keys).to_h.symbolize_keys
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
data/lib/iron_admin/version.rb
CHANGED