Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/graphql/types/global_id_type.rb')
-rw-r--r--app/graphql/types/global_id_type.rb64
1 files changed, 64 insertions, 0 deletions
diff --git a/app/graphql/types/global_id_type.rb b/app/graphql/types/global_id_type.rb
new file mode 100644
index 00000000000..a3964ba83e1
--- /dev/null
+++ b/app/graphql/types/global_id_type.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+module Types
+ class GlobalIDType < BaseScalar
+ graphql_name 'GlobalID'
+ description 'A global identifier'
+
+ # @param value [GID]
+ # @return [String]
+ def self.coerce_result(value, _ctx)
+ ::Gitlab::GlobalId.as_global_id(value).to_s
+ end
+
+ # @param value [String]
+ # @return [GID]
+ def self.coerce_input(value, _ctx)
+ gid = GlobalID.parse(value)
+ raise GraphQL::CoercionError, "#{value.inspect} is not a valid Global ID" if gid.nil?
+ raise GraphQL::CoercionError, "#{value.inspect} is not a Gitlab Global ID" unless gid.app == GlobalID.app
+
+ gid
+ end
+
+ # Construct a restricted type, that can only be inhabited by an ID of
+ # a given model class.
+ def self.[](model_class)
+ @id_types ||= {}
+
+ @id_types[model_class] ||= Class.new(self) do
+ graphql_name "#{model_class.name.gsub(/::/, '')}ID"
+ description "Identifier of #{model_class.name}"
+
+ self.define_singleton_method(:to_s) do
+ graphql_name
+ end
+
+ self.define_singleton_method(:inspect) do
+ graphql_name
+ end
+
+ self.define_singleton_method(:coerce_result) do |gid, ctx|
+ global_id = ::Gitlab::GlobalId.as_global_id(gid, model_name: model_class.name)
+
+ if suitable?(global_id)
+ global_id.to_s
+ else
+ raise GraphQL::CoercionError, "Expected a #{model_class.name} ID, got #{global_id}"
+ end
+ end
+
+ self.define_singleton_method(:suitable?) do |gid|
+ gid&.model_class&.ancestors&.include?(model_class)
+ end
+
+ self.define_singleton_method(:coerce_input) do |string, ctx|
+ gid = super(string, ctx)
+ raise GraphQL::CoercionError, "#{string.inspect} does not represent an instance of #{model_class.name}" unless suitable?(gid)
+
+ gid
+ end
+ end
+ end
+ end
+end