hyrax 5.1.0 → 5.3.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 (561) hide show
  1. checksums.yaml +4 -4
  2. data/.dassie/.env +5 -1
  3. data/.dassie/Gemfile +5 -3
  4. data/.dassie/app/assets/images/bulkrax/removed.png +0 -0
  5. data/.dassie/app/assets/javascripts/application.js +2 -0
  6. data/.dassie/app/assets/stylesheets/application.css +1 -0
  7. data/.dassie/app/controllers/catalog_controller.rb +1 -0
  8. data/.dassie/app/forms/admin_set_resource_form.rb +6 -0
  9. data/.dassie/app/forms/collection_resource_form.rb +5 -2
  10. data/.dassie/app/forms/generic_work_resource_form.rb +5 -2
  11. data/.dassie/app/forms/monograph_form.rb +5 -3
  12. data/.dassie/app/indexers/admin_set_resource_indexer.rb +5 -0
  13. data/.dassie/app/indexers/collection_resource_indexer.rb +3 -3
  14. data/.dassie/app/indexers/generic_work_resource_indexer.rb +6 -3
  15. data/.dassie/app/indexers/monograph_indexer.rb +6 -2
  16. data/.dassie/app/models/ability.rb +8 -0
  17. data/.dassie/app/models/collection_resource.rb +4 -2
  18. data/.dassie/app/models/concerns/bulkrax/has_local_processing.rb +8 -0
  19. data/.dassie/app/models/generic_work_resource.rb +5 -2
  20. data/.dassie/app/models/monograph.rb +5 -2
  21. data/.dassie/app/views/blacklight_dynamic_sitemap/sitemap/show.xml.builder +22 -0
  22. data/.dassie/bin/importer +142 -0
  23. data/.dassie/bin/web +4 -0
  24. data/.dassie/config/application.rb +1 -1
  25. data/.dassie/config/browse_everything_providers.yml +1 -1
  26. data/.dassie/config/bulkrax_api.yml +86 -0
  27. data/.dassie/config/initializers/bulkrax.rb +92 -0
  28. data/.dassie/config/initializers/clamav.rb +2 -0
  29. data/.dassie/config/initializers/devise.rb +1 -0
  30. data/.dassie/config/initializers/hyrax.rb +7 -1
  31. data/.dassie/config/initializers/riiif.rb +4 -80
  32. data/.dassie/config/initializers/wings.rb +1 -1
  33. data/.dassie/config/metadata_profiles/m3_profile.yaml +929 -0
  34. data/.dassie/config/puma.rb +4 -2
  35. data/.dassie/config/routes.rb +7 -0
  36. data/.dassie/config/sidekiq.yml +17 -0
  37. data/.dassie/config/uv/uv.html +63 -81
  38. data/.dassie/db/migrate/20240606205215_create_hyrax_flexible_schemas.rb +9 -0
  39. data/.dassie/db/migrate/20240606205216_add_contexts_to_hyrax_flexible_schemas.rb +5 -0
  40. data/.dassie/db/migrate/20250826142438_create_bulkrax_importers.bulkrax.rb +19 -0
  41. data/.dassie/db/migrate/20250826142439_create_bulkrax_importer_runs.bulkrax.rb +17 -0
  42. data/.dassie/db/migrate/20250826142440_create_bulkrax_entries.bulkrax.rb +17 -0
  43. data/.dassie/db/migrate/20250826142441_add_status_to_entry.bulkrax.rb +10 -0
  44. data/.dassie/db/migrate/20250826142442_add_collections_to_importer_runs.bulkrax.rb +7 -0
  45. data/.dassie/db/migrate/20250826142443_change_collection_ids_on_entries.bulkrax.rb +6 -0
  46. data/.dassie/db/migrate/20250826142444_create_bulkrax_exporters.bulkrax.rb +20 -0
  47. data/.dassie/db/migrate/20250826142445_create_bulkrax_exporter_runs.bulkrax.rb +15 -0
  48. data/.dassie/db/migrate/20250826142446_change_importer_and_exporter_to_polymorphic.bulkrax.rb +19 -0
  49. data/.dassie/db/migrate/20250826142447_add_total_collection_records_to_importer_runs.bulkrax.rb +6 -0
  50. data/.dassie/db/migrate/20250826142448_add_children_to_importer_runs.bulkrax.rb +7 -0
  51. data/.dassie/db/migrate/20250826142449_change_total_records_to_total_work_entries.bulkrax.rb +7 -0
  52. data/.dassie/db/migrate/20250826142450_change_entry_last_error.bulkrax.rb +20 -0
  53. data/.dassie/db/migrate/20250826142451_add_validate_only_to_bulkrax_importers.bulkrax.rb +6 -0
  54. data/.dassie/db/migrate/20250826142452_add_status_to_importers.bulkrax.rb +10 -0
  55. data/.dassie/db/migrate/20250826142453_remove_foreign_key_from_bulkrax_entries.bulkrax.rb +6 -0
  56. data/.dassie/db/migrate/20250826142454_add_status_to_exporters.bulkrax.rb +8 -0
  57. data/.dassie/db/migrate/20250826142455_add_invalid_record_to_importer_run.bulkrax.rb +6 -0
  58. data/.dassie/db/migrate/20250826142456_create_bulkrax_statuses.bulkrax.rb +19 -0
  59. data/.dassie/db/migrate/20250826142457_move_to_statuses.bulkrax.rb +31 -0
  60. data/.dassie/db/migrate/20250826142458_add_date_filter_and_status_to_bulkrax_exporters.bulkrax.rb +8 -0
  61. data/.dassie/db/migrate/20250826142459_add_workflow_status_to_bulkrax_exporter.bulkrax.rb +6 -0
  62. data/.dassie/db/migrate/20250826142460_remove_unused_last_error.bulkrax.rb +8 -0
  63. data/.dassie/db/migrate/20250826142461_increase_text_sizes.bulkrax.rb +13 -0
  64. data/.dassie/db/migrate/20250826142462_change_bulkrax_statuses_error_message_column_type_to_text.bulkrax.rb +6 -0
  65. data/.dassie/db/migrate/20250826142463_rename_children_counters_to_relationships.bulkrax.rb +7 -0
  66. data/.dassie/db/migrate/20250826142464_add_file_set_counters_to_importer_runs.bulkrax.rb +8 -0
  67. data/.dassie/db/migrate/20250826142465_add_import_attempts_to_entries.bulkrax.rb +6 -0
  68. data/.dassie/db/migrate/20250826142466_add_work_counters_to_importer_runs.bulkrax.rb +7 -0
  69. data/.dassie/db/migrate/20250826142467_create_bulkrax_pending_relationships.bulkrax.rb +14 -0
  70. data/.dassie/db/migrate/20250826142468_add_order_to_bulkrax_pending_relationships.bulkrax.rb +6 -0
  71. data/.dassie/db/migrate/20250826142469_add_include_thumbnails_to_bulkrax_exporters.bulkrax.rb +6 -0
  72. data/.dassie/db/migrate/20250826142470_add_generated_metadata_to_bulkrax_exporters.bulkrax.rb +6 -0
  73. data/.dassie/db/migrate/20250826142471_rename_bulkrax_importer_run_to_importer_run.bulkrax.rb +18 -0
  74. data/.dassie/db/migrate/20250826142472_add_indices_to_bulkrax.bulkrax.rb +26 -0
  75. data/.dassie/db/migrate/20250826142473_denormalize_status_message.bulkrax.rb +8 -0
  76. data/.dassie/db/migrate/20250826142474_update_identifier_index.bulkrax.rb +7 -0
  77. data/.dassie/db/migrate/20250826142475_add_index_to_metadata_bulkrax_identifier.bulkrax.rb +19 -0
  78. data/.dassie/db/migrate/20250826142476_add_file_name_to_uploaded_files.bulkrax.rb +6 -0
  79. data/.dassie/db/migrate/20250826142477_add_error_tracking_to_pending_relationships.bulkrax.rb +6 -0
  80. data/.dassie/db/migrate/20250826142478_add_last_imported_at_to_bulkrax_importers.bulkrax.rb +6 -0
  81. data/.dassie/db/migrate/20250826142479_add_next_import_at_to_bulkrax_importers.bulkrax.rb +6 -0
  82. data/.dassie/db/migrate/20250826142480_entry_error_denormalization.bulkrax.rb +8 -0
  83. data/.dassie/db/migrate/20250826142481_faster_first_entry.bulkrax.rb +8 -0
  84. data/.dassie/db/migrate/20260430000001_create_hyrax_redirect_paths.hyrax.rb +13 -0
  85. data/.dassie/db/migrate/20260521003627_add_additional_redirect_info.hyrax.rb +32 -0
  86. data/.dassie/db/schema.rb +263 -109
  87. data/.dassie/package.json +1 -1
  88. data/.dassie/rspec_split_configuration.json +835 -0
  89. data/.dassie/solr/conf/solrconfig.xml +21 -5
  90. data/.github/{ISSUE_TEMPLATE.md → ISSUE_TEMPLATE/issue_template.md} +5 -0
  91. data/.github/workflows/lint-build-test.yml +6 -2
  92. data/.github/workflows/release-charts.yml +48 -0
  93. data/.gitignore +6 -0
  94. data/.koppie/.env +5 -1
  95. data/.koppie/Gemfile +3 -1
  96. data/.koppie/app/assets/images/bulkrax/removed.png +0 -0
  97. data/.koppie/app/assets/javascripts/application.js +2 -0
  98. data/.koppie/app/assets/stylesheets/application.css +1 -0
  99. data/.koppie/app/controllers/catalog_controller.rb +1 -1
  100. data/.koppie/app/forms/collection_resource_form.rb +5 -2
  101. data/.koppie/app/forms/file_set_form.rb +5 -0
  102. data/.koppie/app/forms/generic_work_form.rb +5 -3
  103. data/.koppie/app/forms/monograph_form.rb +5 -3
  104. data/.koppie/app/indexers/collection_resource_indexer.rb +5 -2
  105. data/.koppie/app/indexers/file_set_indexer.rb +7 -0
  106. data/.koppie/app/indexers/generic_work_indexer.rb +6 -3
  107. data/.koppie/app/indexers/monograph_indexer.rb +6 -2
  108. data/.koppie/app/models/ability.rb +8 -0
  109. data/.koppie/app/models/collection_resource.rb +4 -2
  110. data/.koppie/app/models/concerns/bulkrax/has_local_processing.rb +8 -0
  111. data/.koppie/app/models/generic_work.rb +5 -2
  112. data/.koppie/app/models/monograph.rb +5 -2
  113. data/.koppie/app/views/blacklight_dynamic_sitemap/sitemap/show.xml.builder +22 -0
  114. data/.koppie/bin/importer +142 -0
  115. data/.koppie/bin/web +4 -0
  116. data/.koppie/config/browse_everything_providers.yml +2 -0
  117. data/.koppie/config/bulkrax_api.yml +86 -0
  118. data/.koppie/config/initializers/bulkrax.rb +92 -0
  119. data/.koppie/config/initializers/clamav.rb +2 -0
  120. data/.koppie/config/initializers/devise.rb +1 -1
  121. data/.koppie/config/initializers/hyrax.rb +11 -3
  122. data/.koppie/config/initializers/riiif.rb +4 -82
  123. data/.koppie/config/metadata_profiles/m3_profile.yaml +930 -0
  124. data/.koppie/config/routes.rb +7 -0
  125. data/.koppie/config/sidekiq.yml +2 -0
  126. data/.koppie/config/uv/uv.html +63 -81
  127. data/.koppie/db/migrate/20240606205215_create_hyrax_flexible_schemas.rb +9 -0
  128. data/.koppie/db/migrate/20240606205216_add_contexts_to_hyrax_flexible_schemas.rb +5 -0
  129. data/.koppie/db/migrate/20250826142438_create_bulkrax_importers.bulkrax.rb +19 -0
  130. data/.koppie/db/migrate/20250826142439_create_bulkrax_importer_runs.bulkrax.rb +17 -0
  131. data/.koppie/db/migrate/20250826142440_create_bulkrax_entries.bulkrax.rb +17 -0
  132. data/.koppie/db/migrate/20250826142441_add_status_to_entry.bulkrax.rb +10 -0
  133. data/.koppie/db/migrate/20250826142442_add_collections_to_importer_runs.bulkrax.rb +7 -0
  134. data/.koppie/db/migrate/20250826142443_change_collection_ids_on_entries.bulkrax.rb +6 -0
  135. data/.koppie/db/migrate/20250826142444_create_bulkrax_exporters.bulkrax.rb +20 -0
  136. data/.koppie/db/migrate/20250826142445_create_bulkrax_exporter_runs.bulkrax.rb +15 -0
  137. data/.koppie/db/migrate/20250826142446_change_importer_and_exporter_to_polymorphic.bulkrax.rb +19 -0
  138. data/.koppie/db/migrate/20250826142447_add_total_collection_records_to_importer_runs.bulkrax.rb +6 -0
  139. data/.koppie/db/migrate/20250826142448_add_children_to_importer_runs.bulkrax.rb +7 -0
  140. data/.koppie/db/migrate/20250826142449_change_total_records_to_total_work_entries.bulkrax.rb +7 -0
  141. data/.koppie/db/migrate/20250826142450_change_entry_last_error.bulkrax.rb +20 -0
  142. data/.koppie/db/migrate/20250826142451_add_validate_only_to_bulkrax_importers.bulkrax.rb +6 -0
  143. data/.koppie/db/migrate/20250826142452_add_status_to_importers.bulkrax.rb +10 -0
  144. data/.koppie/db/migrate/20250826142453_remove_foreign_key_from_bulkrax_entries.bulkrax.rb +6 -0
  145. data/.koppie/db/migrate/20250826142454_add_status_to_exporters.bulkrax.rb +8 -0
  146. data/.koppie/db/migrate/20250826142455_add_invalid_record_to_importer_run.bulkrax.rb +6 -0
  147. data/.koppie/db/migrate/20250826142456_create_bulkrax_statuses.bulkrax.rb +19 -0
  148. data/.koppie/db/migrate/20250826142457_move_to_statuses.bulkrax.rb +31 -0
  149. data/.koppie/db/migrate/20250826142458_add_date_filter_and_status_to_bulkrax_exporters.bulkrax.rb +8 -0
  150. data/.koppie/db/migrate/20250826142459_add_workflow_status_to_bulkrax_exporter.bulkrax.rb +6 -0
  151. data/.koppie/db/migrate/20250826142460_remove_unused_last_error.bulkrax.rb +8 -0
  152. data/.koppie/db/migrate/20250826142461_increase_text_sizes.bulkrax.rb +13 -0
  153. data/.koppie/db/migrate/20250826142462_change_bulkrax_statuses_error_message_column_type_to_text.bulkrax.rb +6 -0
  154. data/.koppie/db/migrate/20250826142463_rename_children_counters_to_relationships.bulkrax.rb +7 -0
  155. data/.koppie/db/migrate/20250826142464_add_file_set_counters_to_importer_runs.bulkrax.rb +8 -0
  156. data/.koppie/db/migrate/20250826142465_add_import_attempts_to_entries.bulkrax.rb +6 -0
  157. data/.koppie/db/migrate/20250826142466_add_work_counters_to_importer_runs.bulkrax.rb +7 -0
  158. data/.koppie/db/migrate/20250826142467_create_bulkrax_pending_relationships.bulkrax.rb +14 -0
  159. data/.koppie/db/migrate/20250826142468_add_order_to_bulkrax_pending_relationships.bulkrax.rb +6 -0
  160. data/.koppie/db/migrate/20250826142469_add_include_thumbnails_to_bulkrax_exporters.bulkrax.rb +6 -0
  161. data/.koppie/db/migrate/20250826142470_add_generated_metadata_to_bulkrax_exporters.bulkrax.rb +6 -0
  162. data/.koppie/db/migrate/20250826142471_rename_bulkrax_importer_run_to_importer_run.bulkrax.rb +18 -0
  163. data/.koppie/db/migrate/20250826142472_add_indices_to_bulkrax.bulkrax.rb +26 -0
  164. data/.koppie/db/migrate/20250826142473_denormalize_status_message.bulkrax.rb +8 -0
  165. data/.koppie/db/migrate/20250826142474_update_identifier_index.bulkrax.rb +7 -0
  166. data/.koppie/db/migrate/20250826142475_add_index_to_metadata_bulkrax_identifier.bulkrax.rb +19 -0
  167. data/.koppie/db/migrate/20250826142476_add_file_name_to_uploaded_files.bulkrax.rb +6 -0
  168. data/.koppie/db/migrate/20250826142477_add_error_tracking_to_pending_relationships.bulkrax.rb +6 -0
  169. data/.koppie/db/migrate/20250826142478_add_last_imported_at_to_bulkrax_importers.bulkrax.rb +6 -0
  170. data/.koppie/db/migrate/20250826142479_add_next_import_at_to_bulkrax_importers.bulkrax.rb +6 -0
  171. data/.koppie/db/migrate/20250826142480_entry_error_denormalization.bulkrax.rb +8 -0
  172. data/.koppie/db/migrate/20250826142481_faster_first_entry.bulkrax.rb +8 -0
  173. data/.koppie/db/migrate/20260430000001_create_hyrax_redirect_paths.hyrax.rb +13 -0
  174. data/.koppie/db/migrate/20260521003627_add_additional_redirect_info.hyrax.rb +32 -0
  175. data/.koppie/db/schema.rb +154 -1
  176. data/.koppie/package.json +1 -1
  177. data/.koppie/rspec_split_configuration.json +835 -0
  178. data/.koppie/solr/conf/solrconfig.xml +0 -5
  179. data/.koppie/yarn.lock +5587 -752
  180. data/.rubocop.yml +1 -0
  181. data/CONTAINERS.md +12 -10
  182. data/Dockerfile +9 -22
  183. data/Gemfile +1 -1
  184. data/Gemfile.allinson +2 -0
  185. data/README.md +1 -2
  186. data/app/actors/hyrax/actors/file_actor.rb +2 -0
  187. data/app/actors/hyrax/actors/file_set_actor.rb +1 -1
  188. data/app/assets/javascripts/hyrax/app.js.erb +143 -10
  189. data/app/assets/javascripts/hyrax/collection_select.js +68 -0
  190. data/app/assets/javascripts/hyrax/copy_permalink_button.js +28 -0
  191. data/app/assets/javascripts/hyrax/redirects.js +45 -0
  192. data/app/assets/javascripts/hyrax/relationships/control.es6 +21 -1
  193. data/app/assets/javascripts/hyrax/select_work_type.es6 +7 -2
  194. data/app/assets/javascripts/hyrax.js +3 -1
  195. data/app/assets/stylesheets/hyrax/_file-show.scss +1 -0
  196. data/app/assets/stylesheets/hyrax/_viewer.scss +8 -0
  197. data/app/assets/stylesheets/hyrax/dashboard.scss +22 -1
  198. data/app/assets/stylesheets/hyrax/sidebar.scss +98 -3
  199. data/app/authorities/qa/authorities/collections.rb +9 -9
  200. data/app/controllers/concerns/hyrax/analytics_error_handling.rb +97 -0
  201. data/app/controllers/concerns/hyrax/collections_controller_behavior.rb +3 -1
  202. data/app/controllers/concerns/hyrax/ensure_migrated_behavior.rb +50 -0
  203. data/app/controllers/concerns/hyrax/flexible_catalog_behavior.rb +206 -0
  204. data/app/controllers/concerns/hyrax/flexible_schema_behavior.rb +17 -0
  205. data/app/controllers/concerns/hyrax/redirect_to_display_url.rb +54 -0
  206. data/app/controllers/concerns/hyrax/valkyrie_downloads_controller_behavior.rb +1 -0
  207. data/app/controllers/concerns/hyrax/works_controller_behavior.rb +54 -11
  208. data/app/controllers/hyrax/admin/admin_sets_controller.rb +21 -13
  209. data/app/controllers/hyrax/admin/analytics/collection_reports_controller.rb +2 -0
  210. data/app/controllers/hyrax/admin/analytics/work_reports_controller.rb +5 -4
  211. data/app/controllers/hyrax/admin/metadata_profiles_controller.rb +66 -0
  212. data/app/controllers/hyrax/batch_uploads_controller.rb +2 -0
  213. data/app/controllers/hyrax/dashboard/collections_controller.rb +27 -6
  214. data/app/controllers/hyrax/dashboard/nest_collections_controller.rb +2 -1
  215. data/app/controllers/hyrax/dashboard_controller.rb +2 -1
  216. data/app/controllers/hyrax/file_sets_controller.rb +20 -2
  217. data/app/controllers/hyrax/homepage_controller.rb +7 -0
  218. data/app/controllers/hyrax/my/works_controller.rb +2 -21
  219. data/app/controllers/hyrax/permissions_controller.rb +4 -2
  220. data/app/controllers/hyrax/redirects_controller.rb +56 -0
  221. data/app/controllers/hyrax/single_use_links_viewer_controller.rb +2 -1
  222. data/app/controllers/hyrax/transcripts_controller.rb +31 -0
  223. data/app/controllers/hyrax/uploads_controller.rb +18 -9
  224. data/app/forms/concerns/hyrax/based_near_field_behavior.rb +77 -0
  225. data/app/forms/concerns/hyrax/flexible_form_behavior.rb +37 -0
  226. data/app/forms/concerns/hyrax/redirects_field_behavior.rb +95 -0
  227. data/app/forms/concerns/hyrax/transcripts_behavior.rb +40 -0
  228. data/app/forms/hyrax/forms/admin_set_form.rb +1 -1
  229. data/app/forms/hyrax/forms/administrative_set_form.rb +3 -0
  230. data/app/forms/hyrax/forms/batch_edit_form.rb +1 -3
  231. data/app/forms/hyrax/forms/batch_upload_form.rb +14 -0
  232. data/app/forms/hyrax/forms/file_set_edit_form.rb +1 -1
  233. data/app/forms/hyrax/forms/file_set_form.rb +6 -7
  234. data/app/forms/hyrax/forms/pcdm_collection_form.rb +17 -5
  235. data/app/forms/hyrax/forms/pcdm_object_form.rb +11 -3
  236. data/app/forms/hyrax/forms/resource_batch_edit_form.rb +8 -22
  237. data/app/forms/hyrax/forms/resource_form.rb +110 -10
  238. data/app/forms/hyrax/forms.rb +1 -0
  239. data/app/helpers/hyrax/attributes_helper.rb +109 -0
  240. data/app/helpers/hyrax/blacklight_override.rb +26 -0
  241. data/app/helpers/hyrax/collections_helper.rb +2 -0
  242. data/app/helpers/hyrax/file_set_form_helper.rb +24 -0
  243. data/app/helpers/hyrax/hyrax_helper_behavior.rb +53 -4
  244. data/app/helpers/hyrax/iiif_helper.rb +11 -1
  245. data/app/helpers/hyrax/permalink_helper.rb +37 -0
  246. data/app/helpers/hyrax/redirects_tab_helper.rb +29 -0
  247. data/app/helpers/hyrax/trophy_helper.rb +1 -1
  248. data/app/helpers/hyrax/work_form_helper.rb +9 -5
  249. data/app/helpers/hyrax/works_helper.rb +14 -0
  250. data/app/indexers/concerns/hyrax/workflow_indexer.rb +30 -0
  251. data/app/indexers/hyrax/file_set_indexer.rb +1 -0
  252. data/app/indexers/hyrax/indexers/administrative_set_indexer.rb +2 -1
  253. data/app/indexers/hyrax/indexers/file_set_indexer.rb +6 -2
  254. data/app/indexers/hyrax/indexers/pcdm_collection_indexer.rb +11 -1
  255. data/app/indexers/hyrax/indexers/pcdm_object_indexer.rb +25 -4
  256. data/app/indexers/hyrax/indexers/redirects_indexer.rb +29 -0
  257. data/app/indexers/hyrax/indexers/resource_indexer.rb +4 -0
  258. data/app/indexers/hyrax/indexers.rb +2 -0
  259. data/app/inputs/controlled_vocabulary_input.rb +7 -1
  260. data/app/jobs/concerns/hyrax/queued_job_behavior.rb +22 -0
  261. data/app/jobs/content_deposit_error_event_job.rb +14 -0
  262. data/app/jobs/create_work_job.rb +2 -0
  263. data/app/jobs/hyrax/propagate_change_depositor_job.rb +1 -1
  264. data/app/jobs/hyrax/queued_delete_job.rb +11 -0
  265. data/app/jobs/hyrax/queued_indexing_job.rb +11 -0
  266. data/app/jobs/migrate_files_to_valkyrie_job.rb +39 -21
  267. data/app/jobs/migrate_sipity_entity_job.rb +21 -0
  268. data/app/models/batch_upload_item.rb +4 -0
  269. data/app/models/concerns/hyrax/ability/flexible_metadata_ability.rb +10 -0
  270. data/app/models/concerns/hyrax/ability.rb +7 -3
  271. data/app/models/concerns/hyrax/collection_behavior.rb +4 -0
  272. data/app/models/concerns/hyrax/file_set/transcripts.rb +16 -0
  273. data/app/models/concerns/hyrax/file_set_behavior.rb +9 -0
  274. data/app/models/concerns/hyrax/flexibility.rb +107 -0
  275. data/app/models/concerns/hyrax/redirects_normalization.rb +38 -0
  276. data/app/models/concerns/hyrax/solr_document/characterization.rb +1 -1
  277. data/app/models/concerns/hyrax/solr_document/metadata.rb +9 -0
  278. data/app/models/concerns/hyrax/solr_document/ordered_members.rb +4 -0
  279. data/app/models/concerns/hyrax/solr_document_behavior.rb +28 -3
  280. data/app/models/concerns/hyrax/suppressible.rb +1 -1
  281. data/app/models/concerns/hyrax/valkyrie_lazy_migration.rb +1 -1
  282. data/app/models/concerns/hyrax/with_embargoes_and_leases.rb +30 -0
  283. data/app/models/concerns/hyrax/work_behavior.rb +8 -0
  284. data/app/models/hyrax/administrative_set.rb +1 -1
  285. data/app/models/hyrax/change_set.rb +3 -1
  286. data/app/models/hyrax/embargo.rb +3 -1
  287. data/app/models/hyrax/file_metadata.rb +22 -7
  288. data/app/models/hyrax/file_set.rb +4 -2
  289. data/app/models/hyrax/flexible_schema.rb +219 -0
  290. data/app/models/hyrax/lease.rb +3 -1
  291. data/app/models/hyrax/pcdm_collection.rb +4 -1
  292. data/app/models/hyrax/redirect.rb +64 -0
  293. data/app/models/hyrax/redirect_path.rb +14 -0
  294. data/app/models/hyrax/resource.rb +22 -25
  295. data/app/models/hyrax/riiif/file.rb +43 -0
  296. data/app/models/hyrax/riiif/file_resolver.rb +65 -0
  297. data/app/models/hyrax/uploaded_file.rb +9 -0
  298. data/app/models/hyrax/virus_scanner.rb +16 -3
  299. data/app/models/hyrax/work.rb +4 -1
  300. data/app/models/job_io_wrapper.rb +12 -3
  301. data/app/models/user_mailbox.rb +3 -1
  302. data/app/presenters/hyrax/admin_set_presenter.rb +11 -0
  303. data/app/presenters/hyrax/annotates_content.rb +35 -0
  304. data/app/presenters/hyrax/collection_presenter.rb +5 -1
  305. data/app/presenters/hyrax/displays_content.rb +133 -0
  306. data/app/presenters/hyrax/displays_image.rb +11 -4
  307. data/app/presenters/hyrax/displays_transcripts.rb +59 -0
  308. data/app/presenters/hyrax/file_set_presenter.rb +8 -18
  309. data/app/presenters/hyrax/google_scholar_presenter.rb +39 -0
  310. data/app/presenters/hyrax/iiif_manifest_presenter.rb +22 -4
  311. data/app/presenters/hyrax/missing_method_behavior.rb +15 -0
  312. data/app/presenters/hyrax/pcdm_member_presenter_factory.rb +2 -4
  313. data/app/presenters/hyrax/work_show_presenter.rb +56 -14
  314. data/app/renderers/hyrax/renderers/attribute_renderer.rb +6 -2
  315. data/app/renderers/hyrax/renderers/license_attribute_renderer.rb +10 -10
  316. data/app/renderers/hyrax/renderers/redirects_label_attribute_renderer.rb +25 -0
  317. data/app/renderers/hyrax/renderers/rights_statement_attribute_renderer.rb +10 -11
  318. data/app/search_builders/hyrax/dashboard/nested_collections_search_builder.rb +1 -5
  319. data/app/search_builders/hyrax/filter_by_type.rb +1 -1
  320. data/app/services/hyrax/action/create_valkyrie_work.rb +3 -2
  321. data/app/services/hyrax/analytics/ga4/base.rb +1 -1
  322. data/app/services/hyrax/analytics/ga4.rb +5 -1
  323. data/app/services/hyrax/authority_rendering_helper.rb +28 -0
  324. data/app/services/hyrax/authority_service.rb +107 -0
  325. data/app/services/hyrax/callbacks.rb +2 -2
  326. data/app/services/hyrax/change_depositor_service.rb +1 -1
  327. data/app/services/hyrax/characterization/valkyrie_characterization_service.rb +21 -13
  328. data/app/services/hyrax/collections/nested_collection_query_service.rb +9 -3
  329. data/app/services/hyrax/collections_service.rb +17 -0
  330. data/app/services/hyrax/custom_queries/find_by_property_value.rb +89 -0
  331. data/app/services/hyrax/custom_queries/find_ids_by_model.rb +31 -6
  332. data/app/services/hyrax/edit_permissions_service.rb +11 -10
  333. data/app/services/hyrax/file_set_type_service.rb +12 -4
  334. data/app/services/hyrax/flexible_schema_validator_service.rb +153 -0
  335. data/app/services/hyrax/flexible_schema_validators/class_validator.rb +123 -0
  336. data/app/services/hyrax/flexible_schema_validators/core_metadata_validator.rb +211 -0
  337. data/app/services/hyrax/flexible_schema_validators/existing_records_validator.rb +83 -0
  338. data/app/services/hyrax/flexible_schema_validators/redirects_validator.rb +116 -0
  339. data/app/services/hyrax/flexible_schema_validators/schema_validator.rb +34 -0
  340. data/app/services/hyrax/flexible_schema_validators/sort_properties_validator.rb +54 -0
  341. data/app/services/hyrax/license_service.rb +1 -1
  342. data/app/services/hyrax/listeners/metadata_index_listener.rb +11 -0
  343. data/app/services/hyrax/m3_profile_editor.rb +32 -0
  344. data/app/services/hyrax/m3_schema_loader.rb +119 -0
  345. data/app/services/hyrax/manifest_builder_service.rb +18 -24
  346. data/app/services/hyrax/permalink_path.rb +25 -0
  347. data/app/services/hyrax/qa_select_service.rb +9 -5
  348. data/app/services/hyrax/redirect_path_normalizer.rb +58 -0
  349. data/app/services/hyrax/redirects_lookup.rb +59 -0
  350. data/app/services/hyrax/resource_permissions_visibility_propagator.rb +54 -0
  351. data/app/services/hyrax/resource_types_service.rb +3 -20
  352. data/app/services/hyrax/rights_statement_service.rb +1 -1
  353. data/app/services/hyrax/schema_loader.rb +205 -0
  354. data/app/services/hyrax/search_service.rb +1 -1
  355. data/app/services/hyrax/simple_schema_loader.rb +28 -127
  356. data/app/services/hyrax/solr_service.rb +39 -2
  357. data/app/services/hyrax/tolerant_select_service.rb +5 -3
  358. data/app/services/hyrax/valkyrie_upload.rb +2 -2
  359. data/app/services/hyrax/visibility_propagator.rb +4 -1
  360. data/app/services/hyrax/work_uploads_handler.rb +17 -9
  361. data/app/services/hyrax/workflow/workflow_factory.rb +5 -4
  362. data/app/services/migrate_resource_service.rb +8 -2
  363. data/app/uploaders/hyrax/uploaded_file_uploader.rb +2 -2
  364. data/app/utils/hyrax/data_destroyers/collection_branding_destroyer.rb +1 -1
  365. data/app/utils/hyrax/required_data_seeder.rb +1 -0
  366. data/app/utils/hyrax/required_data_seeders/collection_type_seeder.rb +1 -1
  367. data/app/utils/hyrax/required_data_seeders/flexible_profile_seeder.rb +28 -0
  368. data/app/validators/hyrax/controlled_vocabulary_validator.rb +64 -0
  369. data/app/validators/hyrax/redirect_validator.rb +128 -0
  370. data/app/views/_user_util_links.html.erb +2 -1
  371. data/app/views/catalog/_thumbnail_list_default.html.erb +2 -2
  372. data/app/views/collections/edit_fields/_schema_version.html.erb +1 -0
  373. data/app/views/hyrax/admin/admin_sets/_form_metadata.html.erb +24 -2
  374. data/app/views/hyrax/admin/admin_sets/_show_document_list_row.html.erb +1 -1
  375. data/app/views/hyrax/admin/admin_sets/show.html.erb +1 -1
  376. data/app/views/hyrax/admin/analytics/_analytics_error.html.erb +42 -0
  377. data/app/views/hyrax/admin/analytics/collection_reports/_top_collections.html.erb +3 -7
  378. data/app/views/hyrax/admin/analytics/collection_reports/index.html.erb +11 -9
  379. data/app/views/hyrax/admin/analytics/work_reports/_top_file_set_downloads.html.erb +3 -6
  380. data/app/views/hyrax/admin/analytics/work_reports/_top_works.html.erb +2 -3
  381. data/app/views/hyrax/admin/analytics/work_reports/_work_files.html.erb +1 -6
  382. data/app/views/hyrax/admin/analytics/work_reports/index.html.erb +60 -57
  383. data/app/views/hyrax/admin/features/index.html.erb +1 -1
  384. data/app/views/hyrax/admin/metadata_profiles/_import_modal.html.erb +20 -0
  385. data/app/views/hyrax/admin/metadata_profiles/index.html.erb +54 -0
  386. data/app/views/hyrax/base/_attribute_rows.html.erb +4 -21
  387. data/app/views/hyrax/base/_citations.html.erb +1 -0
  388. data/app/views/hyrax/base/_currently_shared.html.erb +2 -1
  389. data/app/views/hyrax/base/_file_manager_thumbnail.html.erb +1 -1
  390. data/app/views/hyrax/base/_form_member_of_collections.html.erb +6 -6
  391. data/app/views/hyrax/base/_form_redirects.html.erb +125 -0
  392. data/app/views/hyrax/base/_form_share.html.erb +7 -2
  393. data/app/views/hyrax/base/_member.html.erb +1 -1
  394. data/app/views/hyrax/base/_social_media.html.erb +3 -1
  395. data/app/views/hyrax/base/iiif_viewers/_universal_viewer.html.erb +1 -1
  396. data/app/views/hyrax/base/show.html.erb +3 -0
  397. data/app/views/hyrax/collections/_default_group.html.erb +3 -0
  398. data/app/views/hyrax/collections/_list_collections.html.erb +3 -0
  399. data/app/views/hyrax/collections/_list_works.html.erb +1 -1
  400. data/app/views/hyrax/collections/_show_document_list_row.html.erb +1 -1
  401. data/app/views/hyrax/collections/show.html.erb +4 -0
  402. data/app/views/hyrax/dashboard/_sidebar.html.erb +4 -2
  403. data/app/views/hyrax/dashboard/collections/_button_for_update_collection.html.erb +2 -1
  404. data/app/views/hyrax/dashboard/collections/_default_group.html.erb +3 -0
  405. data/app/views/hyrax/dashboard/collections/_form.html.erb +17 -0
  406. data/app/views/hyrax/dashboard/collections/_form_for_select_collection.html.erb +7 -10
  407. data/app/views/hyrax/dashboard/collections/_list_collections.html.erb +3 -0
  408. data/app/views/hyrax/dashboard/collections/_list_works.html.erb +1 -1
  409. data/app/views/hyrax/dashboard/collections/_show_document_list_menu.html.erb +13 -12
  410. data/app/views/hyrax/dashboard/collections/_show_document_list_row.html.erb +1 -1
  411. data/app/views/hyrax/dashboard/profiles/_edit_primary.html.erb +1 -8
  412. data/app/views/hyrax/dashboard/profiles/_trophy_edit.html.erb +1 -1
  413. data/app/views/hyrax/dashboard/profiles/show.html.erb +5 -5
  414. data/app/views/hyrax/dashboard/sidebar/_metadata.html.erb +11 -0
  415. data/app/views/hyrax/dashboard/sidebar/_repository_content.html.erb +1 -0
  416. data/app/views/hyrax/dashboard/works/_default_group.html.erb +3 -0
  417. data/app/views/hyrax/dashboard/works/_list_works.html.erb +4 -2
  418. data/app/views/hyrax/file_sets/_form.html.erb +16 -3
  419. data/app/views/hyrax/file_sets/_metadata.html.erb +35 -0
  420. data/app/views/hyrax/file_sets/_valkyrie_form.html.erb +37 -0
  421. data/app/views/hyrax/file_sets/edit.html.erb +14 -8
  422. data/app/views/hyrax/file_sets/media_display/_audio.html.erb +4 -0
  423. data/app/views/hyrax/file_sets/media_display/_image.html.erb +2 -2
  424. data/app/views/hyrax/file_sets/media_display/_video.html.erb +4 -0
  425. data/app/views/hyrax/homepage/_explore_collections.html.erb +1 -1
  426. data/app/views/hyrax/homepage/_featured_fields.html.erb +1 -1
  427. data/app/views/hyrax/homepage/_recent_document.html.erb +1 -1
  428. data/app/views/hyrax/homepage/robots.text.erb +17 -0
  429. data/app/views/hyrax/my/_admin_set_action_menu.html.erb +31 -27
  430. data/app/views/hyrax/my/_collection_action_menu.html.erb +40 -35
  431. data/app/views/hyrax/my/_work_action_menu.html.erb +23 -22
  432. data/app/views/hyrax/my/collections/_default_group.html.erb +3 -0
  433. data/app/views/hyrax/my/collections/_list_collections.html.erb +3 -0
  434. data/app/views/hyrax/my/collections/_modal_add_subcollection.html.erb +2 -2
  435. data/app/views/hyrax/my/collections/_modal_add_to_collection.html.erb +2 -2
  436. data/app/views/hyrax/my/works/_default_group.html.erb +3 -0
  437. data/app/views/hyrax/my/works/_list_works.html.erb +5 -2
  438. data/app/views/hyrax/shared/_copy_permalink.html.erb +10 -0
  439. data/app/views/hyrax/users/_user_info.html.erb +1 -6
  440. data/app/views/layouts/_head_tag_content.html.erb +2 -0
  441. data/app/views/layouts/hyrax/dashboard.html.erb +2 -1
  442. data/app/views/records/edit_fields/_contexts.html.erb +1 -0
  443. data/app/views/records/edit_fields/_license.html.erb +17 -5
  444. data/app/views/records/edit_fields/_resource_type.html.erb +16 -2
  445. data/app/views/records/edit_fields/_rights_statement.html.erb +17 -5
  446. data/app/views/records/edit_fields/_schema_version.html.erb +1 -0
  447. data/app/views/records/edit_fields/_transcript_ids.html.erb +18 -0
  448. data/app/views/records/show_fields/_rights.html.erb +1 -1
  449. data/app/views/shared/_citations.html.erb +46 -31
  450. data/app/views/shared/_schema_version.html.erb +38 -0
  451. data/bin/dev-entrypoint.sh +14 -4
  452. data/chart/hyrax/Chart.yaml +4 -4
  453. data/chart/hyrax/templates/ingress.yaml +3 -0
  454. data/chart/hyrax/values.yaml +10 -8
  455. data/config/features.rb +77 -40
  456. data/config/initializers/blacklight_dynamic_sitemap.rb +43 -0
  457. data/config/initializers/deprecation_patch.rb +27 -0
  458. data/config/initializers/hydra_works.rb +3 -0
  459. data/config/initializers/i18n_extensions.rb +197 -0
  460. data/config/initializers/indexing_adapter_initializer.rb +4 -0
  461. data/config/initializers/new_framework_defaults_7_2.rb +6 -4
  462. data/config/initializers/reform_rails_6_1_monkey_patch.rb +29 -0
  463. data/config/initializers/storage_adapter_initializer.rb +15 -9
  464. data/config/locales/hyrax.de.yml +172 -54
  465. data/config/locales/hyrax.en.yml +183 -66
  466. data/config/locales/hyrax.es.yml +174 -49
  467. data/config/locales/hyrax.fr.yml +169 -45
  468. data/config/locales/hyrax.it.yml +172 -48
  469. data/config/locales/hyrax.pt-BR.yml +172 -54
  470. data/config/locales/hyrax.zh.yml +145 -21
  471. data/config/metadata/basic_metadata.yaml +66 -0
  472. data/config/metadata/batch_edit_metadata.yaml +119 -0
  473. data/config/metadata/core_metadata.yaml +1 -0
  474. data/config/metadata/file_set_metadata.yaml +19 -0
  475. data/config/metadata/redirects.yaml +15 -0
  476. data/config/metadata_profiles/m3_json_schema.json +487 -0
  477. data/config/metadata_profiles/m3_profile.yaml +954 -0
  478. data/config/routes.rb +9 -0
  479. data/docker-compose-allinson.yml +176 -0
  480. data/docker-compose-dassie.yml +18 -10
  481. data/docker-compose-koppie.yml +18 -10
  482. data/docker-compose-sirenia.yml +20 -10
  483. data/documentation/copy_permalink.md +29 -0
  484. data/documentation/developing-your-hyrax-based-app.md +2 -2
  485. data/documentation/file-ingest-characterization.md +763 -0
  486. data/documentation/flexible_metadata.md +113 -0
  487. data/documentation/forms/field_behaviors.md +297 -0
  488. data/documentation/redirects.md +428 -0
  489. data/hyrax.gemspec +9 -4
  490. data/lib/freyja/metadata_adapter.rb +1 -1
  491. data/lib/freyja/persister.rb +36 -5
  492. data/lib/generators/hyrax/collection_resource/collection_resource_generator.rb +2 -2
  493. data/lib/generators/hyrax/collection_resource/templates/collection.rb.erb +5 -1
  494. data/lib/generators/hyrax/collection_resource/templates/collection_form.rb.erb +5 -1
  495. data/lib/generators/hyrax/collection_resource/templates/collection_indexer.rb.erb +6 -1
  496. data/lib/generators/hyrax/iiif_viewer/USAGE +22 -0
  497. data/lib/generators/hyrax/iiif_viewer/iiif_viewer_generator.rb +49 -0
  498. data/lib/generators/hyrax/iiif_viewer/templates/_clover.html.erb +7 -0
  499. data/lib/generators/hyrax/iiif_viewer/templates/clover/clover.css +3328 -0
  500. data/lib/generators/hyrax/iiif_viewer/templates/clover/clover.html +16 -0
  501. data/lib/generators/hyrax/iiif_viewer/templates/clover/clover.js +237 -0
  502. data/lib/generators/hyrax/install_generator.rb +25 -1
  503. data/lib/generators/hyrax/riiif_generator.rb +1 -1
  504. data/lib/generators/hyrax/templates/app/views/blacklight_dynamic_sitemap/sitemap/show.xml.builder +22 -0
  505. data/lib/generators/hyrax/templates/config/clamav.rb +2 -0
  506. data/lib/generators/hyrax/templates/config/initializers/riiif.rb +4 -80
  507. data/lib/generators/hyrax/templates/db/migrate/20240606205215_create_hyrax_flexible_schemas.rb.erb +9 -0
  508. data/lib/generators/hyrax/templates/db/migrate/20240606205216_add_contexts_to_hyrax_flexible_schemas.rb.erb +5 -0
  509. data/lib/generators/hyrax/templates/db/migrate/20260430000001_create_hyrax_redirect_paths.rb.erb +22 -0
  510. data/lib/generators/hyrax/templates/db/migrate/20260521003627_add_additional_redirect_info.rb.erb +39 -0
  511. data/lib/generators/hyrax/templates/package.json +1 -1
  512. data/lib/generators/hyrax/templates/uv.html +60 -82
  513. data/lib/generators/hyrax/work/templates/indexer.rb.erb +1 -1
  514. data/lib/generators/hyrax/work/templates/model.rb.erb +5 -1
  515. data/lib/generators/hyrax/work_resource/templates/form.rb.erb +5 -2
  516. data/lib/generators/hyrax/work_resource/templates/indexer.rb.erb +6 -2
  517. data/lib/generators/hyrax/work_resource/templates/work.rb.erb +5 -2
  518. data/lib/generators/hyrax/work_resource/work_resource_generator.rb +1 -0
  519. data/lib/hyrax/active_fedora_dummy_model.rb +6 -0
  520. data/lib/hyrax/configuration.rb +219 -10
  521. data/lib/hyrax/controlled_vocabulary/importer/language.rb +5 -1
  522. data/lib/hyrax/deprecation.rb +31 -0
  523. data/lib/hyrax/engine.rb +2 -0
  524. data/lib/hyrax/form_fields.rb +17 -5
  525. data/lib/hyrax/indexer.rb +31 -2
  526. data/lib/hyrax/resource_sync/resource_list_writer.rb +3 -0
  527. data/lib/hyrax/schema.rb +15 -4
  528. data/lib/hyrax/specs/shared_specs/factories/administrative_sets.rb +12 -0
  529. data/lib/hyrax/specs/shared_specs/factories/hyrax_embargo.rb +1 -1
  530. data/lib/hyrax/specs/shared_specs/factories/hyrax_file_set.rb +13 -0
  531. data/lib/hyrax/specs/shared_specs/factories/hyrax_lease.rb +5 -1
  532. data/lib/hyrax/specs/shared_specs/factories/hyrax_work.rb +14 -0
  533. data/lib/hyrax/specs/shared_specs/simple_work.rb +41 -0
  534. data/lib/hyrax/specs/shared_specs.rb +1 -0
  535. data/lib/hyrax/transactions/collection_create.rb +2 -1
  536. data/lib/hyrax/transactions/collection_destroy.rb +1 -0
  537. data/lib/hyrax/transactions/collection_update.rb +2 -1
  538. data/lib/hyrax/transactions/container.rb +28 -0
  539. data/lib/hyrax/transactions/steps/add_file_sets.rb +2 -1
  540. data/lib/hyrax/transactions/steps/apply_permission_template_on_update.rb +65 -0
  541. data/lib/hyrax/transactions/steps/apply_workflow_on_admin_set_change.rb +97 -0
  542. data/lib/hyrax/transactions/steps/ensure_admin_set.rb +1 -1
  543. data/lib/hyrax/transactions/steps/remove_redirect_paths.rb +35 -0
  544. data/lib/hyrax/transactions/steps/save.rb +10 -0
  545. data/lib/hyrax/transactions/steps/set_default_admin_set.rb +1 -1
  546. data/lib/hyrax/transactions/steps/sync_redirect_paths.rb +141 -0
  547. data/lib/hyrax/transactions/work_create.rb +2 -1
  548. data/lib/hyrax/transactions/work_destroy.rb +1 -0
  549. data/lib/hyrax/transactions/work_update.rb +4 -1
  550. data/lib/hyrax/version.rb +1 -1
  551. data/lib/hyrax.rb +62 -0
  552. data/lib/tasks/m3_profile_cleanup.rake +35 -0
  553. data/lib/valkyrie/indexing/redis_queue/indexing_adapter.rb +144 -0
  554. data/lib/wings/valkyrie/query_service.rb +3 -4
  555. data/template.rb +4 -1
  556. metadata +327 -25
  557. data/.dassie/public/robots.txt +0 -1
  558. data/.github/workflows/main.yml +0 -17
  559. data/.koppie/public/robots.txt +0 -1
  560. data/app/forms/concerns/hyrax/basic_metadata_form_fields_behavior.rb +0 -39
  561. data/app/views/catalog/_thumbnail_list_collection.html.erb +0 -4
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hyrax
4
+ ##
5
+ # @api private
6
+ #
7
+ # Read m3 profiles from the database
8
+ #
9
+ # @see config/metadata_profiles/m3_profile.yaml for an example configuration
10
+ class M3SchemaLoader < Hyrax::SchemaLoader
11
+ def view_definitions_for(schema:, version: 1, contexts: nil)
12
+ definitions(schema, version, contexts).each_with_object({}) do |definition, hash|
13
+ view_options = definition.view_options
14
+ # display_label, admin_only, and editor_only keys are always added to
15
+ # the view_options hash. If there are no other view options, skip this
16
+ # field.
17
+ next if view_options.without(:display_label, :admin_only, :editor_only).empty?
18
+
19
+ hash[definition.name] = definition.view_options
20
+ end
21
+ end
22
+
23
+ def config_paths(schema_name = 'm3_profile')
24
+ config_search_paths.collect do |root_path|
25
+ path = root_path.to_s + "/config/metadata_profiles/#{schema_name}.yaml"
26
+ path if File.exist?(path)
27
+ end.compact
28
+ end
29
+
30
+ def current_version
31
+ Hyrax::FlexibleSchema.current_schema_id
32
+ rescue ActiveRecord::StatementInvalid # allow for moments when the database is not yet initialized
33
+ 0
34
+ end
35
+
36
+ private
37
+
38
+ ##
39
+ # @param [#to_s] schema_name
40
+ # @return [Enumerable<AttributeDefinition]
41
+ def definitions(schema_name, version, contexts = nil)
42
+ schema = Hyrax::FlexibleSchema.find_by(id: version) || Hyrax::FlexibleSchema.create_default_schema
43
+ attributes = schema.attributes_for(schema_name)
44
+ attributes ||= fallback_schema_for(schema_name)
45
+ attributes.map do |name, config|
46
+ # We might be able to consolidate these conditions, but they have been kept separate to make it easier to reason about
47
+ # If there is a context filter on the metadata field and no context is set, skip it
48
+ next if contexts.blank? && config['context'].present?
49
+
50
+ # If there is a context filter on the metadata field and we have set a context, but the context does not match, skip it
51
+ next if contexts.present? && config['context'].present? && !(Array(contexts) & Array(config['context'])).any?
52
+
53
+ # Wew, we are in the clear to use this field
54
+ M3AttributeDefinition.new(name, config)
55
+ end.compact
56
+ rescue ActiveRecord::StatementInvalid
57
+ Rails.logger.error "Skipping definition load for migrations to run"
58
+ []
59
+ end
60
+
61
+ # rubocop:disable Metrics/MethodLength
62
+ def fallback_schema_for(_schema_name)
63
+ { "title" =>
64
+ { "cardinality" => { "minimum" => 1 },
65
+ "data_type" => "array",
66
+ "controlled_values" => { "format" => "http://www.w3.org/2001/XMLSchema#string", "sources" => ["null"] },
67
+ "definition" =>
68
+ { "default" =>
69
+ "Enter a standardized title for display. If only one title is needed, transcribe the title from the source itself." },
70
+ "display_label" => { "default" => "Title" },
71
+ "index_documentation" => "displayable, searchable",
72
+ "indexing" => ["title_sim", "title_tesim"],
73
+ "form" => { "primary" => true, "multiple" => true },
74
+ "mappings" =>
75
+ { "metatags" => "twitter:title, og:title",
76
+ "mods_oai_pmh" => "mods:titleInfo/mods:title",
77
+ "qualified_dc_pmh" => "dcterms:title",
78
+ "simple_dc_pmh" => "dc:title" },
79
+ "property_uri" => "http://purl.org/dc/terms/title",
80
+ "range" => "http://www.w3.org/2001/XMLSchema#string",
81
+ "requirement" => "required",
82
+ "sample_values" => ["Pencil drawn portrait study of woman"],
83
+ "view" => { "label" => { "en" => "Title", "es" => "Título" }, "html_dl" => true },
84
+ "type" => "string",
85
+ "predicate" => "http://purl.org/dc/terms/title",
86
+ "index_keys" => ["title_sim", "title_tesim"],
87
+ "multiple" => true,
88
+ "context" => nil } }
89
+ end
90
+ # rubocop:enable Metrics/MethodLength
91
+
92
+ ##
93
+ # @api private
94
+ #
95
+ # M3-specific AttributeDefinition that properly handles cardinality-based requirements
96
+ class M3AttributeDefinition < Hyrax::SchemaLoader::AttributeDefinition
97
+ ##
98
+ # @return [Hash{Symbol => Object}]
99
+ def form_options
100
+ options = super
101
+
102
+ # Check if minimum cardinality makes this field required
103
+ options = options.merge(required: true) if cardinality_required?
104
+
105
+ options
106
+ end
107
+
108
+ private
109
+
110
+ def cardinality_required?
111
+ cardinality = config['cardinality']
112
+ return false unless cardinality.is_a?(Hash)
113
+
114
+ minimum = cardinality['minimum']
115
+ minimum.present? && minimum.to_i >= 1
116
+ end
117
+ end
118
+ end
119
+ end
@@ -21,7 +21,7 @@ module Hyrax
21
21
  # @return [Hash] a Ruby hash representation of a IIIF manifest document
