debug.ts 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. import { capitalize, isEmpty } from 'lodash-es'
  3. import { ApolloLink } from '@apollo/client/core'
  4. import { getMainDefinition } from '@apollo/client/utilities'
  5. import { print } from 'graphql/language/printer'
  6. import type {
  7. DebugLinkRequestOutput,
  8. DebugLinkResponseOutput,
  9. } from '#shared/types/server/apollo/client.ts'
  10. import log from '#shared/utils/log.ts'
  11. const debugLink = new ApolloLink((operation, forward) => {
  12. if (log.getLevel() < log.levels.DEBUG) return forward(operation)
  13. const requestContext = operation.getContext()
  14. const definition = getMainDefinition(operation.query)
  15. const opeationType =
  16. definition.kind === 'OperationDefinition'
  17. ? capitalize(definition.operation)
  18. : null
  19. const requestOutput: DebugLinkRequestOutput = {
  20. printedDocument: print(operation.query),
  21. document: operation.query,
  22. }
  23. if (!isEmpty(operation.variables)) {
  24. requestOutput.variables = operation.variables
  25. }
  26. if (!isEmpty(requestContext.headers)) {
  27. requestOutput.requestHeaders = requestContext.headers
  28. }
  29. // Called before operation is sent to server
  30. operation.setContext({ start: new Date() })
  31. log.debug(
  32. `[GraphQL - Request] - ${opeationType} - ${operation.operationName}:`,
  33. requestOutput,
  34. )
  35. return forward(operation).map((data) => {
  36. const context = operation.getContext()
  37. const end = new Date()
  38. const responseHeaders: Record<string, string> = {}
  39. if (context?.response?.headers) {
  40. context.response.headers.forEach((value: string, key: string) => {
  41. responseHeaders[key] = value
  42. })
  43. }
  44. const duration = end.getTime() - context.start.getTime()
  45. const responseOutput: DebugLinkResponseOutput = {
  46. data,
  47. }
  48. if (!isEmpty(responseHeaders)) {
  49. responseOutput.responseHeaders = responseHeaders
  50. }
  51. log.debug(
  52. `[GraphQL - Response] - ${opeationType} - ${operation.operationName} (took ${duration}ms):`,
  53. responseOutput,
  54. )
  55. return data
  56. })
  57. })
  58. export default debugLink