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:
Adrien de Peretti
2024-10-16 17:43:18 +02:00
committed by GitHub
parent c2a39c78f5
commit cc1a25abb2
2 changed files with 56 additions and 9 deletions

View File

@@ -51,6 +51,10 @@ export interface OptionsQuery<T, P extends string = never> {
* Filters to apply on the retrieved items.
*/
filters?: Dictionary<boolean | Dictionary> | string[] | boolean
/**
* Load strategy (e.g for mikro orm it accept select-in or joined)
*/
strategy?: 'select-in' | 'joined' | string & {}
}
/**

View File

@@ -10,24 +10,22 @@ import {
UpsertWithReplaceConfig,
} from "@medusajs/types"
import {
EntityClass,
EntityManager,
EntityName,
EntityProperty,
EntitySchema,
FilterQuery as MikroFilterQuery,
FindOptions as MikroOptions,
LoadStrategy,
ReferenceType,
RequiredEntityData,
} 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 {
MedusaError,
arrayDifference,
isString,
MedusaError,
promiseAll,
} from "../../common"
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[]> {
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)
}
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 findOptions_ = { ...options }
@@ -335,6 +370,10 @@ export function mikroOrmBaseRepositoryFactory<T extends object = object>(
}
}
MikroOrmBaseRepository.compensateRelationFieldsSelectionFromLoadStrategy({
findOptions: findOptions_,
})
return await manager.find(
entity as EntityName<T>,
findOptions_.where as MikroFilterQuery<T>,
@@ -355,6 +394,10 @@ export function mikroOrmBaseRepositoryFactory<T extends object = object>(
strategy: LoadStrategy.SELECT_IN,
})
MikroOrmBaseRepository.compensateRelationFieldsSelectionFromLoadStrategy({
findOptions: findOptions_,
})
return await manager.findAndCount(
entity as EntityName<T>,
findOptions_.where as MikroFilterQuery<T>,