22
22
  #
23
23
  # @see Hyrax::WorksControllerBehavior
24
- def self.manifest_for(presenter:, iiif_manifest_factory: ::IIIFManifest::ManifestFactory)
24
+ def self.manifest_for(presenter:, iiif_manifest_factory: Hyrax.config.iiif_manifest_factory)
25
25
  new(iiif_manifest_factory: iiif_manifest_factory)
26
26
  .manifest_for(presenter: presenter)
27
27
  end
@@ -36,7 +36,7 @@ module Hyrax
36
36
  #
37
37
  # @param iiif_manifest_factory [Class] a class that initializes with presenter
38
38
  # object and returns an object that responds to `#to_h`
39
- def initialize(iiif_manifest_factory: ::IIIFManifest::ManifestFactory)
39
+ def initialize(iiif_manifest_factory: Hyrax.config.iiif_manifest_factory)
40
40
  @manifest_factory = iiif_manifest_factory
41
41
  end
42
42
 
@@ -56,33 +56,27 @@ module Hyrax
56
56
  # @api private
57
57
  # @param presenter [Hyrax::WorkShowPresenter]
58
58
  def sanitized_manifest(presenter:)
59
- # ::IIIFManifest::ManifestBuilder#to_h returns a
60
- # IIIFManifest::ManifestBuilder::IIIFManifest, not a Hash.
61
- # to get a Hash, we have to call its #to_json, then parse.
62
- #
63
- # wild times. maybe there's a better way to do this with the
64
- # ManifestFactory interface?
65
59
  manifest = manifest_factory.new(presenter).to_h
