소스 검색

chore(core): Fix failing custom fields tests

Michael Bromley 2 년 전
부모
커밋
f7de886d8c

+ 1 - 1
packages/core/e2e/custom-field-relations.e2e-spec.ts

@@ -47,7 +47,6 @@ const entitiesWithCustomFields = enumerate<keyof CustomFields>()(
     'Asset',
     'Channel',
     'Collection',
-    'Country',
     'Customer',
     'CustomerGroup',
     'Facet',
@@ -62,6 +61,7 @@ const entitiesWithCustomFields = enumerate<keyof CustomFields>()(
     'ProductOptionGroup',
     'ProductVariant',
     'Promotion',
+    'Region',
     'Seller',
     'ShippingMethod',
     'TaxCategory',

+ 3 - 1
packages/core/src/api/config/generate-resolvers.ts

@@ -19,6 +19,7 @@ import { CustomFieldRelationResolverService } from '../common/custom-field-relat
 import { ApiType } from '../common/get-api-type';
 import { RequestContext } from '../common/request-context';
 
+import { getCustomFieldsConfigWithoutInterfaces } from './get-custom-fields-config-without-interfaces';
 import { GraphQLMoney } from './money-scalar';
 
 /**
@@ -162,7 +163,8 @@ function generateCustomFieldRelationResolvers(
     const adminResolvers: IResolvers = {};
     const shopResolvers: IResolvers = {};
 
-    for (const [entityName, customFields] of Object.entries(configService.customFields)) {
+    const customFieldsConfig = getCustomFieldsConfigWithoutInterfaces(configService.customFields, schema);
+    for (const [entityName, customFields] of customFieldsConfig) {
         const relationCustomFields = customFields.filter(isRelationalType);
         if (relationCustomFields.length === 0 || !schema.getType(entityName)) {
             continue;

+ 31 - 0
packages/core/src/api/config/get-custom-fields-config-without-interfaces.ts

@@ -0,0 +1,31 @@
+import { GraphQLSchema, isInterfaceType } from 'graphql';
+
+import { CustomFields, CustomFieldConfig } from '../../config/custom-field/custom-field-types';
+
+/**
+ * @description
+ * Because the "Region" entity is an interface, it cannot be extended directly, so we need to
+ * replace it if found in the custom field config with its concrete implementations.
+ */
+export function getCustomFieldsConfigWithoutInterfaces(
+    customFieldConfig: CustomFields,
+    schema: GraphQLSchema,
+): Array<[entityName: string, config: CustomFieldConfig[]]> {
+    const entries = Object.entries(customFieldConfig);
+    const regionIndex = entries.findIndex(([name]) => name === 'Region');
+    if (regionIndex !== -1) {
+        // Region is an interface and cannot directly be extended. Instead, we will use the
+        // concrete types that implement it.
+        const regionType = schema.getType('Region');
+        if (isInterfaceType(regionType)) {
+            const implementations = schema.getImplementations(regionType);
+            // Remove "Region" from the list of entities to which custom fields can be added
+            entries.splice(regionIndex, 1);
+
+            for (const implementation of implementations.objects) {
+                entries.push([implementation.name, customFieldConfig.Region]);
+            }
+        }
+    }
+    return entries;
+}

+ 7 - 19
packages/core/src/api/config/graphql-custom-fields.ts

@@ -11,6 +11,8 @@ import {
 
 import { CustomFieldConfig, CustomFields } from '../../config/custom-field/custom-field-types';
 
+import { getCustomFieldsConfigWithoutInterfaces } from './get-custom-fields-config-without-interfaces';
+
 /**
  * Given a CustomFields config object, generates an SDL string extending the built-in
  * types with a customFields property for all entities, translations and inputs for which
@@ -37,25 +39,11 @@ export function addGraphQLCustomFields(
         `;
     }
 
-    let entityNames = Object.keys(customFieldConfig);
-    if (entityNames.includes('Region')) {
-        // Region is an interface and cannot directly be extended. Instead we will use the
-        // concrete types that implement it.
-        const regionType = schema.getType('Region');
-        if (isInterfaceType(regionType)) {
-            const implementations = schema.getImplementations(regionType);
-            entityNames = entityNames
-                .filter(name => name !== 'Region')
-                .concat(implementations.objects.map(t => t.name));
-        }
-    }
-
-    for (const entityName of entityNames) {
-        const customEntityFields = (customFieldConfig[entityName as keyof CustomFields] || []).filter(
-            config => {
-                return !config.internal && (publicOnly === true ? config.public !== false : true);
-            },
-        );
+    const customFieldsConfig = getCustomFieldsConfigWithoutInterfaces(customFieldConfig, schema);
+    for (const [entityName, customFields] of customFieldsConfig) {
+        const customEntityFields = customFields.filter(config => {
+            return !config.internal && (publicOnly === true ? config.public !== false : true);
+        });
 
         for (const fieldDef of customEntityFields) {
             if (fieldDef.type === 'relation') {