diff options
Diffstat (limited to 'app/graphql/types')
-rw-r--r-- | app/graphql/types/base_field.rb | 37 | ||||
-rw-r--r-- | app/graphql/types/base_object.rb | 5 | ||||
-rw-r--r-- | app/graphql/types/ci/pipeline_type.rb | 2 | ||||
-rw-r--r-- | app/graphql/types/group_type.rb | 23 | ||||
-rw-r--r-- | app/graphql/types/issue_type.rb | 12 | ||||
-rw-r--r-- | app/graphql/types/merge_request_type.rb | 2 | ||||
-rw-r--r-- | app/graphql/types/namespace_type.rb | 24 | ||||
-rw-r--r-- | app/graphql/types/permission_types/group.rb | 11 | ||||
-rw-r--r-- | app/graphql/types/project_statistics_type.rb | 16 | ||||
-rw-r--r-- | app/graphql/types/project_type.rb | 9 | ||||
-rw-r--r-- | app/graphql/types/query_type.rb | 10 | ||||
-rw-r--r-- | app/graphql/types/repository_type.rb | 14 | ||||
-rw-r--r-- | app/graphql/types/tree/blob_type.rb | 17 | ||||
-rw-r--r-- | app/graphql/types/tree/entry_type.rb | 14 | ||||
-rw-r--r-- | app/graphql/types/tree/submodule_type.rb | 10 | ||||
-rw-r--r-- | app/graphql/types/tree/tree_entry_type.rb | 15 | ||||
-rw-r--r-- | app/graphql/types/tree/tree_type.rb | 18 | ||||
-rw-r--r-- | app/graphql/types/tree/type_enum.rb | 14 |
18 files changed, 247 insertions, 6 deletions
diff --git a/app/graphql/types/base_field.rb b/app/graphql/types/base_field.rb index 8c8b8a82d3e..dd0d9105df6 100644 --- a/app/graphql/types/base_field.rb +++ b/app/graphql/types/base_field.rb @@ -7,10 +7,43 @@ module Types DEFAULT_COMPLEXITY = 1 def initialize(*args, **kwargs, &block) - # complexity is already defaulted to 1, but let's make it explicit - kwargs[:complexity] ||= DEFAULT_COMPLEXITY + kwargs[:complexity] ||= field_complexity(kwargs[:resolver_class]) super(*args, **kwargs, &block) end + + private + + def field_complexity(resolver_class) + if resolver_class + field_resolver_complexity + else + DEFAULT_COMPLEXITY + end + end + + def field_resolver_complexity + # Complexity can be either integer or proc. If proc is used then it's + # called when computing a query complexity and context and query + # arguments are available for computing complexity. For resolvers we use + # proc because we set complexity depending on arguments and number of + # items which can be loaded. + proc do |ctx, args, child_complexity| + # Resolvers may add extra complexity depending on used arguments + complexity = child_complexity + self.resolver&.try(:resolver_complexity, args, child_complexity: child_complexity).to_i + + field_defn = to_graphql + + if field_defn.connection? + # Resolvers may add extra complexity depending on number of items being loaded. + page_size = field_defn.connection_max_page_size || ctx.schema.default_max_page_size + limit_value = [args[:first], args[:last], page_size].compact.min + multiplier = self.resolver&.try(:complexity_multiplier, args).to_f + complexity += complexity * limit_value * multiplier + end + + complexity.to_i + end + end end end diff --git a/app/graphql/types/base_object.rb b/app/graphql/types/base_object.rb index 82b78abd573..e40059c46bb 100644 --- a/app/graphql/types/base_object.rb +++ b/app/graphql/types/base_object.rb @@ -6,5 +6,10 @@ module Types prepend Gitlab::Graphql::ExposePermissions field_class Types::BaseField + + # All graphql fields exposing an id, should expose a global id. + def id + GitlabSchema.id_from_object(object) + end end end diff --git a/app/graphql/types/ci/pipeline_type.rb b/app/graphql/types/ci/pipeline_type.rb index de7d6570a3e..cff81e5670b 100644 --- a/app/graphql/types/ci/pipeline_type.rb +++ b/app/graphql/types/ci/pipeline_type.rb @@ -10,7 +10,7 @@ module Types expose_permissions Types::PermissionTypes::Ci::Pipeline field :id, GraphQL::ID_TYPE, null: false - field :iid, GraphQL::ID_TYPE, null: false + field :iid, GraphQL::STRING_TYPE, null: false field :sha, GraphQL::STRING_TYPE, null: false field :before_sha, GraphQL::STRING_TYPE, null: true diff --git a/app/graphql/types/group_type.rb b/app/graphql/types/group_type.rb new file mode 100644 index 00000000000..530aecc2bf9 --- /dev/null +++ b/app/graphql/types/group_type.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Types + class GroupType < NamespaceType + graphql_name 'Group' + + authorize :read_group + + expose_permissions Types::PermissionTypes::Group + + field :web_url, GraphQL::STRING_TYPE, null: false + + field :avatar_url, GraphQL::STRING_TYPE, null: true, resolve: -> (group, args, ctx) do + group.avatar_url(only_path: false) + end + + if ::Group.supports_nested_objects? + field :parent, GroupType, + null: true, + resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, obj.parent_id).find } + end + end +end diff --git a/app/graphql/types/issue_type.rb b/app/graphql/types/issue_type.rb index adb137dfee3..dd5133189dc 100644 --- a/app/graphql/types/issue_type.rb +++ b/app/graphql/types/issue_type.rb @@ -15,13 +15,19 @@ module Types field :description, GraphQL::STRING_TYPE, null: true field :state, IssueStateEnum, null: false + field :reference, GraphQL::STRING_TYPE, null: false, method: :to_reference do + argument :full, GraphQL::BOOLEAN_TYPE, required: false, default_value: false + end + field :author, Types::UserType, null: false, resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(User, obj.author_id).find } - field :assignees, Types::UserType.connection_type, null: true + # Remove complexity when BatchLoader is used + field :assignees, Types::UserType.connection_type, null: true, complexity: 5 - field :labels, Types::LabelType.connection_type, null: true + # Remove complexity when BatchLoader is used + field :labels, Types::LabelType.connection_type, null: true, complexity: 5 field :milestone, Types::MilestoneType, null: true, resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Milestone, obj.milestone_id).find } @@ -35,7 +41,9 @@ module Types field :upvotes, GraphQL::INT_TYPE, null: false field :downvotes, GraphQL::INT_TYPE, null: false field :user_notes_count, GraphQL::INT_TYPE, null: false + field :web_path, GraphQL::STRING_TYPE, null: false, method: :issue_path field :web_url, GraphQL::STRING_TYPE, null: false + field :relative_position, GraphQL::INT_TYPE, null: true field :closed_at, Types::TimeType, null: true diff --git a/app/graphql/types/merge_request_type.rb b/app/graphql/types/merge_request_type.rb index 120ffe0dfde..85ac3102442 100644 --- a/app/graphql/types/merge_request_type.rb +++ b/app/graphql/types/merge_request_type.rb @@ -11,7 +11,7 @@ module Types present_using MergeRequestPresenter field :id, GraphQL::ID_TYPE, null: false - field :iid, GraphQL::ID_TYPE, null: false + field :iid, GraphQL::STRING_TYPE, null: false field :title, GraphQL::STRING_TYPE, null: false field :description, GraphQL::STRING_TYPE, null: true field :state, MergeRequestStateEnum, null: false diff --git a/app/graphql/types/namespace_type.rb b/app/graphql/types/namespace_type.rb new file mode 100644 index 00000000000..f6d91320e50 --- /dev/null +++ b/app/graphql/types/namespace_type.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Types + class NamespaceType < BaseObject + graphql_name 'Namespace' + + field :id, GraphQL::ID_TYPE, null: false + + field :name, GraphQL::STRING_TYPE, null: false + field :path, GraphQL::STRING_TYPE, null: false + field :full_name, GraphQL::STRING_TYPE, null: false + field :full_path, GraphQL::ID_TYPE, null: false + + field :description, GraphQL::STRING_TYPE, null: true + field :visibility, GraphQL::STRING_TYPE, null: true + field :lfs_enabled, GraphQL::BOOLEAN_TYPE, null: true, method: :lfs_enabled? + field :request_access_enabled, GraphQL::BOOLEAN_TYPE, null: true + + field :projects, + Types::ProjectType.connection_type, + null: false, + resolver: ::Resolvers::NamespaceProjectsResolver + end +end diff --git a/app/graphql/types/permission_types/group.rb b/app/graphql/types/permission_types/group.rb new file mode 100644 index 00000000000..29833993ce6 --- /dev/null +++ b/app/graphql/types/permission_types/group.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Types + module PermissionTypes + class Group < BasePermissionType + graphql_name 'GroupPermissions' + + abilities :read_group + end + end +end diff --git a/app/graphql/types/project_statistics_type.rb b/app/graphql/types/project_statistics_type.rb new file mode 100644 index 00000000000..62537361918 --- /dev/null +++ b/app/graphql/types/project_statistics_type.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Types + class ProjectStatisticsType < BaseObject + graphql_name 'ProjectStatistics' + + field :commit_count, GraphQL::INT_TYPE, null: false + + field :storage_size, GraphQL::INT_TYPE, null: false + field :repository_size, GraphQL::INT_TYPE, null: false + field :lfs_objects_size, GraphQL::INT_TYPE, null: false + field :build_artifacts_size, GraphQL::INT_TYPE, null: false + field :packages_size, GraphQL::INT_TYPE, null: false + field :wiki_size, GraphQL::INT_TYPE, null: true + end +end diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb index fbb4eddd13c..2236ffa394d 100644 --- a/app/graphql/types/project_type.rb +++ b/app/graphql/types/project_type.rb @@ -66,6 +66,15 @@ module Types field :only_allow_merge_if_all_discussions_are_resolved, GraphQL::BOOLEAN_TYPE, null: true field :printing_merge_request_link_enabled, GraphQL::BOOLEAN_TYPE, null: true + field :namespace, Types::NamespaceType, null: false + field :group, Types::GroupType, null: true + + field :statistics, Types::ProjectStatisticsType, + null: false, + resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchProjectStatisticsLoader.new(obj.id).find } + + field :repository, Types::RepositoryType, null: false + field :merge_requests, Types::MergeRequestType.connection_type, null: true, diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb index 0f655ab9d03..536bdb077ad 100644 --- a/app/graphql/types/query_type.rb +++ b/app/graphql/types/query_type.rb @@ -9,6 +9,16 @@ module Types resolver: Resolvers::ProjectResolver, description: "Find a project" + field :group, Types::GroupType, + null: true, + resolver: Resolvers::GroupResolver, + description: "Find a group" + + field :namespace, Types::NamespaceType, + null: true, + resolver: Resolvers::NamespaceResolver, + description: "Find a namespace" + field :metadata, Types::MetadataType, null: true, resolver: Resolvers::MetadataResolver, diff --git a/app/graphql/types/repository_type.rb b/app/graphql/types/repository_type.rb new file mode 100644 index 00000000000..5987467e1ea --- /dev/null +++ b/app/graphql/types/repository_type.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Types + class RepositoryType < BaseObject + graphql_name 'Repository' + + authorize :download_code + + field :root_ref, GraphQL::STRING_TYPE, null: true + field :empty, GraphQL::BOOLEAN_TYPE, null: false, method: :empty? + field :exists, GraphQL::BOOLEAN_TYPE, null: false, method: :exists? + field :tree, Types::Tree::TreeType, null: true, resolver: Resolvers::TreeResolver + end +end diff --git a/app/graphql/types/tree/blob_type.rb b/app/graphql/types/tree/blob_type.rb new file mode 100644 index 00000000000..760781f3612 --- /dev/null +++ b/app/graphql/types/tree/blob_type.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true +module Types + module Tree + class BlobType < BaseObject + implements Types::Tree::EntryType + + present_using BlobPresenter + + graphql_name 'Blob' + + field :web_url, GraphQL::STRING_TYPE, null: true + field :lfs_oid, GraphQL::STRING_TYPE, null: true, resolve: -> (blob, args, ctx) do + Gitlab::Graphql::Loaders::BatchLfsOidLoader.new(blob.repository, blob.id).find + end + end + end +end diff --git a/app/graphql/types/tree/entry_type.rb b/app/graphql/types/tree/entry_type.rb new file mode 100644 index 00000000000..d8e8642ddb8 --- /dev/null +++ b/app/graphql/types/tree/entry_type.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true +module Types + module Tree + module EntryType + include Types::BaseInterface + + field :id, GraphQL::ID_TYPE, null: false + field :name, GraphQL::STRING_TYPE, null: false + field :type, Tree::TypeEnum, null: false + field :path, GraphQL::STRING_TYPE, null: false + field :flat_path, GraphQL::STRING_TYPE, null: false + end + end +end diff --git a/app/graphql/types/tree/submodule_type.rb b/app/graphql/types/tree/submodule_type.rb new file mode 100644 index 00000000000..cea76dbfd2a --- /dev/null +++ b/app/graphql/types/tree/submodule_type.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true +module Types + module Tree + class SubmoduleType < BaseObject + implements Types::Tree::EntryType + + graphql_name 'Submodule' + end + end +end diff --git a/app/graphql/types/tree/tree_entry_type.rb b/app/graphql/types/tree/tree_entry_type.rb new file mode 100644 index 00000000000..23ec2ef0ec2 --- /dev/null +++ b/app/graphql/types/tree/tree_entry_type.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true +module Types + module Tree + class TreeEntryType < BaseObject + implements Types::Tree::EntryType + + present_using TreeEntryPresenter + + graphql_name 'TreeEntry' + description 'Represents a directory' + + field :web_url, GraphQL::STRING_TYPE, null: true + end + end +end diff --git a/app/graphql/types/tree/tree_type.rb b/app/graphql/types/tree/tree_type.rb new file mode 100644 index 00000000000..1ee93ed9542 --- /dev/null +++ b/app/graphql/types/tree/tree_type.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true +module Types + module Tree + class TreeType < BaseObject + graphql_name 'Tree' + + field :trees, Types::Tree::TreeEntryType.connection_type, null: false, resolve: -> (obj, args, ctx) do + Gitlab::Graphql::Representation::TreeEntry.decorate(obj.trees, obj.repository) + end + + field :submodules, Types::Tree::SubmoduleType.connection_type, null: false + + field :blobs, Types::Tree::BlobType.connection_type, null: false, resolve: -> (obj, args, ctx) do + Gitlab::Graphql::Representation::TreeEntry.decorate(obj.blobs, obj.repository) + end + end + end +end diff --git a/app/graphql/types/tree/type_enum.rb b/app/graphql/types/tree/type_enum.rb new file mode 100644 index 00000000000..6560d91e9e5 --- /dev/null +++ b/app/graphql/types/tree/type_enum.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Types + module Tree + class TypeEnum < BaseEnum + graphql_name 'EntryType' + description 'Type of a tree entry' + + value 'tree', value: :tree + value 'blob', value: :blob + value 'commit', value: :commit + end + end +end |