66
- hash = JSON.parse(manifest.to_json)
67
-
68
- hash['label'] = sanitize_value(hash['label']) if hash.key?('label')
69
- hash['description'] = Array(hash['description'])&.collect { |elem| sanitize_value(elem) } if hash.key?('description')
70
-
71
- hash['sequences']&.each do |sequence|
72
- sequence['canvases']&.each do |canvas|
73
- canvas['label'] = sanitize_value(canvas['label'])
74
- end
75
- end
76
-
77
- hash
60
+ hash = manifest.respond_to?(:inner_hash) ? manifest.inner_hash : JSON.parse(manifest.to_json)
61
+ deep_sanitize(hash)
78
62
  end
79
63
 
80
64
  ##
81
65
  # @api private
82
- # @param [#to_s] text
83
- # @return [String] a sanitized verison of `text`
84
- def sanitize_value(text)
85
- Loofah.fragment(text.to_s).scrub!(:prune).to_s
66
+ # Recursively sanitizes all strings in a nested data structure
67
+ # @param obj [Object] the object to sanitize (Hash, Array, String, or other)
68
+ # @return [Object] sanitized version maintaining the original structure
69
+ def deep_sanitize(obj)
70
+ case obj
71
+ when Hash
72
+ obj.transform_values { |v| deep_sanitize(v) }
73
+ when Array
74
+ obj.map { |v| deep_sanitize(v) }
75
+ when String
76
+ CGI.unescapeHTML(Loofah.fragment(obj.to_s).scrub!(:prune).to_s)
77
+ else
78
+ obj
79
+ end
86
80
  end
