|
| 1 | +module GraphqlDevise |
| 2 | + class ResourceLoader |
| 3 | + def initialize(resource, options, routing = false) |
| 4 | + @resource = resource |
| 5 | + @options = options |
| 6 | + @routing = routing |
| 7 | + @default_operations = GraphqlDevise::DefaultOperations::MUTATIONS.merge(GraphqlDevise::DefaultOperations::QUERIES) |
| 8 | + end |
| 9 | + |
| 10 | + def call(query, mutation) |
| 11 | + mapping_name = @resource.to_s.underscore.tr('/', '_').to_sym |
| 12 | + |
| 13 | + # clean_options responds to all keys defined in GraphqlDevise::MountMethod::SUPPORTED_OPTIONS |
| 14 | + clean_options = GraphqlDevise::MountMethod::OptionSanitizer.new(@options).call! |
| 15 | + |
| 16 | + return clean_options if GraphqlDevise.resource_mounted?(mapping_name) && @routing |
| 17 | + |
| 18 | + validate_options!(clean_options) |
| 19 | + |
| 20 | + authenticatable_type = clean_options.authenticatable_type.presence || |
| 21 | + "Types::#{@resource}Type".safe_constantize || |
| 22 | + GraphqlDevise::Types::AuthenticatableType |
| 23 | + |
| 24 | + prepared_mutations = prepare_mutations(mapping_name, clean_options, authenticatable_type) |
| 25 | + |
| 26 | + if prepared_mutations.any? && mutation.blank? |
| 27 | + raise GraphqlDevise::Error, 'You need to provide a mutation type unless all mutations are skipped' |
| 28 | + end |
| 29 | + |
| 30 | + prepared_mutations.each do |action, prepared_mutation| |
| 31 | + mutation.field(action, mutation: prepared_mutation) |
| 32 | + end |
| 33 | + |
| 34 | + prepared_resolvers = prepare_resolvers(mapping_name, clean_options, authenticatable_type) |
| 35 | + |
| 36 | + prepared_resolvers.each do |action, resolver| |
| 37 | + query.field(action, resolver: resolver) |
| 38 | + end |
| 39 | + |
| 40 | + GraphqlDevise.add_mapping(mapping_name, @resource) |
| 41 | + GraphqlDevise.mount_resource(mapping_name) if @routing |
| 42 | + |
| 43 | + clean_options |
| 44 | + end |
| 45 | + |
| 46 | + private |
| 47 | + |
| 48 | + def prepare_resolvers(mapping_name, clean_options, authenticatable_type) |
| 49 | + GraphqlDevise::MountMethod::OperationPreparer.new( |
| 50 | + mapping_name: mapping_name, |
| 51 | + custom: clean_options.operations, |
| 52 | + additional_operations: clean_options.additional_queries, |
| 53 | + preparer: GraphqlDevise::MountMethod::OperationPreparers::ResolverTypeSetter.new(authenticatable_type), |
| 54 | + selected_operations: GraphqlDevise::MountMethod::OperationSanitizer.call( |
| 55 | + default: GraphqlDevise::DefaultOperations::QUERIES, only: clean_options.only, skipped: clean_options.skip |
| 56 | + ) |
| 57 | + ).call |
| 58 | + end |
| 59 | + |
| 60 | + def prepare_mutations(mapping_name, clean_options, authenticatable_type) |
| 61 | + GraphqlDevise::MountMethod::OperationPreparer.new( |
| 62 | + mapping_name: mapping_name, |
| 63 | + custom: clean_options.operations, |
| 64 | + additional_operations: clean_options.additional_mutations, |
| 65 | + preparer: GraphqlDevise::MountMethod::OperationPreparers::MutationFieldSetter.new(authenticatable_type), |
| 66 | + selected_operations: GraphqlDevise::MountMethod::OperationSanitizer.call( |
| 67 | + default: GraphqlDevise::DefaultOperations::MUTATIONS, only: clean_options.only, skipped: clean_options.skip |
| 68 | + ) |
| 69 | + ).call |
| 70 | + end |
| 71 | + |
| 72 | + def validate_options!(clean_options) |
| 73 | + GraphqlDevise::MountMethod::OptionsValidator.new( |
| 74 | + [ |
| 75 | + GraphqlDevise::MountMethod::OptionValidators::SkipOnlyValidator.new(options: clean_options), |
| 76 | + GraphqlDevise::MountMethod::OptionValidators::ProvidedOperationsValidator.new( |
| 77 | + options: clean_options, supported_operations: @default_operations |
| 78 | + ) |
| 79 | + ] |
| 80 | + ).validate! |
| 81 | + end |
| 82 | + end |
| 83 | +end |
0 commit comments