diff --git a/app/services/hyrax/workflow/workflow_schema.rb b/app/services/hyrax/workflow/workflow_schema.rb index 5ac61cccf2..feb87fa5dc 100644 --- a/app/services/hyrax/workflow/workflow_schema.rb +++ b/app/services/hyrax/workflow/workflow_schema.rb @@ -14,47 +14,107 @@ module Workflow # @see Sipity::Notification # @see Sipity::Method # @see ./lib/generators/hyrax/templates/workflow.json.erb - WorkflowSchema = Dry::Validation.Schema do - configure do - def self.messages - Dry::Validation::Messages.default.merge( - en: { errors: { constant_name?: 'must be an initialized Ruby constant' } } - ) + + # If using dry-validation < 1, create a Dry::Validation::Schema for backwards-compatibility. + # This schema should never ever change. If you need to modify it, upgrade to dry-validation >= 1 + # and use the Dry::Validation::Contract subclass below. + if defined? Dry::Validation::Schema + Deprecation.warn(self, 'The Dry::Validation::Schema implemenation of Hyrax::Workflow::WorkflowSchema is deprecated. ' \ + 'Please upgrade to dry-validation >= 1 to use the Dry::Validation::Contract implementation which will be part of Hyrax 3.0') + WorkflowSchema = Dry::Validation.Schema do + configure do + def self.messages + Dry::Validation::Messages.default.merge( + en: { errors: { constant_name?: 'must be an initialized Ruby constant' } } + ) + end + + def constant_name?(value) + value.constantize + true + rescue NameError + false + end end - def constant_name?(value) - value.constantize - true - rescue NameError - false + required(:workflows).each do + required(:name).filled(:str?) # Sipity::Workflow#name + optional(:label).filled(:str?) # Sipity::Workflow#label + optional(:description).filled(:str?) # Sipity::Workflow#description + optional(:allows_access_grant).filled(:bool?) # Sipity::Workflow#allows_access_grant? + required(:actions).each do + schema do + required(:name).filled(:str?) # Sipity::WorkflowAction#name + required(:from_states).each do + schema do + required(:names) { array? { each(:str?) } } # Sipity::WorkflowState#name + required(:roles) { array? { each(:str?) } } # Sipity::Role#name + end + end + optional(:transition_to).filled(:str?) # Sipity::WorkflowState#name + optional(:notifications).each do + schema do + required(:name).value(:constant_name?) # Sipity::Notification#name + required(:notification_type).value(included_in?: Sipity::Notification.valid_notification_types) + required(:to) { array? { each(:str?) } } + optional(:cc) { array? { each(:str?) } } + optional(:bcc) { array? { each(:str?) } } + end + end + optional(:methods) { array? { each(:str?) } } # See it_behaves_like "a Hyrax workflow method" + end + end end end + elsif defined? Dry::Validation::Contract + # For dry-validation >= 1 + class WorkflowSchema < Dry::Validation::Contract + class Types + include Dry::Types() - required(:workflows).each do - required(:name).filled(:str?) # Sipity::Workflow#name - optional(:label).filled(:str?) # Sipity::Workflow#label - optional(:description).filled(:str?) # Sipity::Workflow#description - optional(:allows_access_grant).filled(:bool?) # Sipity::Workflow#allows_access_grant? - required(:actions).each do - schema do - required(:name).filled(:str?) # Sipity::WorkflowAction#name - required(:from_states).each do - schema do - required(:names) { array? { each(:str?) } } # Sipity::WorkflowState#name - required(:roles) { array? { each(:str?) } } # Sipity::Role#name - end + Constant = Types::Class.constructor do |v| + begin + v.constantize + rescue NameError => _err + v end - optional(:transition_to).filled(:str?) # Sipity::WorkflowState#name - optional(:notifications).each do - schema do - required(:name).value(:constant_name?) # Sipity::Notification#name + end + end + + # Wrap the result for backwards-compatibility. This will be removed in Hyrax 3.0. + class ResultWrapper < SimpleDelegator + def messages(opts = {}) + errors(opts) + end + end + + # Provide a class method for backwards-compatibility. This will be removed in Hyrax 3.0. + def self.call(data) + ResultWrapper.new(new.call(data)) + end + + params do + required(:workflows).array(:hash) do + required(:name).filled(:string) # Sipity::Workflow#name + optional(:label).filled(:string) # Sipity::Workflow#label + optional(:description).filled(:string) # Sipity::Workflow#description + optional(:allows_access_grant).filled(:bool) # Sipity::Workflow#allows_access_grant? + required(:actions).array(:hash) do + required(:name).filled(:string) # Sipity::WorkflowAction#name + required(:from_states).array(:hash) do + required(:names) { array? { each(:string) } } # Sipity::WorkflowState#name + required(:roles) { array? { each(:string) } } # Sipity::Role#name + end + optional(:transition_to).filled(:string) # Sipity::WorkflowState#name + optional(:notifications).array(:hash) do + required(:name).value(Types::Constant) # Sipity::Notification#name required(:notification_type).value(included_in?: Sipity::Notification.valid_notification_types) - required(:to) { array? { each(:str?) } } - optional(:cc) { array? { each(:str?) } } - optional(:bcc) { array? { each(:str?) } } + required(:to) { array? { each(:string) } } + optional(:cc) { array? { each(:string) } } + optional(:bcc) { array? { each(:string) } } end end - optional(:methods) { array? { each(:str?) } } # See it_behaves_like "a Hyrax workflow method" + optional(:methods) { array? { each(:string) } } # See it_behaves_like "a Hyrax workflow method" end end end diff --git a/hyrax.gemspec b/hyrax.gemspec index 393c5973df..9e025a6f15 100644 --- a/hyrax.gemspec +++ b/hyrax.gemspec @@ -40,9 +40,9 @@ SUMMARY spec.add_dependency 'carrierwave', '~> 1.0' spec.add_dependency 'clipboard-rails', '~> 1.5' spec.add_dependency 'dry-equalizer', '~> 0.2' - spec.add_dependency 'dry-struct', '~> 0.1' + spec.add_dependency 'dry-struct', '>= 0.1', '< 2.0' spec.add_dependency 'dry-transaction', '~> 0.11' - spec.add_dependency 'dry-validation', '~> 0.9' + spec.add_dependency 'dry-validation', '>= 0.9', '< 2.0' spec.add_dependency 'flipflop', '~> 2.3' # Pin more tightly because 0.x gems are potentially unstable spec.add_dependency 'flot-rails', '~> 0.0.6'