diff --git a/.changeset/eight-monkeys-bathe.md b/.changeset/eight-monkeys-bathe.md new file mode 100644 index 0000000000..86251c9ec7 --- /dev/null +++ b/.changeset/eight-monkeys-bathe.md @@ -0,0 +1,5 @@ +--- +"@medusajs/medusa": patch +--- + +chore(medusa): migrate SalesChannel / ProductCategory repository diff --git a/packages/medusa/src/repositories/product-category.ts b/packages/medusa/src/repositories/product-category.ts index beb4af8648..f45402976e 100644 --- a/packages/medusa/src/repositories/product-category.ts +++ b/packages/medusa/src/repositories/product-category.ts @@ -44,14 +44,14 @@ export const ProductCategoryRepository = dataSource const options_ = { ...options } options_.where = options_.where as FindOptionsWhere - const legacySelect = buildLegacyFieldsListFrom(options_.select) - const legacyRelations = buildLegacyFieldsListFrom(options_.relations) + const columnsSelected = buildLegacyFieldsListFrom(options_.select) + const relationsSelected = buildLegacyFieldsListFrom(options_.relations) - const selectStatements = (relationName: string): string[] => { + const fetchSelectColumns = (relationName: string): string[] => { const modelColumns = this.metadata.ownColumns.map( (column) => column.propertyName ) - const selectColumns = legacySelect.length ? legacySelect : modelColumns + const selectColumns = columnsSelected.length ? columnsSelected : modelColumns return selectColumns.map((column) => { return `${relationName}.${column}` @@ -59,7 +59,7 @@ export const ProductCategoryRepository = dataSource } const queryBuilder = this.createQueryBuilder(entityName) - .select(selectStatements(entityName)) + .select(fetchSelectColumns(entityName)) .skip(options_.skip) .take(options_.take) .addOrderBy(`${entityName}.rank`, "ASC") @@ -69,18 +69,18 @@ export const ProductCategoryRepository = dataSource delete options_.where?.name delete options_.where?.handle - queryBuilder.where( - new Brackets((bracket) => { - bracket - .where({ name: ILike(`%${q}%`) }) - .orWhere({ handle: ILike(`%${q}%`) }) - }) - ) + options_.where = [{ + ...options_.where, + name: ILike(`%${q}%`) + }, { + ...options_.where, + handle: ILike(`%${q}%`) + }] } - queryBuilder.andWhere(options_.where) + queryBuilder.where(options_.where) - const includedTreeRelations: string[] = legacyRelations.filter((rel) => + const includedTreeRelations: string[] = relationsSelected.filter((rel) => ProductCategory.treeRelations.includes(rel) ) @@ -96,12 +96,12 @@ export const ProductCategoryRepository = dataSource treeWhere, treeScope ) - .addSelect(selectStatements(treeRelation)) + .addSelect(fetchSelectColumns(treeRelation)) .addOrderBy(`${treeRelation}.rank`, "ASC") .addOrderBy(`${treeRelation}.handle`, "ASC") }) - const nonTreeRelations: string[] = legacyRelations.filter( + const nonTreeRelations: string[] = relationsSelected.filter( (rel) => !ProductCategory.treeRelations.includes(rel) ) @@ -128,15 +128,15 @@ export const ProductCategoryRepository = dataSource productCategoryId: string, productIds: string[] ): Promise { + const valuesToInsert = productIds.map((id) => ({ + product_category_id: productCategoryId, + product_id: id, + })) + await this.createQueryBuilder() .insert() .into(ProductCategory.productCategoryProductJoinTable) - .values( - productIds.map((id) => ({ - product_category_id: productCategoryId, - product_id: id, - })) - ) + .values(valuesToInsert) .orIgnore() .execute() }, diff --git a/packages/medusa/src/repositories/product.ts b/packages/medusa/src/repositories/product.ts index 508ab5923b..78c6a90ea7 100644 --- a/packages/medusa/src/repositories/product.ts +++ b/packages/medusa/src/repositories/product.ts @@ -11,8 +11,8 @@ import { dataSource } from "../loaders/database" import { ProductFilterOptions } from "../types/product" import { buildLegacyFieldsListFrom, - isObject, fetchCategoryDescendantsIds, + isObject, } from "../utils" export const ProductRepository = dataSource.getRepository(Product).extend({ @@ -123,7 +123,6 @@ export const ProductRepository = dataSource.getRepository(Product).extend({ delete options_.where.include_category_children delete options_.where.categories - // TODO: move back to the service layer if (q) { options_.relations = options_.relations ?? {} options_.relations.variants = options_.relations.variants ?? true diff --git a/packages/medusa/src/repositories/publishable-api-key-sales-channel.ts b/packages/medusa/src/repositories/publishable-api-key-sales-channel.ts index bd86a60631..2a51854749 100644 --- a/packages/medusa/src/repositories/publishable-api-key-sales-channel.ts +++ b/packages/medusa/src/repositories/publishable-api-key-sales-channel.ts @@ -2,6 +2,9 @@ import { Brackets, In } from "typeorm" import { PublishableApiKeySalesChannel, SalesChannel } from "../models" import { dataSource } from "../loaders/database" +import SalesChannelRepository from "./sales-channel" + +const publishableApiKeySalesChannelAlias = "PublishableKeySalesChannel" export const PublishableApiKeySalesChannelRepository = dataSource .getRepository(PublishableApiKeySalesChannel) @@ -16,35 +19,38 @@ export const PublishableApiKeySalesChannelRepository = dataSource publishableApiKeyId: string, config?: { q?: string } ): Promise { - const query = this.createQueryBuilder("PublishableKeySalesChannel") - .select("PublishableKeySalesChannel.sales_channel_id") - .innerJoinAndMapOne( - "PublishableKeySalesChannel.sales_channel_id", - SalesChannel, - "SalesChannel", - "PublishableKeySalesChannel.sales_channel_id = SalesChannel.id" - ) + const salesChannelAlias = "sales_channel" + + const queryBuilder = this.createQueryBuilder( + publishableApiKeySalesChannelAlias + ) + .select(`${salesChannelAlias}.*`) + .from(SalesChannel, salesChannelAlias) .where( - "PublishableKeySalesChannel.publishable_key_id = :publishableApiKeyId", + `${publishableApiKeySalesChannelAlias}.publishable_key_id = :publishableApiKeyId`, { publishableApiKeyId, } ) + .andWhere( + `${publishableApiKeySalesChannelAlias}.sales_channel_id = ${salesChannelAlias}.id` + ) if (config?.q) { - query.andWhere( + queryBuilder.andWhere( new Brackets((qb) => { - qb.where(`SalesChannel.description ILIKE :q`, { + qb.where(`${salesChannelAlias}.description ILIKE :q`, { q: `%${config.q}%`, - }).orWhere(`SalesChannel.name ILIKE :q`, { q: `%${config.q}%` }) + }).orWhere(`${salesChannelAlias}.name ILIKE :q`, { + q: `%${config.q}%`, + }) }) ) } - const records = await query.getMany() - - return records.map( - (record) => record.sales_channel_id as unknown as SalesChannel + const records = await queryBuilder.getRawMany() + return records.map((salesChannel: SalesChannel) => + SalesChannelRepository.create(salesChannel) ) }, @@ -60,7 +66,7 @@ export const PublishableApiKeySalesChannelRepository = dataSource ): Promise { await this.createQueryBuilder() .insert() - .into("publishable_api_key_sales_channel") + .into(PublishableApiKeySalesChannel) .values( salesChannelIds.map((id) => ({ sales_channel_id: id, @@ -83,7 +89,7 @@ export const PublishableApiKeySalesChannelRepository = dataSource ): Promise { await this.createQueryBuilder() .delete() - .from("publishable_api_key_sales_channel") + .from(PublishableApiKeySalesChannel) .where({ sales_channel_id: In(salesChannelIds), publishable_key_id: publishableApiKeyId, diff --git a/packages/medusa/src/repositories/sales-channel.ts b/packages/medusa/src/repositories/sales-channel.ts index d7da56af0c..648afec64d 100644 --- a/packages/medusa/src/repositories/sales-channel.ts +++ b/packages/medusa/src/repositories/sales-channel.ts @@ -1,8 +1,10 @@ -import { Brackets, DeleteResult, FindOptionsWhere, In } from "typeorm" +import { Brackets, DeleteResult, FindOptionsWhere, In, ILike } from "typeorm" import { SalesChannel } from "../models" import { ExtendedFindConfig } from "../types/common" import { dataSource } from "../loaders/database" +const productSalesChannelTable = "product_sales_channel" + export const SalesChannelRepository = dataSource .getRepository(SalesChannel) .extend({ @@ -13,25 +15,29 @@ export const SalesChannelRepository = dataSource } ): Promise<[SalesChannel[], number]> { const options_ = { ...options } - options_.where = options_.where as FindOptionsWhere + options_.where = options_.where as FindOptionsWhere delete options_?.where?.name delete options_?.where?.description - let qb = this.createQueryBuilder("sales_channel") + options_.where = [ + { + ...options_.where, + name: ILike(`%${q}%`), + }, + { + ...options_.where, + description: ILike(`%${q}%`), + }, + ] + + let qb = this.createQueryBuilder() .select() .where(options_.where) - .andWhere( - new Brackets((qb) => { - qb.where(`sales_channel.description ILIKE :q`, { - q: `%${q}%`, - }).orWhere(`sales_channel.name ILIKE :q`, { q: `%${q}%` }) - }) - ) - .skip(options.skip) - .take(options.take) + .skip(options_.skip) + .take(options_.take) - if (options.withDeleted) { + if (options_.withDeleted) { qb = qb.withDeleted() } @@ -42,13 +48,15 @@ export const SalesChannelRepository = dataSource salesChannelId: string, productIds: string[] ): Promise { + const whereOptions = { + sales_channel_id: salesChannelId, + product_id: In(productIds), + } + return await this.createQueryBuilder() .delete() - .from("product_sales_channel") - .where({ - sales_channel_id: salesChannelId, - product_id: In(productIds), - }) + .from(productSalesChannelTable) + .where(whereOptions) .execute() }, @@ -56,17 +64,18 @@ export const SalesChannelRepository = dataSource salesChannelId: string, productIds: string[] ): Promise { + const valuesToInsert = productIds.map((id) => ({ + sales_channel_id: salesChannelId, + product_id: id, + })) + await this.createQueryBuilder() .insert() - .into("product_sales_channel") - .values( - productIds.map((id) => ({ - sales_channel_id: salesChannelId, - product_id: id, - })) - ) + .into(productSalesChannelTable) + .values(valuesToInsert) .orIgnore() .execute() }, }) + export default SalesChannelRepository