chore: abstract the modules repository (#6035)

**What**
Reduce the work effort to create repositories when building new modules by abstracting the most common cases into the base class default implementation returned by a factory

- [x] Migrate all modules

Co-authored-by: Riqwan Thamir <5105988+riqwan@users.noreply.github.com>
This commit is contained in:
Adrien de Peretti
2024-01-10 13:12:02 +00:00
committed by GitHub
co-authored by Riqwan Thamir
parent ef5024980d
commit b6ac768698
38 changed files with 411 additions and 2832 deletions
@@ -26,22 +26,13 @@ export type ReorderConditions = {
export const tempReorderRank = 99999
// eslint-disable-next-line max-len
export class ProductCategoryRepository extends DALUtils.MikroOrmBaseTreeRepository {
protected readonly manager_: SqlEntityManager
constructor({ manager }: { manager: SqlEntityManager }) {
// @ts-ignore
// eslint-disable-next-line prefer-rest-params
super(...arguments)
this.manager_ = manager
}
export class ProductCategoryRepository extends DALUtils.MikroOrmBaseTreeRepository<ProductCategory> {
async find(
findOptions: DAL.FindOptions<ProductCategory> = { where: {} },
transformOptions: ProductCategoryTransformOptions = {},
context: Context = {}
): Promise<ProductCategory[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const manager = super.getActiveManager<SqlEntityManager>(context)
const findOptions_ = { ...findOptions }
const { includeDescendantsTree } = transformOptions
@@ -81,7 +72,7 @@ export class ProductCategoryRepository extends DALUtils.MikroOrmBaseTreeReposito
findOptions: DAL.FindOptions<ProductCategory> = { where: {} },
context: Context = {}
): Promise<ProductCategory[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const manager = super.getActiveManager<SqlEntityManager>(context)
for (let productCategory of productCategories) {
const whereOptions = {
@@ -132,7 +123,7 @@ export class ProductCategoryRepository extends DALUtils.MikroOrmBaseTreeReposito
transformOptions: ProductCategoryTransformOptions = {},
context: Context = {}
): Promise<[ProductCategory[], number]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const manager = super.getActiveManager<SqlEntityManager>(context)
const findOptions_ = { ...findOptions }
const { includeDescendantsTree } = transformOptions
@@ -171,7 +162,7 @@ export class ProductCategoryRepository extends DALUtils.MikroOrmBaseTreeReposito
}
async delete(id: string, context: Context = {}): Promise<void> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const manager = super.getActiveManager<SqlEntityManager>(context)
const productCategory = await manager.findOneOrFail(
ProductCategory,
{ id },
@@ -197,11 +188,7 @@ export class ProductCategoryRepository extends DALUtils.MikroOrmBaseTreeReposito
)
await this.performReordering(manager, conditions)
await (manager as SqlEntityManager).nativeDelete(
ProductCategory,
{ id: id },
{}
)
await manager.nativeDelete(ProductCategory, { id: id }, {})
}
async create(
@@ -209,7 +196,7 @@ export class ProductCategoryRepository extends DALUtils.MikroOrmBaseTreeReposito
context: Context = {}
): Promise<ProductCategory> {
const categoryData = { ...data }
const manager = this.getActiveManager<SqlEntityManager>(context)
const manager = super.getActiveManager<SqlEntityManager>(context)
const siblings = await manager.find(ProductCategory, {
parent_category_id: categoryData?.parent_category_id || null,
})
@@ -231,7 +218,7 @@ export class ProductCategoryRepository extends DALUtils.MikroOrmBaseTreeReposito
context: Context = {}
): Promise<ProductCategory> {
const categoryData = { ...data }
const manager = this.getActiveManager<SqlEntityManager>(context)
const manager = super.getActiveManager<SqlEntityManager>(context)
const productCategory = await manager.findOneOrFail(ProductCategory, { id })
const conditions = this.fetchReorderConditions(
@@ -403,7 +390,7 @@ export class ProductCategoryRepository extends DALUtils.MikroOrmBaseTreeReposito
throw new Error("sibling rank is not defined")
}
const rank = shouldIncrementRank ? ++sibling.rank : --sibling.rank
const rank = shouldIncrementRank ? ++sibling.rank! : --sibling.rank!
manager.assign(sibling, { rank })
manager.persist(sibling)
@@ -1,11 +1,5 @@
import { Context, DAL, ProductTypes } from "@medusajs/types"
import { DALUtils, MedusaError } from "@medusajs/utils"
import {
FilterQuery as MikroFilterQuery,
FindOptions as MikroOptions,
LoadStrategy,
} from "@mikro-orm/core"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { Context, ProductTypes } from "@medusajs/types"
import { DALUtils } from "@medusajs/utils"
import { ProductCollection } from "@models"
type UpdateProductCollection = ProductTypes.UpdateProductCollectionDTO & {
@@ -17,71 +11,13 @@ type CreateProductCollection = ProductTypes.CreateProductCollectionDTO & {
}
// eslint-disable-next-line max-len
export class ProductCollectionRepository extends DALUtils.MikroOrmBaseRepository {
protected readonly manager_: SqlEntityManager
constructor({ manager }: { manager: SqlEntityManager }) {
// @ts-ignore
// eslint-disable-next-line prefer-rest-params
super(...arguments)
this.manager_ = manager
}
async find(
findOptions: DAL.FindOptions<ProductCollection> = { where: {} },
context: Context = {}
): Promise<ProductCollection[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const findOptions_ = { ...findOptions }
findOptions_.options ??= {}
Object.assign(findOptions_.options, {
strategy: LoadStrategy.SELECT_IN,
})
return await manager.find(
ProductCollection,
findOptions_.where as MikroFilterQuery<ProductCollection>,
findOptions_.options as MikroOptions<ProductCollection>
)
}
async findAndCount(
findOptions: DAL.FindOptions<ProductCollection> = { where: {} },
context: Context = {}
): Promise<[ProductCollection[], number]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const findOptions_ = { ...findOptions }
findOptions_.options ??= {}
Object.assign(findOptions_.options, {
strategy: LoadStrategy.SELECT_IN,
})
return await manager.findAndCount(
ProductCollection,
findOptions_.where as MikroFilterQuery<ProductCollection>,
findOptions_.options as MikroOptions<ProductCollection>
)
}
async delete(collectionIds: string[], context: Context = {}): Promise<void> {
const manager = this.getActiveManager<SqlEntityManager>(context)
await manager.nativeDelete(
ProductCollection,
{ id: { $in: collectionIds } },
{}
)
}
export class ProductCollectionRepository extends DALUtils.mikroOrmBaseRepositoryFactory(
ProductCollection
) {
async create(
data: CreateProductCollection[],
context: Context = {}
): Promise<ProductCollection[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const productCollections = data.map((collectionData) => {
if (collectionData.product_ids) {
collectionData.products = collectionData.product_ids
@@ -89,59 +25,26 @@ export class ProductCollectionRepository extends DALUtils.MikroOrmBaseRepository
delete collectionData.product_ids
}
return manager.create(ProductCollection, collectionData)
return collectionData
})
manager.persist(productCollections)
return productCollections
return await super.create(productCollections, context)
}
async update(
data: UpdateProductCollection[],
context: Context = {}
): Promise<ProductCollection[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const collectionIds = data.map((collectionData) => collectionData.id)
const existingCollections = await this.find(
{
where: {
id: {
$in: collectionIds,
},
},
},
context
)
const existingCollectionsMap = new Map(
existingCollections.map<[string, ProductCollection]>((collection) => [
collection.id,
collection,
])
)
const productCollections = data.map((collectionData) => {
const existingCollection = existingCollectionsMap.get(collectionData.id)
if (!existingCollection) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
`ProductCollection with id "${collectionData.id}" not found`
)
}
if (collectionData.product_ids) {
collectionData.products = collectionData.product_ids
delete collectionData.product_ids
}
return manager.assign(existingCollection, collectionData)
return collectionData
})
manager.persist(productCollections)
return productCollections
return await super.update(productCollections, context)
}
}
@@ -1,64 +1,12 @@
import {
FilterQuery as MikroFilterQuery,
FindOptions as MikroOptions,
LoadStrategy,
} from "@mikro-orm/core"
import { Context, DAL } from "@medusajs/types"
import { Image, Product } from "@models"
import { Context } from "@medusajs/types"
import { Image } from "@models"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { DALUtils } from "@medusajs/utils"
// eslint-disable-next-line max-len
export class ProductImageRepository extends DALUtils.MikroOrmAbstractBaseRepository<Image> {
protected readonly manager_: SqlEntityManager
constructor({ manager }: { manager: SqlEntityManager }) {
// @ts-ignore
// eslint-disable-next-line prefer-rest-params
super(...arguments)
this.manager_ = manager
}
async find(
findOptions: DAL.FindOptions<Image> = { where: {} },
context: Context = {}
): Promise<Image[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const findOptions_ = { ...findOptions }
findOptions_.options ??= {}
Object.assign(findOptions_.options, {
strategy: LoadStrategy.SELECT_IN,
})
return await manager.find(
Image,
findOptions_.where as MikroFilterQuery<Image>,
findOptions_.options as MikroOptions<Image>
)
}
async findAndCount(
findOptions: DAL.FindOptions<Image> = { where: {} },
context: Context = {}
): Promise<[Image[], number]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const findOptions_ = { ...findOptions }
findOptions_.options ??= {}
Object.assign(findOptions_.options, {
strategy: LoadStrategy.SELECT_IN,
})
return await manager.findAndCount(
Image,
findOptions_.where as MikroFilterQuery<Image>,
findOptions_.options as MikroOptions<Image>
)
}
export class ProductImageRepository extends DALUtils.mikroOrmBaseRepositoryFactory(
Image
) {
async upsert(urls: string[], context: Context = {}): Promise<Image[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
@@ -73,7 +21,7 @@ export class ProductImageRepository extends DALUtils.MikroOrmAbstractBaseReposit
context
)
const existingImagesMap = new Map(
const existingImagesMap = new Map<string, Image>(
existingImages.map<[string, Image]>((img) => [img.url, img])
)
@@ -97,13 +45,4 @@ export class ProductImageRepository extends DALUtils.MikroOrmAbstractBaseReposit
return upsertedImgs
}
async delete(ids: string[], context: Context = {}): Promise<void> {
const manager = this.getActiveManager<SqlEntityManager>(context)
await manager.nativeDelete(Product, { id: { $in: ids } }, {})
}
async create(data: unknown[], context: Context = {}): Promise<Image[]> {
throw new Error("Method not implemented.")
}
}
@@ -1,41 +1,16 @@
import { Context, DAL } from "@medusajs/types"
import { Context } from "@medusajs/types"
import {
CreateProductOptionValueDTO,
UpdateProductOptionValueDTO,
} from "../types/services/product-option-value"
import { DALUtils } from "@medusajs/utils"
import { FilterQuery as MikroFilterQuery } from "@mikro-orm/core/typings"
import { FindOptions as MikroOptions } from "@mikro-orm/core/drivers/IDatabaseDriver"
import { ProductOptionValue } from "@models"
import { SqlEntityManager } from "@mikro-orm/postgresql"
export class ProductOptionValueRepository extends DALUtils.MikroOrmBaseRepository {
protected readonly manager_: SqlEntityManager
constructor({ manager }: { manager: SqlEntityManager }) {
// @ts-ignore
// eslint-disable-next-line prefer-rest-params
super(...arguments)
this.manager_ = manager
}
async find(
findOptions: DAL.FindOptions<ProductOptionValue> = { where: {} },
context: Context = {}
): Promise<ProductOptionValue[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const findOptions_ = { ...findOptions }
findOptions_.options ??= {}
return await manager.find(
ProductOptionValue,
findOptions_.where as MikroFilterQuery<ProductOptionValue>,
findOptions_.options as MikroOptions<ProductOptionValue>
)
}
export class ProductOptionValueRepository extends DALUtils.mikroOrmBaseRepositoryFactory(
ProductOptionValue
) {
async upsert(
optionValues: (UpdateProductOptionValueDTO | CreateProductOptionValueDTO)[],
context: Context = {}
@@ -106,9 +81,4 @@ export class ProductOptionValueRepository extends DALUtils.MikroOrmBaseRepositor
return upsertedOptionValues
}
async delete(ids: string[], context: Context = {}): Promise<void> {
const manager = this.getActiveManager<SqlEntityManager>(context)
await manager.nativeDelete(ProductOptionValue, { id: { $in: ids } }, {})
}
}
@@ -1,74 +1,15 @@
import { Context, DAL, ProductTypes } from "@medusajs/types"
import { DALUtils, MedusaError } from "@medusajs/utils"
import {
FilterQuery as MikroFilterQuery,
FindOptions as MikroOptions,
LoadStrategy,
} from "@mikro-orm/core"
import { Context, ProductTypes } from "@medusajs/types"
import { DALUtils } from "@medusajs/utils"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { Product, ProductOption } from "@models"
// eslint-disable-next-line max-len
export class ProductOptionRepository extends DALUtils.MikroOrmAbstractBaseRepository<ProductOption> {
protected readonly manager_: SqlEntityManager
constructor({ manager }: { manager: SqlEntityManager }) {
// @ts-ignore
// eslint-disable-next-line prefer-rest-params
super(...arguments)
this.manager_ = manager
export class ProductOptionRepository extends DALUtils.mikroOrmBaseRepositoryFactory<
ProductOption,
{
update: ProductTypes.UpdateProductOptionDTO
}
async find(
findOptions: DAL.FindOptions<ProductOption> = { where: {} },
context: Context = {}
): Promise<ProductOption[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const findOptions_ = { ...findOptions }
findOptions_.options ??= {}
Object.assign(findOptions_.options, {
strategy: LoadStrategy.SELECT_IN,
})
return await manager.find(
ProductOption,
findOptions_.where as MikroFilterQuery<ProductOption>,
findOptions_.options as MikroOptions<ProductOption>
)
}
async findAndCount(
findOptions: DAL.FindOptions<ProductOption> = { where: {} },
context: Context = {}
): Promise<[ProductOption[], number]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const findOptions_ = { ...findOptions }
findOptions_.options ??= {}
Object.assign(findOptions_.options, {
strategy: LoadStrategy.SELECT_IN,
})
return await manager.findAndCount(
ProductOption,
findOptions_.where as MikroFilterQuery<ProductOption>,
findOptions_.options as MikroOptions<ProductOption>
)
}
async delete(ids: string[], context: Context = {}): Promise<void> {
const manager = this.getActiveManager<SqlEntityManager>(context)
await (manager as SqlEntityManager).nativeDelete(
ProductOption,
{ id: { $in: ids } },
{}
)
}
>(ProductOption) {
async create(
data: ProductTypes.CreateProductOptionDTO[],
context: Context = {}
@@ -82,7 +23,7 @@ export class ProductOptionRepository extends DALUtils.MikroOrmAbstractBaseReposi
id: { $in: productIds },
})
const existingProductsMap = new Map(
const existingProductsMap = new Map<string, Product>(
existingProducts.map<[string, Product]>((product) => [
product.id,
product,
@@ -100,54 +41,10 @@ export class ProductOptionRepository extends DALUtils.MikroOrmAbstractBaseReposi
optionData.product_id = product?.id
}
return manager.create(ProductOption, optionData)
return optionData
})
manager.persist(productOptions)
return productOptions
}
async update(
data: ProductTypes.UpdateProductOptionDTO[],
context: Context = {}
): Promise<ProductOption[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const optionIds = data.map((optionData) => optionData.id)
const existingOptions = await this.find(
{
where: {
id: {
$in: optionIds,
},
},
},
context
)
const existingOptionsMap = new Map(
existingOptions.map<[string, ProductOption]>((option) => [
option.id,
option,
])
)
const productOptions = data.map((optionData) => {
const existingOption = existingOptionsMap.get(optionData.id)
if (!existingOption) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
`ProductOption with id "${optionData.id}" not found`
)
}
return manager.assign(existingOption, optionData)
})
manager.persist(productOptions)
return productOptions
return await super.create(productOptions, context)
}
async upsert(
@@ -1,123 +1,20 @@
import {
FilterQuery as MikroFilterQuery,
FindOptions as MikroOptions,
LoadStrategy,
} from "@mikro-orm/core"
import { ProductTag } from "@models"
import {
Context,
CreateProductTagDTO,
DAL,
UpdateProductTagDTO,
UpsertProductTagDTO,
} from "@medusajs/types"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { DALUtils, MedusaError } from "@medusajs/utils"
import { DALUtils } from "@medusajs/utils"
export class ProductTagRepository extends DALUtils.MikroOrmBaseRepository {
protected readonly manager_: SqlEntityManager
constructor({ manager }: { manager: SqlEntityManager }) {
// @ts-ignore
// eslint-disable-next-line prefer-rest-params
super(...arguments)
this.manager_ = manager
export class ProductTagRepository extends DALUtils.mikroOrmBaseRepositoryFactory<
ProductTag,
{
create: CreateProductTagDTO
update: UpdateProductTagDTO
}
async find(
findOptions: DAL.FindOptions<ProductTag> = { where: {} },
context: Context = {}
): Promise<ProductTag[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const findOptions_ = { ...findOptions }
findOptions_.options ??= {}
Object.assign(findOptions_.options, {
strategy: LoadStrategy.SELECT_IN,
})
return await manager.find(
ProductTag,
findOptions_.where as MikroFilterQuery<ProductTag>,
findOptions_.options as MikroOptions<ProductTag>
)
}
async findAndCount(
findOptions: DAL.FindOptions<ProductTag> = { where: {} },
context: Context = {}
): Promise<[ProductTag[], number]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const findOptions_ = { ...findOptions }
findOptions_.options ??= {}
Object.assign(findOptions_.options, {
strategy: LoadStrategy.SELECT_IN,
})
return await manager.findAndCount(
ProductTag,
findOptions_.where as MikroFilterQuery<ProductTag>,
findOptions_.options as MikroOptions<ProductTag>
)
}
async create(
data: CreateProductTagDTO[],
context: Context = {}
): Promise<ProductTag[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const productTags = data.map((tagData) => {
return manager.create(ProductTag, tagData)
})
manager.persist(productTags)
return productTags
}
async update(
data: UpdateProductTagDTO[],
context: Context = {}
): Promise<ProductTag[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const tagIds = data.map((tagData) => tagData.id)
const existingTags = await this.find(
{
where: {
id: {
$in: tagIds,
},
},
},
context
)
const existingTagsMap = new Map(
existingTags.map<[string, ProductTag]>((tag) => [tag.id, tag])
)
const productTags = data.map((tagData) => {
const existingTag = existingTagsMap.get(tagData.id)
if (!existingTag) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
`ProductTag with id "${tagData.id}" not found`
)
}
return manager.assign(existingTag, tagData)
})
manager.persist(productTags)
return productTags
}
>(ProductTag) {
async upsert(
tags: UpsertProductTagDTO[],
context: Context = {}
@@ -166,10 +63,4 @@ export class ProductTagRepository extends DALUtils.MikroOrmBaseRepository {
return upsertedTags
}
async delete(ids: string[], context: Context = {}): Promise<void> {
const manager = this.getActiveManager<SqlEntityManager>(context)
await manager.nativeDelete(ProductTag, { id: { $in: ids } }, {})
}
}
@@ -1,68 +1,19 @@
import {
FilterQuery as MikroFilterQuery,
FindOptions as MikroOptions,
LoadStrategy,
} from "@mikro-orm/core"
import { ProductType } from "@models"
import {
Context,
CreateProductTypeDTO,
DAL,
UpdateProductTypeDTO,
} from "@medusajs/types"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { DALUtils, MedusaError } from "@medusajs/utils"
import { DALUtils } from "@medusajs/utils"
export class ProductTypeRepository extends DALUtils.MikroOrmBaseRepository {
protected readonly manager_: SqlEntityManager
constructor({ manager }: { manager: SqlEntityManager }) {
// @ts-ignore
// eslint-disable-next-line prefer-rest-params
super(...arguments)
this.manager_ = manager
export class ProductTypeRepository extends DALUtils.mikroOrmBaseRepositoryFactory<
ProductType,
{
create: CreateProductTypeDTO
update: UpdateProductTypeDTO
}
async find(
findOptions: DAL.FindOptions<ProductType> = { where: {} },
context: Context = {}
): Promise<ProductType[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const findOptions_ = { ...findOptions }
findOptions_.options ??= {}
Object.assign(findOptions_.options, {
strategy: LoadStrategy.SELECT_IN,
})
return await manager.find(
ProductType,
findOptions_.where as MikroFilterQuery<ProductType>,
findOptions_.options as MikroOptions<ProductType>
)
}
async findAndCount(
findOptions: DAL.FindOptions<ProductType> = { where: {} },
context: Context = {}
): Promise<[ProductType[], number]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const findOptions_ = { ...findOptions }
findOptions_.options ??= {}
Object.assign(findOptions_.options, {
strategy: LoadStrategy.SELECT_IN,
})
return await manager.findAndCount(
ProductType,
findOptions_.where as MikroFilterQuery<ProductType>,
findOptions_.options as MikroOptions<ProductType>
)
}
>(ProductType) {
async upsert(
types: CreateProductTypeDTO[],
context: Context = {}
@@ -112,63 +63,4 @@ export class ProductTypeRepository extends DALUtils.MikroOrmBaseRepository {
return upsertedTypes
}
async delete(ids: string[], context: Context = {}): Promise<void> {
const manager = this.getActiveManager<SqlEntityManager>(context)
await manager.nativeDelete(ProductType, { id: { $in: ids } }, {})
}
async create(
data: CreateProductTypeDTO[],
context: Context = {}
): Promise<ProductType[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const productTypes = data.map((typeData) => {
return manager.create(ProductType, typeData)
})
manager.persist(productTypes)
return productTypes
}
async update(
data: UpdateProductTypeDTO[],
context: Context = {}
): Promise<ProductType[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const typeIds = data.map((typeData) => typeData.id)
const existingTypes = await this.find(
{
where: {
id: {
$in: typeIds,
},
},
},
context
)
const existingTypesMap = new Map(
existingTypes.map<[string, ProductType]>((type) => [type.id, type])
)
const productTypes = data.map((typeData) => {
const existingType = existingTypesMap.get(typeData.id)
if (!existingType) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
`ProductType with id "${typeData.id}" not found`
)
}
return manager.assign(existingType, typeData)
})
manager.persist(productTypes)
return productTypes
}
}
@@ -1,131 +1,17 @@
import {
FilterQuery as MikroFilterQuery,
FindOptions as MikroOptions,
LoadStrategy,
RequiredEntityData,
} from "@mikro-orm/core"
import { ProductVariant } from "@models"
import { Context, DAL, WithRequiredProperty } from "@medusajs/types"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import {
DALUtils,
InjectTransactionManager,
MedusaContext,
MedusaError,
} from "@medusajs/utils"
import { DALUtils } from "@medusajs/utils"
import { RequiredEntityData } from "@mikro-orm/core"
import { WithRequiredProperty } from "@medusajs/types"
import { ProductVariantServiceTypes } from "../types/services"
// eslint-disable-next-line max-len
export class ProductVariantRepository extends DALUtils.MikroOrmAbstractBaseRepository<ProductVariant> {
protected readonly manager_: SqlEntityManager
constructor({ manager }: { manager: SqlEntityManager }) {
// @ts-ignore
// eslint-disable-next-line prefer-rest-params
super(...arguments)
this.manager_ = manager
}
async find(
findOptions: DAL.FindOptions<ProductVariant> = { where: {} },
context: Context = {}
): Promise<ProductVariant[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const findOptions_ = { ...findOptions }
findOptions_.options ??= {}
Object.assign(findOptions_.options, {
strategy: LoadStrategy.SELECT_IN,
})
return await manager.find(
ProductVariant,
findOptions_.where as MikroFilterQuery<ProductVariant>,
findOptions_.options as MikroOptions<ProductVariant>
)
}
async findAndCount(
findOptions: DAL.FindOptions<ProductVariant> = { where: {} },
context: Context = {}
): Promise<[ProductVariant[], number]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const findOptions_ = { ...findOptions }
findOptions_.options ??= {}
Object.assign(findOptions_.options, {
strategy: LoadStrategy.SELECT_IN,
})
return await manager.findAndCount(
ProductVariant,
findOptions_.where as MikroFilterQuery<ProductVariant>,
findOptions_.options as MikroOptions<ProductVariant>
)
}
@InjectTransactionManager()
async delete(
ids: string[],
@MedusaContext()
{ transactionManager: manager }: Context = {}
): Promise<void> {
await (manager as SqlEntityManager).nativeDelete(
ProductVariant,
{ id: { $in: ids } },
{}
)
}
async create(
data: RequiredEntityData<ProductVariant>[],
context: Context = {}
): Promise<ProductVariant[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const variants = data.map((variant) => {
return (manager as SqlEntityManager).create(ProductVariant, variant)
})
manager.persist(variants)
return variants
}
async update(
data: WithRequiredProperty<
export class ProductVariantRepository extends DALUtils.mikroOrmBaseRepositoryFactory<
ProductVariant,
{
create: RequiredEntityData<ProductVariant>
update: WithRequiredProperty<
ProductVariantServiceTypes.UpdateProductVariantDTO,
"id"
>[],
context: Context = {}
): Promise<ProductVariant[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const productVariantsToUpdate = await manager.find(ProductVariant, {
id: data.map((updateData) => updateData.id),
})
const productVariantsToUpdateMap = new Map<string, ProductVariant>(
productVariantsToUpdate.map((variant) => [variant.id, variant])
)
const variants = data.map((variantData) => {
const productVariant = productVariantsToUpdateMap.get(variantData.id)
if (!productVariant) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
`ProductVariant with id "${variantData.id}" not found`
)
}
return manager.assign(productVariant, variantData)
})
manager.persist(variants)
return variants
>
}
}
>(ProductVariant) {}
+8 -57
View File
@@ -6,12 +6,6 @@ import {
ProductType,
} from "@models"
import {
FilterQuery as MikroFilterQuery,
FindOptions as MikroOptions,
LoadStrategy,
} from "@mikro-orm/core"
import {
Context,
DAL,
@@ -24,29 +18,19 @@ import { DALUtils, isDefined, MedusaError, promiseAll } from "@medusajs/utils"
import { ProductServiceTypes } from "../types/services"
// eslint-disable-next-line max-len
export class ProductRepository extends DALUtils.MikroOrmAbstractBaseRepository<Product> {
protected readonly manager_: SqlEntityManager
constructor({ manager }: { manager: SqlEntityManager }) {
// @ts-ignore
// eslint-disable-next-line prefer-rest-params
super(...arguments)
this.manager_ = manager
export class ProductRepository extends DALUtils.mikroOrmBaseRepositoryFactory<
Product,
{
create: WithRequiredProperty<ProductTypes.CreateProductOnlyDTO, "status">
}
>(Product) {
async find(
findOptions: DAL.FindOptions<Product & { q?: string }> = { where: {} },
context: Context = {}
): Promise<Product[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const findOptions_ = { ...findOptions }
findOptions_.options ??= {}
Object.assign(findOptions_.options, {
strategy: LoadStrategy.SELECT_IN,
})
await this.mutateNotInCategoriesConstraints(findOptions_)
this.applyFreeTextSearchFilters<Product>(
@@ -54,26 +38,16 @@ export class ProductRepository extends DALUtils.MikroOrmAbstractBaseRepository<P
this.getFreeTextSearchConstraints
)
return await manager.find(
Product,
findOptions_.where as MikroFilterQuery<Product>,
findOptions_.options as MikroOptions<Product>
)
return await super.find(findOptions_, context)
}
async findAndCount(
findOptions: DAL.FindOptions<Product & { q?: string }> = { where: {} },
context: Context = {}
): Promise<[Product[], number]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const findOptions_ = { ...findOptions }
findOptions_.options ??= {}
Object.assign(findOptions_.options, {
strategy: LoadStrategy.SELECT_IN,
})
await this.mutateNotInCategoriesConstraints(findOptions_)
this.applyFreeTextSearchFilters<Product>(
@@ -81,12 +55,9 @@ export class ProductRepository extends DALUtils.MikroOrmAbstractBaseRepository<P
this.getFreeTextSearchConstraints
)
return await manager.findAndCount(
Product,
findOptions_.where as MikroFilterQuery<Product>,
findOptions_.options as MikroOptions<Product>
)
return await super.findAndCount(findOptions_, context)
}
/**
* In order to be able to have a strict not in categories, and prevent a product
* to be return in the case it also belongs to other categories, we need to
@@ -127,26 +98,6 @@ export class ProductRepository extends DALUtils.MikroOrmAbstractBaseRepository<P
}
}
async delete(ids: string[], context: Context = {}): Promise<void> {
const manager = this.getActiveManager<SqlEntityManager>(context)
await manager.nativeDelete(Product, { id: { $in: ids } }, {})
}
async create(
data: WithRequiredProperty<ProductTypes.CreateProductOnlyDTO, "status">[],
context: Context = {}
): Promise<Product[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const products = data.map((product) => {
return (manager as SqlEntityManager).create(Product, product)
})
manager.persist(products)
return products
}
async update(
data: WithRequiredProperty<ProductServiceTypes.UpdateProductDTO, "id">[],
context: Context = {}