87
81
  end
88
82
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hyrax
4
+ # Returns the canonical, UUID-based path for a Hyrax resource
5
+ # (e.g. '/concern/generic_works/<uuid>' or '/collections/<uuid>').
6
+ #
7
+ # Collections are routed by the Hyrax engine; works are routed by the
8
+ # host app's curation-concern resources, so the picker consults
9
+ # `resource.collection?` to choose the right route helper.
10
+ module PermalinkPath
11
+ module_function
12
+
13
+ # @param resource [#collection?] a Hyrax::Resource (work or collection)
14
+ # @return [String] the canonical path, e.g. '/concern/generic_works/<uuid>'
15
+ def call(resource)
16
+ helpers = collection_resource?(resource) ? Hyrax::Engine.routes.url_helpers : Rails.application.routes.url_helpers
17
+ helpers.polymorphic_path(resource)
18
+ end
19
+
20
+ def collection_resource?(resource)
21
+ resource.respond_to?(:collection?) && resource.collection?
22
+ end
23
+ private_class_method :collection_resource?
24
+ end
25
+ end
@@ -27,19 +27,22 @@ module Hyrax
27
27
  #
28
28
  # @raise [KeyError] when the key has no `active:` status
29
29
  def active?(id)
30
- authority.find(id).fetch('active')
30
+ result = authority.find(id)
31
+ return false if result.empty?
32
+ result&.fetch('active')
31
33
  end
