fix(utils): Mikro orm joined selection issue when select-in strategy (#9615)
* fix(utils): Mikro orm joined selection issue when select-in strategy * fix types --------- Co-authored-by: Carlos R. L. Rodrigues <37986729+carlos-r-l-rodrigues@users.noreply.github.com>
This commit is contained in:
co-authored by
Carlos R. L. Rodrigues
parent
c2a39c78f5
commit
cc1a25abb2
@@ -51,6 +51,10 @@ export interface OptionsQuery<T, P extends string = never> {
|
|||||||
* Filters to apply on the retrieved items.
|
* Filters to apply on the retrieved items.
|
||||||
*/
|
*/
|
||||||
filters?: Dictionary<boolean | Dictionary> | string[] | boolean
|
filters?: Dictionary<boolean | Dictionary> | string[] | boolean
|
||||||
|
/**
|
||||||
|
* Load strategy (e.g for mikro orm it accept select-in or joined)
|
||||||
|
*/
|
||||||
|
strategy?: 'select-in' | 'joined' | string & {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -10,24 +10,22 @@ import {
|
|||||||
UpsertWithReplaceConfig,
|
UpsertWithReplaceConfig,
|
||||||
} from "@medusajs/types"
|
} from "@medusajs/types"
|
||||||
import {
|
import {
|
||||||
|
EntityClass,
|
||||||
EntityManager,
|
EntityManager,
|
||||||
|
EntityName,
|
||||||
|
EntityProperty,
|
||||||
EntitySchema,
|
EntitySchema,
|
||||||
|
FilterQuery as MikroFilterQuery,
|
||||||
|
FindOptions as MikroOptions,
|
||||||
LoadStrategy,
|
LoadStrategy,
|
||||||
ReferenceType,
|
ReferenceType,
|
||||||
RequiredEntityData,
|
RequiredEntityData,
|
||||||
} from "@mikro-orm/core"
|
} from "@mikro-orm/core"
|
||||||
import {
|
|
||||||
EntityClass,
|
|
||||||
EntityName,
|
|
||||||
EntityProperty,
|
|
||||||
FindOptions as MikroOptions,
|
|
||||||
FilterQuery as MikroFilterQuery,
|
|
||||||
} from "@mikro-orm/core"
|
|
||||||
import { SqlEntityManager } from "@mikro-orm/postgresql"
|
import { SqlEntityManager } from "@mikro-orm/postgresql"
|
||||||
import {
|
import {
|
||||||
MedusaError,
|
|
||||||
arrayDifference,
|
arrayDifference,
|
||||||
isString,
|
isString,
|
||||||
|
MedusaError,
|
||||||
promiseAll,
|
promiseAll,
|
||||||
} from "../../common"
|
} from "../../common"
|
||||||
import { buildQuery } from "../../modules-sdk/build-query"
|
import { buildQuery } from "../../modules-sdk/build-query"
|
||||||
@@ -112,6 +110,40 @@ export class MikroOrmBaseRepository<T extends object = object>
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When using the select-in strategy, the populated fields are not selected by default unlike when using the joined strategy.
|
||||||
|
* This method will add the populated fields to the fields array if they are not already specifically selected.
|
||||||
|
*
|
||||||
|
* TODO: Revisit if this is still needed in v6 as it seems to be a workaround for a bug in v5
|
||||||
|
*
|
||||||
|
* @param {FindOptions<any>} findOptions
|
||||||
|
*/
|
||||||
|
static compensateRelationFieldsSelectionFromLoadStrategy({
|
||||||
|
findOptions,
|
||||||
|
}: {
|
||||||
|
findOptions: DAL.FindOptions
|
||||||
|
}) {
|
||||||
|
const loadStrategy = findOptions?.options?.strategy
|
||||||
|
|
||||||
|
if (loadStrategy !== LoadStrategy.SELECT_IN) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
findOptions.options ??= {}
|
||||||
|
const populate = findOptions.options.populate ?? []
|
||||||
|
const fields = findOptions.options.fields ?? []
|
||||||
|
populate.forEach((populateRelation: string) => {
|
||||||
|
if (
|
||||||
|
fields.some((field: string) => field.startsWith(populateRelation + "."))
|
||||||
|
) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is no specific fields selected for the relation but the relation is populated, we select all fields
|
||||||
|
fields.push(populateRelation + ".*")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
create(data: unknown[], context?: Context): Promise<T[]> {
|
create(data: unknown[], context?: Context): Promise<T[]> {
|
||||||
throw new Error("Method not implemented.")
|
throw new Error("Method not implemented.")
|
||||||
}
|
}
|
||||||
@@ -317,7 +349,10 @@ export function mikroOrmBaseRepositoryFactory<T extends object = object>(
|
|||||||
await manager.nativeDelete<T>(entity as EntityName<T>, filters as any)
|
await manager.nativeDelete<T>(entity as EntityName<T>, filters as any)
|
||||||
}
|
}
|
||||||
|
|
||||||
async find(options?: DAL.FindOptions<T>, context?: Context): Promise<T[]> {
|
async find(
|
||||||
|
options: DAL.FindOptions<T> = { where: {} },
|
||||||
|
context?: Context
|
||||||
|
): Promise<T[]> {
|
||||||
const manager = this.getActiveManager<EntityManager>(context)
|
const manager = this.getActiveManager<EntityManager>(context)
|
||||||
|
|
||||||
const findOptions_ = { ...options }
|
const findOptions_ = { ...options }
|
||||||
@@ -335,6 +370,10 @@ export function mikroOrmBaseRepositoryFactory<T extends object = object>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MikroOrmBaseRepository.compensateRelationFieldsSelectionFromLoadStrategy({
|
||||||
|
findOptions: findOptions_,
|
||||||
|
})
|
||||||
|
|
||||||
return await manager.find(
|
return await manager.find(
|
||||||
entity as EntityName<T>,
|
entity as EntityName<T>,
|
||||||
findOptions_.where as MikroFilterQuery<T>,
|
findOptions_.where as MikroFilterQuery<T>,
|
||||||
@@ -355,6 +394,10 @@ export function mikroOrmBaseRepositoryFactory<T extends object = object>(
|
|||||||
strategy: LoadStrategy.SELECT_IN,
|
strategy: LoadStrategy.SELECT_IN,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
MikroOrmBaseRepository.compensateRelationFieldsSelectionFromLoadStrategy({
|
||||||
|
findOptions: findOptions_,
|
||||||
|
})
|
||||||
|
|
||||||
return await manager.findAndCount(
|
return await manager.findAndCount(
|
||||||
entity as EntityName<T>,
|
entity as EntityName<T>,
|
||||||
findOptions_.where as MikroFilterQuery<T>,
|
findOptions_.where as MikroFilterQuery<T>,
|
||||||
|
|||||||
Reference in New Issue
Block a user