Просмотр исходного кода

fix(core): Fix entity hydration of nested array entities

Fixes #2013
Michael Bromley 2 лет назад
Родитель
Сommit
55009a5041

+ 2 - 1
packages/core/e2e/entity-hydrator.e2e-spec.ts

@@ -257,13 +257,14 @@ describe('Entity hydration', () => {
             orderResultGuard.assertSuccess(addItemToOrder);
             const channel = await server.app.get(ChannelService).getDefaultChannel();
             // This is ugly, but in our real life example we use a CTX constructed by Vendure
+            const internalOrderId = +addItemToOrder.id.replace(/^\D+/g, '');
             const ctx = new RequestContext({
                 channel,
                 authorizedAsOwnerOnly: true,
                 apiType: 'shop',
                 isAuthorized: true,
                 session: {
-                    activeOrderId: addItemToOrder.id,
+                    activeOrderId: internalOrderId,
                     activeChannelId: 1,
                     user: {
                         id: 2,

+ 25 - 11
packages/core/src/service/helpers/entity-hydrator/entity-hydrator.service.ts

@@ -212,20 +212,34 @@ export class EntityHydrator {
         entity: VendureEntity,
         path: string[],
     ): VendureEntity | VendureEntity[] | undefined {
-        let relation: any = entity;
-        for (let i = 0; i < path.length; i++) {
-            const part = path[i];
-            const isLast = i === path.length - 1;
-            if (relation[part]) {
-                relation =
-                    Array.isArray(relation[part]) && relation[part].length && !isLast
-                        ? relation[part][0]
-                        : relation[part];
-            } else {
+        let isArrayResult = false;
+        const result: VendureEntity[] = [];
+
+        function visit(parent: any, parts: string[]): any {
+            if (parts.length === 0) {
                 return;
             }
+            const part = parts.shift() as string;
+            const target = parent[part];
+            if (Array.isArray(target)) {
+                isArrayResult = true;
+                if (parts.length === 0) {
+                    result.push(...target);
+                } else {
+                    for (const item of target) {
+                        visit(item, parts.slice());
+                    }
+                }
+            } else {
+                if (parts.length === 0) {
+                    result.push(target);
+                } else {
+                    visit(target, parts.slice());
+                }
+            }
         }
-        return relation;
+        visit(entity, path.slice());
+        return isArrayResult ? result : result[0];
     }
 
     private getRelationEntityTypeAtPath(entity: VendureEntity, path: string): Type<VendureEntity> {