api-extensions.ts 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import { gql } from 'graphql-tag';
  2. import { DocumentNode } from 'graphql';
  3. import { ElasticsearchOptions } from '../options';
  4. export function generateSchemaExtensions(options: ElasticsearchOptions): DocumentNode {
  5. const customMappingTypes = generateCustomMappingTypes(options);
  6. const inputExtensions = Object.entries(options.extendSearchInputType || {});
  7. const sortExtensions = options.extendSearchSortType || [];
  8. const sortExtensionGql = `
  9. extend input SearchResultSortParameter {
  10. ${sortExtensions.map(key => `${key}: SortOrder`).join('\n ')}
  11. }`;
  12. return gql`
  13. extend type SearchResponse {
  14. prices: SearchResponsePriceData!
  15. }
  16. extend type SearchResult {
  17. inStock: Boolean
  18. }
  19. type SearchResponsePriceData {
  20. range: PriceRange!
  21. rangeWithTax: PriceRange!
  22. buckets: [PriceRangeBucket!]!
  23. bucketsWithTax: [PriceRangeBucket!]!
  24. }
  25. type PriceRangeBucket {
  26. to: Int!
  27. count: Int!
  28. }
  29. extend input SearchInput {
  30. priceRange: PriceRangeInput
  31. priceRangeWithTax: PriceRangeInput
  32. inStock: Boolean
  33. groupBySKU: Boolean
  34. ${inputExtensions.map(([name, type]) => `${name}: ${type}`).join('\n ')}
  35. }
  36. ${sortExtensions.length > 0 ? sortExtensionGql : ''}
  37. input PriceRangeInput {
  38. min: Int!
  39. max: Int!
  40. }
  41. ${customMappingTypes ? customMappingTypes : ''}
  42. `;
  43. }
  44. function generateCustomMappingTypes(options: ElasticsearchOptions): DocumentNode | undefined {
  45. const productMappings = Object.entries(options.customProductMappings || {}).filter(
  46. ([, value]) => value.public ?? true,
  47. );
  48. const variantMappings = Object.entries(options.customProductVariantMappings || {}).filter(
  49. ([, value]) => value.public ?? true,
  50. );
  51. const searchInputTypeExtensions = Object.entries(options.extendSearchInputType || {});
  52. const scriptProductFields = Object.entries(options.searchConfig?.scriptFields || {}).filter(
  53. ([, scriptField]) => scriptField.context !== 'variant',
  54. );
  55. const scriptVariantFields = Object.entries(options.searchConfig?.scriptFields || {}).filter(
  56. ([, scriptField]) => scriptField.context !== 'product',
  57. );
  58. let sdl = '';
  59. if (scriptProductFields.length || scriptVariantFields.length) {
  60. if (scriptProductFields.length) {
  61. sdl += `
  62. type CustomProductScriptFields {
  63. ${scriptProductFields.map(([name, def]) => `${name}: ${def.graphQlType}`).join('\n')}
  64. }
  65. `;
  66. }
  67. if (scriptVariantFields.length) {
  68. sdl += `
  69. type CustomProductVariantScriptFields {
  70. ${scriptVariantFields.map(([name, def]) => `${name}: ${def.graphQlType}`).join('\n')}
  71. }
  72. `;
  73. }
  74. if (scriptProductFields.length && scriptVariantFields.length) {
  75. sdl += `
  76. union CustomScriptFields = CustomProductScriptFields | CustomProductVariantScriptFields
  77. extend type SearchResult {
  78. customScriptFields: CustomScriptFields!
  79. }
  80. `;
  81. } else if (scriptProductFields.length) {
  82. sdl += `
  83. extend type SearchResult {
  84. customScriptFields: CustomProductScriptFields!
  85. }
  86. `;
  87. } else if (scriptVariantFields.length) {
  88. sdl += `
  89. extend type SearchResult {
  90. customScriptFields: CustomProductVariantScriptFields!
  91. }
  92. `;
  93. }
  94. }
  95. if (productMappings.length || variantMappings.length) {
  96. if (productMappings.length) {
  97. sdl += `
  98. type CustomProductMappings {
  99. ${productMappings.map(([name, def]) => `${name}: ${def.graphQlType}`).join('\n')}
  100. }
  101. `;
  102. }
  103. if (variantMappings.length) {
  104. sdl += `
  105. type CustomProductVariantMappings {
  106. ${variantMappings.map(([name, def]) => `${name}: ${def.graphQlType}`).join('\n')}
  107. }
  108. `;
  109. }
  110. if (productMappings.length && variantMappings.length) {
  111. sdl += `
  112. union CustomMappings = CustomProductMappings | CustomProductVariantMappings
  113. extend type SearchResult {
  114. customMappings: CustomMappings! @deprecated(reason: "Use customProductMappings or customProductVariantMappings")
  115. customProductMappings: CustomProductMappings!
  116. customProductVariantMappings: CustomProductVariantMappings!
  117. }
  118. `;
  119. } else if (productMappings.length) {
  120. sdl += `
  121. extend type SearchResult {
  122. customMappings: CustomProductMappings! @deprecated(reason: "Use customProductMappings or customProductVariantMappings")
  123. customProductMappings: CustomProductMappings!
  124. }
  125. `;
  126. } else if (variantMappings.length) {
  127. sdl += `
  128. extend type SearchResult {
  129. customMappings: CustomProductVariantMappings! @deprecated(reason: "Use customProductMappings or customProductVariantMappings")
  130. customProductVariantMappings: CustomProductVariantMappings!
  131. }
  132. `;
  133. }
  134. }
  135. return sdl.length
  136. ? gql`
  137. ${sdl}
  138. `
  139. : undefined;
  140. }