summaryrefslogtreecommitdiff
path: root/lib/gitlab/graphql/present/instrumentation.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/graphql/present/instrumentation.rb')
-rw-r--r--lib/gitlab/graphql/present/instrumentation.rb34
1 files changed, 34 insertions, 0 deletions
diff --git a/lib/gitlab/graphql/present/instrumentation.rb b/lib/gitlab/graphql/present/instrumentation.rb
new file mode 100644
index 00000000000..6f2b26c9676
--- /dev/null
+++ b/lib/gitlab/graphql/present/instrumentation.rb
@@ -0,0 +1,34 @@
+module Gitlab
+ module Graphql
+ module Present
+ class Instrumentation
+ def instrument(type, field)
+ presented_in = field.metadata[:type_class].owner
+ return field unless presented_in.respond_to?(:presenter_class)
+ return field unless presented_in.presenter_class
+
+ old_resolver = field.resolve_proc
+
+ resolve_with_presenter = -> (presented_type, args, context) do
+ # We need to wrap the original presentation type into a type that
+ # uses the presenter as an object.
+ object = presented_type.object
+
+ if object.is_a?(presented_in.presenter_class)
+ next old_resolver.call(presented_type, args, context)
+ end
+
+ presenter = presented_in.presenter_class.new(object, **context.to_h)
+ wrapped = presented_type.class.new(presenter, context)
+
+ old_resolver.call(wrapped, args, context)
+ end
+
+ field.redefine do
+ resolve(resolve_with_presenter)
+ end
+ end
+ end
+ end
+ end
+end