mocksGraphqlPlugin.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. /* eslint-disable no-nested-ternary */
  3. const { basename } = require('path')
  4. const { convertFactory } = require('@graphql-codegen/visitor-plugin-common')
  5. const camelCase = require('lodash/camelCase.js')
  6. const startCase = require('lodash/startCase.js')
  7. /** @typedef {import('graphql').OperationDefinitionNode} OperationDefinitionNode */
  8. const pascalCase = (str) => startCase(camelCase(str))
  9. const getCompositionFunctionSuffix = (name, operationType) => {
  10. if (
  11. name.includes('Query') ||
  12. name.includes('Mutation') ||
  13. name.includes('Subscription')
  14. ) {
  15. return ''
  16. }
  17. return pascalCase(operationType)
  18. }
  19. const getOperationSuffix = (config, node, operationType) => {
  20. const { omitOperationSuffix = false, dedupeOperationSuffix = false } = config
  21. const operationName =
  22. typeof node === 'string' ? node : node.name ? node.name.value : ''
  23. return omitOperationSuffix
  24. ? ''
  25. : dedupeOperationSuffix &&
  26. operationName.toLowerCase().endsWith(operationType.toLowerCase())
  27. ? ''
  28. : operationType
  29. }
  30. module.exports.plugin = (schema, documents, config) => {
  31. // we assume that there is only one operation per file
  32. // if not, then we take the first operation and assume it is the only one
  33. const node = documents[0].document.definitions[0]
  34. const suffix = getCompositionFunctionSuffix(node.name.value, node.operation)
  35. const convertName = convertFactory(config)
  36. const operationName = convertName(node.name.value, {
  37. suffix,
  38. useTypesPrefix: false,
  39. })
  40. const baseFile = basename(documents[0].location).replace(
  41. /\.graphql$/,
  42. '.api.ts',
  43. )
  44. const documentVariableName = convertName(node, {
  45. suffix: config.documentVariableSuffix || 'Document',
  46. prefix: config.documentVariablePrefix,
  47. useTypesPrefix: false,
  48. })
  49. const operationType = pascalCase(node.operation)
  50. const operationTypeSuffix = getOperationSuffix(config, node, operationType)
  51. const operationResultType = `Types.${convertName(node, {
  52. suffix: operationTypeSuffix,
  53. })}`
  54. const operationVariablesTypes = `Types.${convertName(node, {
  55. suffix: `${operationTypeSuffix}Variables`,
  56. })}`
  57. return {
  58. prepend: [
  59. "import * as Mocks from '#tests/graphql/builders/mocks.ts'",
  60. `import * as Operations from './${baseFile}'`,
  61. ],
  62. content: [
  63. node.operation === 'subscription'
  64. ? `
  65. export function get${operationName}Handler() {
  66. return Mocks.getGraphQLSubscriptionHandler<${operationResultType}>(Operations.${documentVariableName})
  67. }
  68. `
  69. : `
  70. export function mock${operationName}(defaults: Mocks.MockDefaultsValue<${operationResultType}, ${operationVariablesTypes}>) {
  71. return Mocks.mockGraphQLResult(Operations.${documentVariableName}, defaults)
  72. }
  73. export function waitFor${operationName}Calls() {
  74. return Mocks.waitForGraphQLMockCalls<${operationResultType}>(Operations.${documentVariableName})
  75. }
  76. `,
  77. ],
  78. }
  79. }