Browse Source

fix(core): Fix nested customField relations "alias was not found" error

Relates to #1664
Michael Bromley 3 years ago
parent
commit
3c48263de9

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

@@ -32,7 +32,12 @@ import { initialData } from '../../../e2e-common/e2e-initial-data';
 import { testConfig, TEST_SETUP_TIMEOUT_MS } from '../../../e2e-common/test-config';
 
 import { testSuccessfulPaymentMethod } from './fixtures/test-payment-methods';
+import {
+    UpdateProductVariantsMutation,
+    UpdateProductVariantsMutationVariables,
+} from './graphql/generated-e2e-admin-types';
 import { AddItemToOrder } from './graphql/generated-e2e-shop-types';
+import { UPDATE_PRODUCT_VARIANTS } from './graphql/shared-definitions';
 import { ADD_ITEM_TO_ORDER } from './graphql/shop-definitions';
 import { sortById } from './utils/test-order-utils';
 
@@ -123,6 +128,14 @@ customFieldConfig.User?.push({
     internal: false,
     public: true,
 });
+customFieldConfig.ProductVariant?.push({
+    name: 'cfRelatedProducts',
+    type: 'relation',
+    entity: Product,
+    list: true,
+    internal: false,
+    public: true,
+});
 
 const testResolverSpy = jest.fn();
 
@@ -856,6 +869,43 @@ describe('Custom field relations', () => {
                 expect(customer).toBeDefined();
             });
 
+            // https://github.com/vendure-ecommerce/vendure/issues/1664
+            it('successfully gets product.variants with nested custom field relation', async () => {
+                await adminClient.query(gql`
+                    mutation {
+                        updateProductVariants(
+                            input: [{ id: "T_1", customFields: { cfRelatedProductsIds: ["T_2"] } }]
+                        ) {
+                            id
+                        }
+                    }
+                `);
+
+                const { product } = await adminClient.query(gql`
+                    query {
+                        product(id: "T_1") {
+                            variants {
+                                id
+                                customFields {
+                                    cfRelatedProducts {
+                                        featuredAsset {
+                                            id
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                `);
+
+                expect(product).toBeDefined();
+                expect(product.variants[0].customFields.cfRelatedProducts).toEqual([
+                    {
+                        featuredAsset: { id: 'T_2' },
+                    },
+                ]);
+            });
+
             it('successfully gets product by slug with eager-loading custom field relation', async () => {
                 const { product } = await shopClient.query(gql`
                     query {

+ 14 - 1
packages/core/src/service/helpers/list-query-builder/list-query-builder.ts

@@ -406,8 +406,21 @@ export class ListQueryBuilder implements OnApplicationBootstrap {
         const entityMap = new Map(entities.map(e => [e.id, e]));
         const entitiesIds = entities.map(({ id }) => id);
 
-        const splitRelations = relations.map(r => r.split('.'));
+        const splitRelations = relations
+            .map(r => r.split('.'))
+            .filter(path => {
+                // There is an issue in TypeORM currently which causes
+                // an error when trying to join nested relations inside
+                // customFields. See https://github.com/vendure-ecommerce/vendure/issues/1664
+                // The work-around is to omit them and rely on the GraphQL resolver
+                // layer to handle.
+                if (path[0] === 'customFields' && 2 < path.length) {
+                    return false;
+                }
+                return true;
+            });
         const groupedRelationsMap = new Map<string, string[]>();
+
         for (const relationParts of splitRelations) {
             const group = groupedRelationsMap.get(relationParts[0]);
             if (group) {