32
34
 
33
35
  ##
34
36
  # @param id [String]
35
37
  #
36
- # @return [String] the label for the authority
38
+ # @return [String] the label for the authority, falling back to the id itself
39
+ # when no matching term exists. Callers may pass a block to override the
40
+ # fallback value.
37
41
  #
38
42
  # @yield when no 'term' value is present for the id
39
43
  # @yieldreturn [String] an alternate label to return
40
- #
41
- # @raise [KeyError] when no 'term' value is present for the id
42
44
  def label(id, &block)
45
+ block ||= ->(_key) { id }
43
46
  authority.find(id).fetch('term', &block)
44
47
  end
45
48
 
@@ -61,8 +64,9 @@ module Hyrax
61
64
  # that this service knows about HTML rendering details. Maybe a factory
62
65
  # is an appropriate next step?
63
66
  def include_current_value(value, _index, render_options, html_options)
67
+ force_select = html_options[:class].is_a?(Array) ? [' force-select'] : ' force-select'
64
68
  unless value.blank? || active?(value)
65
- html_options[:class] += ' force-select'
69
+ html_options[:class] += force_select
66
70
  render_options += [[label(value) { value }, value]]
67
71
  end
68
72
  [render_options, html_options]
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hyrax
4
+ # Normalizes a user- or system-supplied redirect path into the canonical
5
+ # form stored in `hyrax_redirect_paths` and queried by the resolver.
6
+ # Single source of truth for "what does this path look like on disk?".
7
+ #
8
+ # Normalization rules:
9
+ # 1. If input parses as a URL with scheme/host, keep only the path component
10
+ # (drop scheme, host, port, userinfo, query, fragment).
11
+ # 2. Strip query strings and fragments from path-only inputs.
12
+ # 3. Ensure a leading slash.
13
+ # 4. Strip trailing slashes (but never reduce the path to empty).
14
+ #
15
+ # Idempotent: normalize(normalize(x)) == normalize(x).
16
+ #
17
+ # See documentation/redirects.md.
18
+ module RedirectPathNormalizer
19
+ module_function
20
+
21
+ def call(input)
22
+ return input if input.nil?
23
+ path = input.to_s.strip
24
+ return path if path.empty?
25
+
26
+ path = extract_path(path)
27
+ path = strip_query_and_fragment(path)
28
+ path = ensure_leading_slash(path)
29
+ path = strip_trailing_slashes(path)
30
+ path
31
+ end
32
+
33
+ def extract_path(path)
34
+ return path unless path.match?(%r{\A[a-zA-Z][a-zA-Z0-9+.-]*://})
35
+ uri = URI.parse(path)
36
+ uri.path.presence || '/'
37
+ rescue URI::InvalidURIError
38
+ path
39
+ end
40
+ private_class_method :extract_path
41
+
42
+ def strip_query_and_fragment(path)
43
+ path.sub(/[?#].*\z/, '')
44
+ end
45
+ private_class_method :strip_query_and_fragment
46
+
47
+ def ensure_leading_slash(path)
48
+ path.start_with?('/') ? path : "/#{path}"
49
+ end
50
+ private_class_method :ensure_leading_slash
51
+
52
+ def strip_trailing_slashes(path)
53
+ stripped = path.sub(/\/+\z/, '')
54
+ stripped.empty? ? '/' : stripped
55
+ end
56
+ private_class_method :strip_trailing_slashes
57
+ end
58
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hyrax
4
+ # Single point of truth for read-side queries against the
5
+ # `hyrax_redirect_paths` table. The unique index on `from_path` makes
6
+ # both lookups (`.find_row` and `.taken?`) indexed equality checks on a
7
+ # small derived table — sub-millisecond against any reasonable load.
8
+ #
9
+ # See documentation/redirects.md.
10
+ class RedirectsLookup
11
+ # Returns true if any row exists with the given `from_path`, optionally
12
+ # excluding rows owned by `except_id`. Used by `Hyrax::RedirectValidator`
13
+ # at form-submit time to surface "this alias is already in use" before
14
+ # the DB unique index would reject the insert.
15
+ #
16
+ # @param path [String] the alias to check, normalized or not
17
+ # @param except_id [String, nil] resource_id to exclude from the check
18
+ # @return [Boolean]
19
+ def self.taken?(path, except_id: nil)
20
+ new(path, except_id: except_id).taken?
21
+ end
22
+
23
+ # Returns the `Hyrax::RedirectPath` row matching the given `from_path`,
24
+ # or nil when no row matches. Used by request-time resolvers
25
+ # (`Hyrax::RedirectsController` and the `Hyrax::RedirectToDisplayUrl`
26
+ # before_action) to decide whether the visited path triggers a
27
+ # redirect or in-process dispatch.
28
+ #
29
+ # @param path [String] the visited path, normalized or not
30
+ # @return [Hyrax::RedirectPath, nil]
31
+ def self.find_row(path)
32
+ normalized = Hyrax::RedirectPathNormalizer.call(path)
33
+ return nil if normalized.blank?
34
+ Hyrax::RedirectPath.find_by(from_path: normalized)
35
+ end
36
+
37
+ # Returns the `from_path` of the row marked as the resource's display
38
+ # URL, or nil when no row is marked.
39
+ #
40
+ # @param resource_id [String]
41
+ # @return [String, nil]
42
+ def self.display_path_for(resource_id)
43
+ return nil if resource_id.blank?
44
+ Hyrax::RedirectPath.where(resource_id: resource_id, is_display_url: true).limit(1).pick(:from_path)
45
+ end
46
+
47
+ def initialize(path, except_id: nil)
48
+ @path = Hyrax::RedirectPathNormalizer.call(path)
49
+ @except_id = except_id
50
+ end
51
+
52
+ def taken?
53
+ return false if @path.blank?
54
+ scope = Hyrax::RedirectPath.where(from_path: @path)
55
+ scope = scope.where.not(resource_id: @except_id) if @except_id.present?
56
+ scope.exists?
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hyrax
4
+ ##
5
+ # Propagates visibility from a valkyrie Work to its FileSets
6
+ class ResourcePermissionsVisibilityPropagator
7
+ ##
8
+ # @!attribute [rw] source
9
+ # @return [#visibility]
10
+ attr_accessor :source
11
+
12
+ ##
13
+ # @!attribute [r] embargo_manager
14
+ # @return [Hyrax::EmbargoManager]
15
+ # @!attribute [r] lease_manager
16
+ # @return [Hyrax::LeaseManager]
17
+ # @!attribute [r] persister
18
+ # @return [#save]
19
+ # @!attribute [r] queries
20
+ # @return [Valkyrie::Persistence::CustomQueryContainer]
21
+ attr_reader :embargo_manager, :lease_manager, :persister, :queries
22
+
23
+ ##
24
+ # @param source [#visibility] the object to propagate visibility from
25
+ def initialize(source:,
26
+ embargo_manager: Hyrax::EmbargoManager,
27
+ lease_manager: Hyrax::LeaseManager,
28
+ persister: Hyrax.persister,
29
+ queries: Hyrax.custom_queries)
30
+ @persister = persister
31
+ @queries = queries
32
+ self.source = source
33
+ @embargo_manager = embargo_manager.new(resource: source)
34
+ @lease_manager = lease_manager.new(resource: source)
35
+ end
36
+
37
+ ##
38
+ # @return [void]
39
+ #
40
+ # @raise [RuntimeError] if visibility propagation fails
41
+ def propagate
42
+ queries.find_child_file_sets(resource: source).each do |file_set|
43
+ file_set.visibility = source.visibility
44
+ embargo_manager.copy_embargo_to(target: file_set)
45
+ lease_manager.copy_lease_to(target: file_set)
46
+
47
+ Hyrax::AccessControlList
48
+ .copy_permissions(source: source, target: file_set)
49
+ file_set.permission_manager.acl.save
50
+ persister.save(resource: file_set)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -1,26 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
  module Hyrax
3
3
  module ResourceTypesService
4
- mattr_accessor :authority
5
- self.authority = Qa::Authorities::Local.subauthority_for('resource_types')
4
+ extend Hyrax::AuthorityService
6
5
 
7
- def self.select_options
8
- authority.all.map do |element|
9
- [element[:label], element[:id]]
10
- end
11
- end
12
-
13
- def self.label(id)
14
- authority.find(id).fetch('term')
15
- end
16
-
17
- ##
18
- # @param [String, nil] id identifier of the resource type
19
- #
20
- # @return [String] a schema.org type. Gives the default type if `id` is nil.
21
- def self.microdata_type(id)
22
- return Hyrax.config.microdata_default_type if id.nil?
23
- Microdata.fetch("resource_type.#{id}", default: Hyrax.config.microdata_default_type)
24
- end
6
+ authority_name 'resource_types'
7
+ microdata_namespace 'resource_type.'
25
8
  end
26
9
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  module Hyrax
3
3
  # Provide select options for the copyright status (edm:rights) field
4
- class RightsStatementService < QaSelectService
4
+ class RightsStatementService < TolerantSelectService
5
5
  def initialize(_authority_name = nil)
6
6
  super('rights_statements')
7
7
  end
@@ -0,0 +1,205 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hyrax
4
+ ##
5
+ # @api private
6
+ #
7
+ # This is a simple yaml config-driven schema loader
8
+ #
9
+ # @see config/metadata/basic_metadata.yaml for an example configuration
10
+ class SchemaLoader
11
+ class UndefinedSchemaError < ArgumentError; end
12
+
13
+ ##
14
+ # @param [Symbol] schema
15
+ #
16
+ # @return [Hash<Symbol, Dry::Types::Type>] a map from attribute names to
17
+ # types
18
+ def attributes_for(schema:, version: 1, contexts: nil)
19
+ definitions(schema, version, contexts).each_with_object({}) do |definition, hash|
20
+ hash[definition.name] = definition.type.meta(definition.config)
21
+ end
22
+ end
23
+
24
+ ##
25
+ # @param [Symbol] schema
26
+ #
27
+ # @return [Hash{Symbol => Hash{Symbol => Object}}]
28
+ def form_definitions_for(schema:, version: 1, contexts: nil)
29
+ definitions(schema, version, contexts).each_with_object({}) do |definition, hash|
30
+ next if definition.form_options.empty?
31
+
32
+ hash[definition.name] = definition.form_options
33
+ end
34
+ end
35
+
36
+ ##
37
+ # @param [Symbol] schema
38
+ #
39
+ # @return [{Symbol => Symbol}] a map from index keys to attribute names
40
+ def index_rules_for(schema:, version: 1, contexts: nil)
41
+ definitions(schema, version, contexts).each_with_object({}) do |definition, hash|
42
+ definition.index_keys.each do |key|
43
+ hash[key] = definition.name
44
+ end
45
+ end
46
+ end
47
+
48
+ def current_version
49
+ 1
50
+ end
51
+
52
+ ##
53
+ # @api private
54
+ class AttributeDefinition
55
+ ##
56
+ # @!attr_reader :config
57
+ # @return [Hash<String, Object>]
58
+ # @!attr_reader :name
59
+ # @return [#to_sym]
60
+ attr_reader :config, :name
61
+
62
+ ##
63
+ # @param [#to_sym] name
64
+ # @param [Hash<String, Object>] config
65
+ def initialize(name, config)
66
+ @config = config
67
+ @name = (config['name'] || name).to_sym
68
+ end
69
+
70
+ ##
71
+ # @return [Hash{Symbol => Object}]
72
+ def form_options
73
+ config.fetch('form', {})&.symbolize_keys || {}
74
+ end
75
+
76
+ ##
77
+ # @return [Enumerable<Symbol>]
78
+ def index_keys
79
+ (config.fetch('indexing', nil) || config.fetch('index_keys', []))&.reject { |k| ['facetable', 'stored_searchable', 'admin_only', 'editor_only'].include?(k) }&.map(&:to_sym) || []
80
+ end
81
+
82
+ ##
83
+ # @return [Hash{Symbol => Object}]
84
+ def view_options
85
+ # prefer display_label over view:label for labels, make available in the view
86
+ @view_options = config.fetch('view', {})&.with_indifferent_access || {}
87
+ Deprecation.warn('view: label is deprecated, use display_label instead') if @view_options[:label].present?
88
+ @view_options.delete(:label)
89
+ @view_options[:display_label] = display_label
90
+ @view_options[:admin_only] = admin_only?
91
+ @view_options[:editor_only] = editor_only?
92
+ @view_options
93
+ end
94
+
95
+ def display_label
96
+ return @display_label if @display_label
97
+ @display_label = config.fetch('display_label', {})&.with_indifferent_access || {}
98
+ @display_label = { default: @display_label } if @display_label.is_a?(String)
99
+ @display_label
100
+ end
101
+
102
+ def admin_only?
103
+ @admin_only ||= config.fetch('admin_only', false) || config['indexing']&.include?('admin_only')
104
+ end
105
+
106
+ def editor_only?
107
+ @editor_only ||= config.fetch('editor_only', false) || config['indexing']&.include?('editor_only')
108
+ end
109
+
110
+ ##
111
+ # @return [Dry::Types::Type]
112
+ def type
113
+ member_type = type_for(config['type'])
114
+ wrapper_type = multiple? ? Valkyrie::Types::Array.constructor(&Coerce) : Identity
115
+ wrapper_type.of(member_type)
116
+ end
117
+
118
+ # Cleans up the input before the type system sees it: drops the
119
+ # "no value provided" placeholder dry-types uses internally, then
120
+ # removes blanks. Wraps a bare Hash in a one-element array; using
121
+ # `Array(hash)` would surprise-flatten it into [[:k, v], ...] pairs.
122
+ # Valkyrie's JSONValueMapper unwraps single-element arrays on read,
123
+ # so the type sees a hash here when there was originally one entry.
124
+ Coerce = lambda do |value|
125
+ return [] if value.equal?(Dry::Types::Undefined)
126
+ wrapped = value.is_a?(::Hash) ? [value] : Array(value)
127
+ wrapped.reject { |v| v.equal?(Dry::Types::Undefined) }.select(&:present?)
128
+ end
129
+
130
+ # Determine whether this attribute allows multiple values.
131
+ def multiple?
132
+ return config['multiple'] if config.key?('multiple')
133
+ return true if config.key?('data_type') && config['data_type'] == 'array'
134
+ return false unless (card = config['cardinality'])
135
+
136
+ max = card['maximum']
137
+ max.nil? || max.to_i > 1
138
+ end
139
+
140
+ ##
141
+ # @api private
142
+ #
143
+ # Single-value wrapper that matches the multi-value branch's cleanup:
144
+ # strips the dry-types Undefined placeholder and coerces blank strings to nil.
145
+ # Booleans, numbers, and other types pass through unchanged.
146
+ #
147
+ # @example
148
+ # Identity.of(Valkyrie::Types::String) # => Valkyrie::Types::String with blank-string → nil coercion
149
+ class Identity
150
+ def self.of(type)
151
+ type.constructor do |value|
152
+ next nil if value.equal?(Dry::Types::Undefined)
153
+ value.is_a?(String) ? value.presence : value
154
+ end
155
+ end
156
+ end
157
+
158
+ private
159
+
160
+ ##
161
+ # Resolves a `type:` value from a schema YAML to a Dry::Types::Type.
162
+ #
163
+ # Recognized values:
164
+ # - `id`, `uri`, `date_time` — Valkyrie type shortcuts.
165
+ # - `hash` — for attributes whose entries carry multiple sub-fields
166
+ # (e.g. redirects, with path / canonical / sequence). Use this
167
+ # instead of nesting a Valkyrie::Resource. See
168
+ # `documentation/redirects.md` for a worked example.
169
+ # - Any primitive Valkyrie type, looked up under `Valkyrie::Types::*`
170
+ # by classified name (e.g. `string` → `Valkyrie::Types::String`).
171
+ #
172
+ # Raises `ArgumentError` if nothing matches.
173
+ #
174
+ # @param [String]
175
+ # @return [Dry::Types::Type]
176
+ def type_for(type)
177
+ case type
178
+ when 'id'
179
+ Valkyrie::Types::ID
180
+ when 'uri'
181
+ Valkyrie::Types::URI
182
+ when 'date_time'
183
+ Valkyrie::Types::DateTime
184
+ when 'hash'
185
+ Dry::Types['hash']
186
+ else
187
+ "Valkyrie::Types::#{type.classify}".safe_constantize ||
188
+ raise(ArgumentError, "Unrecognized type: #{type}")
189
+ end
190
+ end
191
+ end
192
+
193
+ class UndefinedSchemaError < ArgumentError; end
194
+
195
+ private
196
+
197
+ def definitions(_schema_name, _version, _contexts)
198
+ raise NotImplementedError, 'Implement #definitions in a child class'
199
+ end
200
+
201
+ def config_search_paths
202
+ Hyrax.config.schema_loader_config_search_paths
203
+ end
204
+ end
205
+ end
@@ -10,7 +10,7 @@ module Hyrax
10
10
 
11
11
  def method_missing(method_name, *arguments, &block)
12
12
  if scope&.respond_to?(method_name)
13
- Deprecation.warn(self.class, "Calling `#{method_name}` on scope " \
13
+ Deprecation.warn("Calling `#{method_name}` on scope " \
14
14
  'is deprecated and will be removed in Blacklight 8. Call #to_h first if you ' \
15
15
  ' need to use hash methods (or, preferably, use your own SearchState implementation)')
16
16
  scope&.public_send(method_name, *arguments, &block)