feat(medusa): Migrate services to use TransactionBaseService (#2276)

This commit is contained in:
Adrien de Peretti
2022-09-29 15:58:17 +02:00
committed by GitHub
parent 8797a1441b
commit 678a06752a
45 changed files with 317 additions and 586 deletions
+6
View File
@@ -0,0 +1,6 @@
---
"medusa-react": patch
"@medusajs/medusa": patch
---
Finalise service migration and fix super constructor arguments
@@ -1,18 +1,18 @@
import { adminProductKeys } from "./queries"
import {
AdminProductsDeleteRes,
AdminProductsRes,
AdminPostProductsProductReq,
AdminPostProductsReq,
AdminPostProductsProductVariantsReq,
AdminProductsDeleteVariantRes,
AdminPostProductsProductOptionsReq,
AdminPostProductsProductOptionsOption,
AdminPostProductsProductOptionsReq,
AdminPostProductsProductReq,
AdminPostProductsProductVariantsReq,
AdminPostProductsReq,
AdminProductsDeleteOptionRes,
AdminProductsDeleteRes,
AdminProductsDeleteVariantRes,
AdminProductsRes,
} from "@medusajs/medusa"
import { Response } from "@medusajs/medusa-js"
import { useMutation, UseMutationOptions, useQueryClient } from "react-query"
import { useMedusa } from "../../../contexts/medusa"
import { useMedusa } from "../../../contexts"
import { buildOptions } from "../../utils/buildOptions"
export const useAdminCreateProduct = (
@@ -89,5 +89,5 @@ export class AdminPostCustomerGroupsReq {
@IsObject()
@IsOptional()
metadata?: object
metadata?: Record<string, unknown>
}
@@ -119,5 +119,5 @@ export class AdminPostCustomerGroupsGroupReq {
@IsObject()
@IsOptional()
metadata?: object
metadata?: Record<string, unknown>
}
@@ -107,5 +107,5 @@ export class AdminPostDiscountsDiscountDynamicCodesReq {
@IsObject()
@IsOptional()
metadata?: object
metadata?: Record<string, unknown>
}
@@ -440,7 +440,7 @@ export class AdminPostOrdersOrderClaimsReq {
@IsObject()
@IsOptional()
metadata?: object
metadata?: Record<string, unknown>
}
class ReturnShipping {
@@ -241,7 +241,7 @@ class Item {
@IsObject()
@IsOptional()
metadata?: object
metadata?: Record<string, unknown>
}
class Image {
@@ -300,7 +300,7 @@ export class AdminPostProductsProductVariantsReq {
@IsObject()
@IsOptional()
metadata?: object
metadata?: Record<string, unknown>
@IsArray()
@ValidateNested({ each: true })
@@ -307,7 +307,7 @@ export class AdminPostProductsProductVariantsVariantReq {
@IsObject()
@IsOptional()
metadata?: object
metadata?: Record<string, unknown>
@IsArray()
@IsOptional()
@@ -219,7 +219,7 @@ export class AdminPostShippingOptionsReq {
@IsObject()
@IsOptional()
metadata?: object
metadata?: Record<string, unknown>
@FeatureFlagDecorators(TaxInclusivePricingFeatureFlag.key, [
IsOptional(),
@@ -178,7 +178,7 @@ export class AdminPostShippingOptionsOptionReq {
@IsObject()
@IsOptional()
metadata?: object
metadata?: Record<string, unknown>
@FeatureFlagDecorators(TaxInclusivePricingFeatureFlag.key, [
IsOptional(),
+2 -3
View File
@@ -1,6 +1,6 @@
import Scrypt from "scrypt-kdf"
import { AuthenticateResult } from "../types/auth"
import { User, Customer } from "../models"
import { Customer, User } from "../models"
import { TransactionBaseService } from "../interfaces"
import UserService from "./user"
import CustomerService from "./customer"
@@ -14,7 +14,6 @@ type InjectedDependencies = {
/**
* Can authenticate a user based on email password combination
* @extends BaseService
*/
class AuthService extends TransactionBaseService {
protected manager_: EntityManager
@@ -23,7 +22,7 @@ class AuthService extends TransactionBaseService {
protected readonly customerService_: CustomerService
constructor({ manager, userService, customerService }: InjectedDependencies) {
super({ manager, userService, customerService })
super(arguments[0])
this.manager_ = manager
this.userService_ = userService
+1 -6
View File
@@ -96,12 +96,7 @@ class BatchJobService extends TransactionBaseService {
eventBusService,
strategyResolverService,
}: InjectedDependencies) {
super({
manager,
batchJobRepository,
eventBusService,
strategyResolverService,
})
super(arguments[0])
this.manager_ = manager
this.batchJobRepository_ = batchJobRepository
+2 -2
View File
@@ -1,6 +1,6 @@
import { MedusaError } from "medusa-core-utils"
import { EntityManager } from "typeorm"
import { TransactionBaseService as BaseService } from "../interfaces"
import { TransactionBaseService } from "../interfaces"
import { ClaimImage, ClaimItem, ClaimTag } from "../models"
import { ClaimImageRepository } from "../repositories/claim-image"
import { ClaimItemRepository } from "../repositories/claim-item"
@@ -11,7 +11,7 @@ import { buildQuery, setMetadata } from "../utils"
import EventBusService from "./event-bus"
import LineItemService from "./line-item"
class ClaimItemService extends BaseService {
class ClaimItemService extends TransactionBaseService {
static Events = {
CREATED: "claim_item.created",
UPDATED: "claim_item.updated",
+1 -1
View File
@@ -35,7 +35,7 @@ export default class CurrencyService extends TransactionBaseService {
eventBusService,
featureFlagRouter,
}: InjectedDependencies) {
super({ manager })
super(arguments[0])
this.manager_ = manager
this.currencyRepository_ = currencyRepository
this.eventBusService_ = eventBusService
+47 -66
View File
@@ -1,5 +1,4 @@
import { MedusaError } from "medusa-core-utils"
import { BaseService } from "medusa-interfaces"
import { DeepPartial, EntityManager, ILike, SelectQueryBuilder } from "typeorm"
import { CustomerService } from "."
import { CustomerGroup } from ".."
@@ -9,7 +8,14 @@ import {
CustomerGroupUpdate,
FilterableCustomerGroupProps,
} from "../types/customer-groups"
import { isDefined, formatException, PostgresError } from "../utils"
import {
buildQuery,
formatException,
isDefined,
PostgresError,
setMetadata,
} from "../utils"
import { TransactionBaseService } from "../interfaces"
type CustomerGroupConstructorProps = {
manager: EntityManager
@@ -17,55 +23,31 @@ type CustomerGroupConstructorProps = {
customerService: CustomerService
}
/**
* Provides layer to manipulate discounts.
* @implements {BaseService}
*/
class CustomerGroupService extends BaseService {
private manager_: EntityManager
class CustomerGroupService extends TransactionBaseService {
protected manager_: EntityManager
protected transactionManager_: EntityManager | undefined
private customerGroupRepository_: typeof CustomerGroupRepository
private customerService_: CustomerService
protected readonly customerGroupRepository_: typeof CustomerGroupRepository
protected readonly customerService_: CustomerService
constructor({
manager,
customerGroupRepository,
customerService,
}: CustomerGroupConstructorProps) {
super()
super(arguments[0])
this.manager_ = manager
this.customerGroupRepository_ = customerGroupRepository
/** @private @const {CustomerGroupService} */
this.customerService_ = customerService
}
withTransaction(transactionManager: EntityManager): CustomerGroupService {
if (!transactionManager) {
return this
}
const cloned = new CustomerGroupService({
manager: transactionManager,
customerGroupRepository: this.customerGroupRepository_,
customerService: this.customerService_,
})
cloned.transactionManager_ = transactionManager
return cloned
}
async retrieve(id: string, config = {}): Promise<CustomerGroup> {
const cgRepo = this.manager_.getCustomRepository(
this.customerGroupRepository_
)
const validatedId = this.validateId_(id)
const query = this.buildQuery_({ id: validatedId }, config)
const query = buildQuery({ id }, config)
const customerGroup = await cgRepo.findOne(query)
if (!customerGroup) {
@@ -80,21 +62,18 @@ class CustomerGroupService extends BaseService {
/**
* Creates a customer group with the provided data.
* @param {DeepPartial<CustomerGroup>} group - the customer group to create
* @return {Promise} the result of the create operation
* @param group - the customer group to create
* @return the result of the create operation
*/
async create(group: DeepPartial<CustomerGroup>): Promise<CustomerGroup> {
return this.atomicPhase_(async (manager) => {
return await this.atomicPhase_(async (manager) => {
try {
const cgRepo: CustomerGroupRepository = manager.getCustomRepository(
this.customerGroupRepository_
)
const created = cgRepo.create(group)
const result = await cgRepo.save(created)
return result
return await cgRepo.save(created)
} catch (err) {
if (err.code === PostgresError.DUPLICATE_ERROR) {
throw new MedusaError(MedusaError.Types.DUPLICATE_ERROR, err.detail)
@@ -106,9 +85,9 @@ class CustomerGroupService extends BaseService {
/**
* Add a batch of customers to a customer group at once
* @param {string} id id of the customer group to add customers to
* @param {string[]} customerIds customer id's to add to the group
* @return {Promise<CustomerGroup>} the customer group after insertion
* @param id id of the customer group to add customers to
* @param customerIds customer id's to add to the group
* @return the customer group after insertion
*/
async addCustomers(
id: string,
@@ -121,14 +100,14 @@ class CustomerGroupService extends BaseService {
ids = customerIds
}
return this.atomicPhase_(
return await this.atomicPhase_(
async (manager) => {
const cgRepo: CustomerGroupRepository = manager.getCustomRepository(
this.customerGroupRepository_
)
return await cgRepo.addCustomers(id, ids)
},
async (error) => {
async (error: any) => {
if (error.code === PostgresError.FOREIGN_KEY_ERROR) {
await this.retrieve(id)
@@ -155,15 +134,15 @@ class CustomerGroupService extends BaseService {
/**
* Update a customer group.
*
* @param {string} customerGroupId - id of the customer group
* @param {CustomerGroupUpdate} update - customer group partial data
* @param customerGroupId - id of the customer group
* @param update - customer group partial data
* @returns resulting customer group
*/
async update(
customerGroupId: string,
update: CustomerGroupUpdate
): Promise<CustomerGroup[]> {
return this.atomicPhase_(async (manager) => {
): Promise<CustomerGroup> {
return await this.atomicPhase_(async (manager) => {
const { metadata, ...properties } = update
const cgRepo: CustomerGroupRepository = manager.getCustomRepository(
@@ -179,8 +158,9 @@ class CustomerGroupService extends BaseService {
}
if (isDefined(metadata)) {
customerGroup.metadata = this.setMetadata_(customerGroup, metadata)
customerGroup.metadata = setMetadata(customerGroup, metadata)
}
return await cgRepo.save(customerGroup)
})
}
@@ -188,11 +168,11 @@ class CustomerGroupService extends BaseService {
/**
* Remove customer group
*
* @param {string} groupId id of the customer group to delete
* @return {Promise} a promise
* @param groupId id of the customer group to delete
* @return a promise
*/
async delete(groupId: string): Promise<void> {
return this.atomicPhase_(async (manager) => {
return await this.atomicPhase_(async (manager) => {
const cgRepo: CustomerGroupRepository = manager.getCustomRepository(
this.customerGroupRepository_
)
@@ -210,9 +190,9 @@ class CustomerGroupService extends BaseService {
/**
* List customer groups.
*
* @param {Object} selector - the query object for find
* @param {Object} config - the config to be used for find
* @return {Promise} the result of the find operation
* @param selector - the query object for find
* @param config - the config to be used for find
* @return the result of the find operation
*/
async list(
selector: FilterableCustomerGroupProps = {},
@@ -222,16 +202,16 @@ class CustomerGroupService extends BaseService {
this.customerGroupRepository_
)
const query = this.buildQuery_(selector, config)
const query = buildQuery(selector, config)
return await cgRepo.find(query)
}
/**
* Retrieve a list of customer groups and total count of records that match the query.
*
* @param {Object} selector - the query object for find
* @param {Object} config - the config to be used for find
* @return {Promise} the result of the find operation
* @param selector - the query object for find
* @param config - the config to be used for find
* @return the result of the find operation
*/
async listAndCount(
selector: FilterableCustomerGroupProps = {},
@@ -247,26 +227,27 @@ class CustomerGroupService extends BaseService {
delete selector.q
}
const query = this.buildQuery_(selector, config)
const query = buildQuery(selector, config)
if (q) {
const where = query.where
delete where.name
query.where = (qb: SelectQueryBuilder<CustomerGroup>): void => {
query.where = ((qb: SelectQueryBuilder<CustomerGroup>): void => {
qb.where(where).andWhere([{ name: ILike(`%${q}%`) }])
}
}) as any
}
return await cgRepo.findAndCount(query)
}
/**
* Remove list of customers from a customergroup
*
* @param {string} id id of the customer group from which the customers are removed
* @param {string[] | string} customerIds id's of the customer to remove from group
* @return {Promise<CustomerGroup>} the customergroup with the provided id
* @param id id of the customer group from which the customers are removed
* @param customerIds id's of the customer to remove from group
* @return the customergroup with the provided id
*/
async removeCustomer(
id: string,
@@ -39,7 +39,7 @@ class DiscountConditionService extends TransactionBaseService {
discountConditionRepository,
eventBusService,
}: InjectedDependencies) {
super({ manager, discountConditionRepository, eventBusService })
super(arguments[0])
this.manager_ = manager
this.discountConditionRepository_ = discountConditionRepository
+2 -12
View File
@@ -8,7 +8,7 @@ import LineItemService from "./line-item"
import { OrderRepository } from "../repositories/order"
import ProductVariantService from "./product-variant"
import ShippingOptionService from "./shipping-option"
import { DraftOrder, DraftOrderStatus, Cart, CartType } from "../models"
import { Cart, CartType, DraftOrder, DraftOrderStatus } from "../models"
import { AdminPostDraftOrdersReq } from "../api/routes/admin/draft-orders"
import { TransactionBaseService } from "../interfaces"
import { ExtendedFindConfig, FindConfig } from "../types/common"
@@ -59,17 +59,7 @@ class DraftOrderService extends TransactionBaseService {
productVariantService,
shippingOptionService,
}: InjectedDependencies) {
super({
manager,
draftOrderRepository,
paymentRepository,
orderRepository,
eventBusService,
cartService,
lineItemService,
productVariantService,
shippingOptionService,
})
super(arguments[0])
this.manager_ = manager
this.draftOrderRepository_ = draftOrderRepository
+3 -2
View File
@@ -1,4 +1,3 @@
import { BaseService } from "medusa-interfaces"
import { MedusaError } from "medusa-core-utils"
import { TransactionBaseService } from "../interfaces"
import { EntityManager } from "typeorm"
@@ -9,6 +8,7 @@ type InventoryServiceProps = {
manager: EntityManager
productVariantService: ProductVariantService
}
class InventoryService extends TransactionBaseService {
protected readonly productVariantService_: ProductVariantService
@@ -16,7 +16,7 @@ class InventoryService extends TransactionBaseService {
protected transactionManager_: EntityManager | undefined
constructor({ manager, productVariantService }: InventoryServiceProps) {
super({ manager, productVariantService })
super(arguments[0])
this.manager_ = manager
this.productVariantService_ = productVariantService
@@ -52,6 +52,7 @@ class InventoryService extends TransactionBaseService {
}
})
}
/**
* Checks if the inventory of a variant can cover a given quantity. Will
* return true if the variant doesn't have managed inventory or if the variant
+24 -43
View File
@@ -1,6 +1,5 @@
import jwt, { JwtPayload } from "jsonwebtoken"
import { MedusaError } from "medusa-core-utils"
import { BaseService } from "medusa-interfaces"
import { EntityManager } from "typeorm"
import { EventBusService, UserService } from "."
import { User } from ".."
@@ -9,6 +8,8 @@ import { InviteRepository } from "../repositories/invite"
import { UserRepository } from "../repositories/user"
import { ListInvite } from "../types/invites"
import { ConfigModule } from "../types/global"
import { TransactionBaseService } from "../interfaces"
import { buildQuery } from "../utils"
// 7 days
const DEFAULT_VALID_DURATION = 1000 * 60 * 60 * 24 * 7
@@ -16,21 +17,23 @@ const DEFAULT_VALID_DURATION = 1000 * 60 * 60 * 24 * 7
type InviteServiceProps = {
manager: EntityManager
userService: UserService
userRepository: UserRepository
inviteRepository: InviteRepository
userRepository: typeof UserRepository
inviteRepository: typeof InviteRepository
eventBusService: EventBusService
}
class InviteService extends BaseService {
class InviteService extends TransactionBaseService {
static Events = {
CREATED: "invite.created",
}
private manager_: EntityManager
private userService_: UserService
private userRepo_: UserRepository
private inviteRepository_: InviteRepository
private eventBus_: EventBusService
protected manager_: EntityManager
protected transactionManager_: EntityManager | undefined
protected readonly userService_: UserService
protected readonly userRepo_: typeof UserRepository
protected readonly inviteRepository_: typeof InviteRepository
protected readonly eventBus_: EventBusService
protected readonly configModule_: ConfigModule
@@ -44,7 +47,8 @@ class InviteService extends BaseService {
}: InviteServiceProps,
configModule: ConfigModule
) {
super()
// @ts-ignore
super(...arguments)
this.configModule_ = configModule
@@ -64,27 +68,6 @@ class InviteService extends BaseService {
this.eventBus_ = eventBusService
}
withTransaction(manager): InviteService {
if (!manager) {
return this
}
const cloned = new InviteService(
{
manager,
inviteRepository: this.inviteRepository_,
userService: this.userService_,
userRepository: this.userRepo_,
eventBusService: this.eventBus_,
},
this.configModule_
)
cloned.transactionManager_ = manager
return cloned
}
generateToken(data): string {
const { jwt_secret } = this.configModule_.projectConfig
if (jwt_secret) {
@@ -99,17 +82,17 @@ class InviteService extends BaseService {
async list(selector, config = {}): Promise<ListInvite[]> {
const inviteRepo = this.manager_.getCustomRepository(InviteRepository)
const query = this.buildQuery_(selector, config)
const query = buildQuery(selector, config)
return await inviteRepo.find(query)
}
/**
* Updates an account_user.
* @param {string} user - user emails
* @param {string} role - role to assign to the user
* @param {number} validDuration - role to assign to the user
* @return {Promise} the result of create
* @param user - user emails
* @param role - role to assign to the user
* @param validDuration - role to assign to the user
* @return the result of create
*/
async create(
user: string,
@@ -178,12 +161,12 @@ class InviteService extends BaseService {
/**
* Deletes an invite from a given user id.
* @param {string} inviteId - the id of the invite to delete. Must be
* @param inviteId - the id of the invite to delete. Must be
* castable as an ObjectId
* @return {Promise} the result of the delete operation.
* @return the result of the delete operation.
*/
async delete(inviteId): Promise<void> {
return this.atomicPhase_(async (manager) => {
return await this.atomicPhase_(async (manager) => {
const inviteRepo: InviteRepository =
manager.getCustomRepository(InviteRepository)
@@ -191,12 +174,10 @@ class InviteService extends BaseService {
const invite = await inviteRepo.findOne({ where: { id: inviteId } })
if (!invite) {
return Promise.resolve()
return
}
await inviteRepo.delete({ id: invite.id })
return Promise.resolve()
})
}
@@ -213,7 +194,7 @@ class InviteService extends BaseService {
const { invite_id, user_email } = decoded
return this.atomicPhase_(async (m) => {
return await this.atomicPhase_(async (m) => {
const userRepo = m.getCustomRepository(this.userRepo_)
const inviteRepo: InviteRepository = m.getCustomRepository(
this.inviteRepository_
@@ -33,7 +33,6 @@ type GeneratedAdjustment = {
/**
* Provides layer to manipulate line item adjustments.
* @extends BaseService
*/
class LineItemAdjustmentService extends TransactionBaseService {
protected readonly manager_: EntityManager
+19 -45
View File
@@ -1,5 +1,4 @@
import { MedusaError } from "medusa-core-utils"
import { BaseService } from "medusa-interfaces"
import { EntityManager, In } from "typeorm"
import { DeepPartial } from "typeorm/common/DeepPartial"
@@ -18,7 +17,8 @@ import {
ProductVariantService,
RegionService,
} from "./index"
import { setMetadata } from "../utils"
import { buildQuery, setMetadata } from "../utils"
import { TransactionBaseService } from "../interfaces"
type InjectedDependencies = {
manager: EntityManager
@@ -33,12 +33,10 @@ type InjectedDependencies = {
featureFlagRouter: FlagRouter
}
/**
* Provides layer to manipulate line items.
* @extends BaseService
*/
class LineItemService extends BaseService {
protected readonly manager_: EntityManager
class LineItemService extends TransactionBaseService {
protected manager_: EntityManager
protected transactionManager_: EntityManager | undefined
protected readonly lineItemRepository_: typeof LineItemRepository
protected readonly itemTaxLineRepo_: typeof LineItemTaxLineRepository
protected readonly cartRepository_: typeof CartRepository
@@ -61,7 +59,7 @@ class LineItemService extends BaseService {
lineItemAdjustmentService,
featureFlagRouter,
}: InjectedDependencies) {
super()
super(arguments[0])
this.manager_ = manager
this.lineItemRepository_ = lineItemRepository
@@ -75,29 +73,6 @@ class LineItemService extends BaseService {
this.featureFlagRouter_ = featureFlagRouter
}
withTransaction(transactionManager: EntityManager): LineItemService {
if (!transactionManager) {
return this
}
const cloned = new LineItemService({
manager: transactionManager,
lineItemRepository: this.lineItemRepository_,
lineItemTaxLineRepository: this.itemTaxLineRepo_,
productVariantService: this.productVariantService_,
productService: this.productService_,
pricingService: this.pricingService_,
regionService: this.regionService_,
cartRepository: this.cartRepository_,
lineItemAdjustmentService: this.lineItemAdjustmentService_,
featureFlagRouter: this.featureFlagRouter_,
})
cloned.transactionManager_ = transactionManager
return cloned
}
async list(
selector: Selector<LineItem>,
config: FindConfig<LineItem> = {
@@ -108,15 +83,15 @@ class LineItemService extends BaseService {
): Promise<LineItem[]> {
const manager = this.manager_
const lineItemRepo = manager.getCustomRepository(this.lineItemRepository_)
const query = this.buildQuery_(selector, config)
const query = buildQuery(selector, config)
return await lineItemRepo.find(query)
}
/**
* Retrieves a line item by its id.
* @param {string} id - the id of the line item to retrieve
* @param {object} config - the config to be used at query building
* @return {Promise<LineItem | never>} the line item
* @param id - the id of the line item to retrieve
* @param config - the config to be used at query building
* @return the line item
*/
async retrieve(id: string, config = {}): Promise<LineItem | never> {
const manager = this.manager_
@@ -124,8 +99,7 @@ class LineItemService extends BaseService {
this.lineItemRepository_
)
const validatedId = this.validateId_(id)
const query = this.buildQuery_({ id: validatedId }, config)
const query = buildQuery({ id }, config)
const lineItem = await lineItemRepository.findOne(query)
@@ -142,9 +116,9 @@ class LineItemService extends BaseService {
/**
* Creates return line items for a given cart based on the return items in a
* return.
* @param {string} returnId - the id to generate return items from.
* @param {string} cartId - the cart to assign the return line items to.
* @return {Promise<LineItem[]>} the created line items
* @param returnId - the id to generate return items from.
* @param cartId - the cart to assign the return line items to.
* @return the created line items
*/
async createReturnLines(
returnId: string,
@@ -293,8 +267,8 @@ class LineItemService extends BaseService {
/**
* Create a line item
* @param {Partial<LineItem>} data - the line item object to create
* @return {Promise<LineItem>} the created line item
* @param data - the line item object to create
* @return the created line item
*/
async create(data: Partial<LineItem>): Promise<LineItem> {
return await this.atomicPhase_(
@@ -361,8 +335,8 @@ class LineItemService extends BaseService {
/**
* Deletes a line item.
* @param {string} id - the id of the line item to delete
* @return {Promise<LineItem | undefined>} the result of the delete operation
* @param id - the id of the line item to delete
* @return the result of the delete operation
*/
async delete(id: string): Promise<LineItem | undefined> {
return await this.atomicPhase_(
+1 -1
View File
@@ -31,7 +31,7 @@ class NoteService extends TransactionBaseService {
noteRepository,
eventBusService,
}: InjectedDependencies) {
super({ manager, noteRepository, eventBusService })
super(arguments[0])
this.manager_ = manager
this.noteRepository_ = noteRepository
@@ -41,7 +41,6 @@ type PriceListConstructorProps = {
/**
* Provides layer to manipulate product tags.
* @extends BaseService
*/
class PriceListService extends TransactionBaseService {
protected manager_: EntityManager
-1
View File
@@ -31,7 +31,6 @@ type InjectedDependencies = {
/**
* Allows retrieval of prices.
* @extends BaseService
*/
class PricingService extends TransactionBaseService {
protected manager_: EntityManager
@@ -38,12 +38,7 @@ class ProductCollectionService extends TransactionBaseService {
productRepository,
eventBusService,
}: InjectedDependencies) {
super({
manager,
productCollectionRepository,
productRepository,
eventBusService,
})
super(arguments[0])
this.manager_ = manager
this.productCollectionRepository_ = productCollectionRepository
+23 -39
View File
@@ -1,50 +1,34 @@
import { MedusaError } from "medusa-core-utils"
import { BaseService } from "medusa-interfaces"
import { EntityManager, ILike, SelectQueryBuilder } from "typeorm"
import { ProductTag } from "../models/product-tag"
import { ProductTag } from "../models"
import { ProductTagRepository } from "../repositories/product-tag"
import { FindConfig } from "../types/common"
import { FilterableProductTagProps } from "../types/product"
import { TransactionBaseService } from "../interfaces"
import { buildQuery } from "../utils"
type ProductTagConstructorProps = {
manager: EntityManager
productTagRepository: typeof ProductTagRepository
}
/**
* Provides layer to manipulate product tags.
* @extends BaseService
*/
class ProductTagService extends BaseService {
private manager_: EntityManager
private tagRepo_: typeof ProductTagRepository
class ProductTagService extends TransactionBaseService {
protected manager_: EntityManager
protected transactionManager_: EntityManager | undefined
protected readonly tagRepo_: typeof ProductTagRepository
constructor({ manager, productTagRepository }: ProductTagConstructorProps) {
super()
super(arguments[0])
this.manager_ = manager
this.tagRepo_ = productTagRepository
}
withTransaction(transactionManager: EntityManager): ProductTagService {
if (!transactionManager) {
return this
}
const cloned = new ProductTagService({
manager: transactionManager,
productTagRepository: this.tagRepo_,
})
cloned.transactionManager_ = transactionManager
return cloned
}
/**
* Retrieves a product tag by id.
* @param {string} tagId - the id of the product tag to retrieve
* @param {Object} config - the config to retrieve the tag by
* @return {Promise<ProductTag>} the collection.
* @param tagId - the id of the product tag to retrieve
* @param config - the config to retrieve the tag by
* @return the collection.
*/
async retrieve(
tagId: string,
@@ -52,7 +36,7 @@ class ProductTagService extends BaseService {
): Promise<ProductTag> {
const tagRepo = this.manager_.getCustomRepository(this.tagRepo_)
const query = this.buildQuery_({ id: tagId }, config)
const query = buildQuery({ id: tagId }, config)
const tag = await tagRepo.findOne(query)
if (!tag) {
@@ -67,8 +51,8 @@ class ProductTagService extends BaseService {
/**
* Creates a product tag
* @param {object} tag - the product tag to create
* @return {Promise<ProductTag>} created product tag
* @param tag - the product tag to create
* @return created product tag
*/
async create(tag: Partial<ProductTag>): Promise<ProductTag> {
return await this.atomicPhase_(async (manager: EntityManager) => {
@@ -81,9 +65,9 @@ class ProductTagService extends BaseService {
/**
* Lists product tags
* @param {Object} selector - the query object for find
* @param {Object} config - the config to be used for find
* @return {Promise} the result of the find operation
* @param selector - the query object for find
* @param config - the config to be used for find
* @return the result of the find operation
*/
async list(
selector: FilterableProductTagProps = {},
@@ -91,15 +75,15 @@ class ProductTagService extends BaseService {
): Promise<ProductTag[]> {
const tagRepo = this.manager_.getCustomRepository(this.tagRepo_)
const query = this.buildQuery_(selector, config)
const query = buildQuery(selector, config)
return await tagRepo.find(query)
}
/**
* Lists product tags and adds count.
* @param {Object} selector - the query object for find
* @param {Object} config - the config to be used for find
* @return {Promise} the result of the find operation
* @param selector - the query object for find
* @param config - the config to be used for find
* @return the result of the find operation
*/
async listAndCount(
selector: FilterableProductTagProps = {},
@@ -113,7 +97,7 @@ class ProductTagService extends BaseService {
delete selector.q
}
const query = this.buildQuery_(selector, config)
const query = buildQuery(selector, config)
if (q) {
const where = query.where
@@ -1,47 +1,28 @@
import { BaseService } from "medusa-interfaces"
import { EntityManager } from "typeorm"
import { ProductTaxRate } from "../models/product-tax-rate"
import { ProductTaxRate } from "../models"
import { ProductTaxRateRepository } from "../repositories/product-tax-rate"
import { FindConfig } from "../types/common"
import { FilterableProductTaxRateProps } from "../types/product-tax-rate"
import { TransactionBaseService } from "../interfaces"
import { buildQuery } from "../utils"
/**
* Provides layer to manipulate product variants.
* @extends BaseService
*/
class ProductTaxRateService extends BaseService {
private manager_: EntityManager
private productTaxRateRepository_: typeof ProductTaxRateRepository
class ProductTaxRateService extends TransactionBaseService {
protected manager_: EntityManager
protected transactionManager_: EntityManager | undefined
protected readonly productTaxRateRepository_: typeof ProductTaxRateRepository
constructor({ manager, productTaxRateRepository }) {
super()
super(arguments[0])
/** @private @const {EntityManager} */
this.manager_ = manager
/** @private @const {ProductVariantModel} */
this.productTaxRateRepository_ = productTaxRateRepository
}
withTransaction(transactionManager: EntityManager): ProductTaxRateService {
if (!transactionManager) {
return this
}
const cloned = new ProductTaxRateService({
manager: transactionManager,
productTaxRateRepository: this.productTaxRateRepository_,
})
cloned.transactionManager_ = transactionManager
return cloned
}
/**
* @param {FilterableProductVariantProps} selector - the query object for find
* @param {FindConfig<ProductVariant>} config - query config object for variant retrieval
* @return {Promise} the result of the find operation
* @param selector - the query object for find
* @param config - query config object for variant retrieval
* @return the result of the find operation
*/
async list(
selector: FilterableProductTaxRateProps,
@@ -51,7 +32,7 @@ class ProductTaxRateService extends BaseService {
this.productTaxRateRepository_
)
const query = this.buildQuery_(selector, config)
const query = buildQuery(selector, config)
return await pTaxRateRepo.find(query)
}
+19 -35
View File
@@ -1,48 +1,32 @@
import { MedusaError } from "medusa-core-utils"
import { BaseService } from "medusa-interfaces"
import { EntityManager, ILike, SelectQueryBuilder } from "typeorm"
import { ProductType } from "../models/product-type"
import { ProductTypeRepository } from "../repositories/product-type"
import { FindConfig } from "../types/common"
import { FilterableProductTypeProps } from "../types/product"
import { TransactionBaseService } from "../interfaces"
import { buildQuery } from "../utils"
class ProductTypeService extends TransactionBaseService {
protected manager_: EntityManager
protected transactionManager_: EntityManager | undefined
protected readonly typeRepository_: typeof ProductTypeRepository
/**
* Provides layer to manipulate products.
* @extends BaseService
*/
class ProductTypeService extends BaseService {
private manager_: EntityManager
private typeRepository_: typeof ProductTypeRepository
constructor({ manager, productTypeRepository }) {
super()
super(arguments[0])
this.manager_ = manager
this.typeRepository_ = productTypeRepository
}
withTransaction(transactionManager: EntityManager): ProductTypeService {
if (!transactionManager) {
return this
}
const cloned = new ProductTypeService({
manager: transactionManager,
productTypeRepository: this.typeRepository_,
})
cloned.transactionManager_ = transactionManager
cloned.manager_ = transactionManager
return cloned
}
/**
* Gets a product by id.
* Throws in case of DB Error and if product was not found.
* @param id - id of the product to get.
* @param config - object that defines what should be included in the
* query response
* @return {Promise<Product>} the result of the find one operation.
* @return the result of the find one operation.
*/
async retrieve(
id: string,
@@ -50,7 +34,7 @@ class ProductTypeService extends BaseService {
): Promise<ProductType> {
const typeRepo = this.manager_.getCustomRepository(this.typeRepository_)
const query = this.buildQuery_({ id }, config)
const query = buildQuery({ id }, config)
const type = await typeRepo.findOne(query)
if (!type) {
@@ -65,9 +49,9 @@ class ProductTypeService extends BaseService {
/**
* Lists product types
* @param {Object} selector - the query object for find
* @param {Object} config - the config to be used for find
* @return {Promise} the result of the find operation
* @param selector - the query object for find
* @param config - the config to be used for find
* @return the result of the find operation
*/
async list(
selector: FilterableProductTypeProps = {},
@@ -75,15 +59,15 @@ class ProductTypeService extends BaseService {
): Promise<ProductType[]> {
const typeRepo = this.manager_.getCustomRepository(this.typeRepository_)
const query = this.buildQuery_(selector, config)
const query = buildQuery(selector, config)
return await typeRepo.find(query)
}
/**
* Lists product tags and adds count.
* @param {Object} selector - the query object for find
* @param {Object} config - the config to be used for find
* @return {Promise} the result of the find operation
* @param selector - the query object for find
* @param config - the config to be used for find
* @return the result of the find operation
*/
async listAndCount(
selector: FilterableProductTypeProps = {},
@@ -97,7 +81,7 @@ class ProductTypeService extends BaseService {
delete selector.q
}
const query = this.buildQuery_(selector, config)
const query = buildQuery(selector, config)
if (q) {
const where = query.where
+93 -164
View File
@@ -1,14 +1,16 @@
import { MedusaError } from "medusa-core-utils"
import { BaseService } from "medusa-interfaces"
import { Brackets, EntityManager, ILike, SelectQueryBuilder } from "typeorm"
import {
IPriceSelectionStrategy,
PriceSelectionContext,
} from "../interfaces/price-selection-strategy"
import { MoneyAmount } from "../models/money-amount"
import { Product } from "../models/product"
import { ProductOptionValue } from "../models/product-option-value"
import { ProductVariant } from "../models/product-variant"
TransactionBaseService,
} from "../interfaces"
import {
MoneyAmount,
Product,
ProductOptionValue,
ProductVariant,
} from "../models"
import { CartRepository } from "../repositories/cart"
import { MoneyAmountRepository } from "../repositories/money-amount"
import { ProductRepository } from "../repositories/product"
@@ -27,28 +29,26 @@ import {
ProductVariantPrice,
UpdateProductVariantInput,
} from "../types/product-variant"
import { isDefined } from "../utils"
import { buildQuery, isDefined, setMetadata } from "../utils"
/**
* Provides layer to manipulate product variants.
* @extends BaseService
*/
class ProductVariantService extends BaseService {
class ProductVariantService extends TransactionBaseService {
static Events = {
UPDATED: "product-variant.updated",
CREATED: "product-variant.created",
DELETED: "product-variant.deleted",
}
private manager_: EntityManager
private productVariantRepository_: typeof ProductVariantRepository
private productRepository_: typeof ProductRepository
private eventBus_: EventBusService
private regionService_: RegionService
private priceSelectionStrategy_: IPriceSelectionStrategy
private moneyAmountRepository_: typeof MoneyAmountRepository
private productOptionValueRepository_: typeof ProductOptionValueRepository
private cartRepository_: typeof CartRepository
protected manager_: EntityManager
protected transactionManager_: EntityManager | undefined
protected readonly productVariantRepository_: typeof ProductVariantRepository
protected readonly productRepository_: typeof ProductRepository
protected readonly eventBus_: EventBusService
protected readonly regionService_: RegionService
protected readonly priceSelectionStrategy_: IPriceSelectionStrategy
protected readonly moneyAmountRepository_: typeof MoneyAmountRepository
protected readonly productOptionValueRepository_: typeof ProductOptionValueRepository
protected readonly cartRepository_: typeof CartRepository
constructor({
manager,
@@ -61,59 +61,24 @@ class ProductVariantService extends BaseService {
cartRepository,
priceSelectionStrategy,
}) {
super()
super(arguments[0])
/** @private @const {EntityManager} */
this.manager_ = manager
/** @private @const {ProductVariantModel} */
this.productVariantRepository_ = productVariantRepository
/** @private @const {ProductModel} */
this.productRepository_ = productRepository
/** @private @const {EventBus} */
this.eventBus_ = eventBusService
/** @private @const {RegionService} */
this.regionService_ = regionService
this.moneyAmountRepository_ = moneyAmountRepository
this.productOptionValueRepository_ = productOptionValueRepository
this.cartRepository_ = cartRepository
this.priceSelectionStrategy_ = priceSelectionStrategy
}
withTransaction(transactionManager: EntityManager): ProductVariantService {
if (!transactionManager) {
return this
}
const cloned = new ProductVariantService({
manager: transactionManager,
productVariantRepository: this.productVariantRepository_,
productRepository: this.productRepository_,
eventBusService: this.eventBus_,
regionService: this.regionService_,
moneyAmountRepository: this.moneyAmountRepository_,
productOptionValueRepository: this.productOptionValueRepository_,
cartRepository: this.cartRepository_,
priceSelectionStrategy: this.priceSelectionStrategy_,
})
cloned.transactionManager_ = transactionManager
return cloned
}
/**
* Gets a product variant by id.
* @param {string} variantId - the id of the product to get.
* @param {FindConfig<ProductVariant>} config - query config object for variant retrieval.
* @return {Promise<Product>} the product document.
* @param variantId - the id of the product to get.
* @param config - query config object for variant retrieval.
* @return the product document.
*/
async retrieve(
variantId: string,
@@ -124,9 +89,7 @@ class ProductVariantService extends BaseService {
const variantRepo = this.manager_.getCustomRepository(
this.productVariantRepository_
)
const validatedId = this.validateId_(variantId)
const query = this.buildQuery_({ id: validatedId }, config)
const query = buildQuery({ id: variantId }, config)
const variant = await variantRepo.findOne(query)
if (!variant) {
@@ -141,9 +104,9 @@ class ProductVariantService extends BaseService {
/**
* Gets a product variant by id.
* @param {string} sku - The unique stock keeping unit used to identify the product variant.
* @param {FindConfig<ProductVariant>} config - query config object for variant retrieval.
* @return {Promise<Product>} the product document.
* @param sku - The unique stock keeping unit used to identify the product variant.
* @param config - query config object for variant retrieval.
* @return the product document.
*/
async retrieveBySKU(
sku: string,
@@ -161,7 +124,7 @@ class ProductVariantService extends BaseService {
config.relations.splice(priceIndex, 1)
}
const query = this.buildQuery_({ sku }, config)
const query = buildQuery({ sku }, config)
const variant = await variantRepo.findOne(query)
if (!variant) {
@@ -177,15 +140,15 @@ class ProductVariantService extends BaseService {
/**
* Creates an unpublished product variant. Will validate against parent product
* to ensure that the variant can in fact be created.
* @param {string} productOrProductId - the product the variant will be added to
* @param {object} variant - the variant to create
* @return {Promise} resolves to the creation result.
* @param productOrProductId - the product the variant will be added to
* @param variant - the variant to create
* @return resolves to the creation result.
*/
async create(
productOrProductId: string | Product,
variant: CreateProductVariantInput
): Promise<ProductVariant> {
return this.atomicPhase_(async (manager: EntityManager) => {
return await this.atomicPhase_(async (manager: EntityManager) => {
const productRepo = manager.getCustomRepository(this.productRepository_)
const variantRepo = manager.getCustomRepository(
this.productVariantRepository_
@@ -193,7 +156,7 @@ class ProductVariantService extends BaseService {
const { prices, ...rest } = variant
let product = productOrProductId as Product
let product = productOrProductId
if (typeof product === `string`) {
product = (await productRepo.findOne({
@@ -284,21 +247,21 @@ class ProductVariantService extends BaseService {
* Updates a variant.
* Price updates should use dedicated methods.
* The function will throw, if price updates are attempted.
* @param {string | ProductVariant} variantOrVariantId - variant or id of a variant.
* @param {object} update - an object with the update values.
* @param {object} config - an object with the config values for returning the variant.
* @return {Promise} resolves to the update result.
* @param variantOrVariantId - variant or id of a variant.
* @param update - an object with the update values.
* @param config - an object with the config values for returning the variant.
* @return resolves to the update result.
*/
async update(
variantOrVariantId: string | Partial<ProductVariant>,
update: UpdateProductVariantInput
): Promise<ProductVariant> {
return this.atomicPhase_(async (manager: EntityManager) => {
return await this.atomicPhase_(async (manager: EntityManager) => {
const variantRepo = manager.getCustomRepository(
this.productVariantRepository_
)
let variant = variantOrVariantId as ProductVariant
let variant = variantOrVariantId
if (typeof variant === `string`) {
const variantRes = await variantRepo.findOne({
where: { id: variantOrVariantId as string },
@@ -321,13 +284,13 @@ class ProductVariantService extends BaseService {
const { prices, options, metadata, inventory_quantity, ...rest } = update
if (prices) {
await this.updateVariantPrices(variant.id, prices)
await this.updateVariantPrices(variant.id!, prices)
}
if (options) {
for (const option of options) {
await this.updateOptionValue(
variant.id,
variant.id!,
option.option_id,
option.value
)
@@ -335,7 +298,7 @@ class ProductVariantService extends BaseService {
}
if (typeof metadata === "object") {
variant.metadata = this.setMetadata_(variant, metadata as object)
variant.metadata = setMetadata(variant as ProductVariant, metadata)
}
if (typeof inventory_quantity === "number") {
@@ -365,13 +328,13 @@ class ProductVariantService extends BaseService {
* Deletes any prices that are not in the update object, and is not associated with a price list.
* @param variantId - the id of variant
* @param prices - the update prices
* @returns {Promise<void>} empty promise
* @returns empty promise
*/
async updateVariantPrices(
variantId: string,
prices: ProductVariantPrice[]
): Promise<void> {
return this.atomicPhase_(async (manager: EntityManager) => {
return await this.atomicPhase_(async (manager: EntityManager) => {
const moneyAmountRepo = manager.getCustomRepository(
this.moneyAmountRepository_
)
@@ -404,15 +367,15 @@ class ProductVariantService extends BaseService {
* Gets the price specific to a region. If no region specific money amount
* exists the function will try to use a currency price. If no default
* currency price exists the function will throw an error.
* @param {string} variantId - the id of the variant to get price from
* @param {GetRegionPriceContext} context - context for getting region price
* @return {number} the price specific to the region
* @param variantId - the id of the variant to get price from
* @param context - context for getting region price
* @return the price specific to the region
*/
async getRegionPrice(
variantId: string,
context: GetRegionPriceContext
): Promise<number> {
return this.atomicPhase_(async (manager: EntityManager) => {
): Promise<number | null> {
return await this.atomicPhase_(async (manager: EntityManager) => {
const region = await this.regionService_
.withTransaction(manager)
.retrieve(context.regionId)
@@ -433,15 +396,15 @@ class ProductVariantService extends BaseService {
/**
* Sets the default price of a specific region
* @param {string} variantId - the id of the variant to update
* @param {string} price - the price for the variant.
* @return {Promise} the result of the update operation
* @param variantId - the id of the variant to update
* @param price - the price for the variant.
* @return the result of the update operation
*/
async setRegionPrice(
variantId: string,
price: ProductVariantPrice
): Promise<MoneyAmount> {
return this.atomicPhase_(async (manager: EntityManager) => {
return await this.atomicPhase_(async (manager: EntityManager) => {
const moneyAmountRepo = manager.getCustomRepository(
this.moneyAmountRepository_
)
@@ -463,22 +426,21 @@ class ProductVariantService extends BaseService {
moneyAmount.amount = price.amount
}
const result = await moneyAmountRepo.save(moneyAmount)
return result
return await moneyAmountRepo.save(moneyAmount)
})
}
/**
* Sets the default price for the given currency.
* @param {string} variantId - the id of the variant to set prices for
* @param {ProductVariantPrice} price - the price for the variant
* @return {Promise} the result of the update operation
* @param variantId - the id of the variant to set prices for
* @param price - the price for the variant
* @return the result of the update operation
*/
async setCurrencyPrice(
variantId: string,
price: ProductVariantPrice
): Promise<MoneyAmount> {
return this.atomicPhase_(async (manager: EntityManager) => {
return await this.atomicPhase_(async (manager: EntityManager) => {
const moneyAmountRepo = manager.getCustomRepository(
this.moneyAmountRepository_
)
@@ -490,17 +452,17 @@ class ProductVariantService extends BaseService {
/**
* Updates variant's option value.
* Option value must be of type string or number.
* @param {string} variantId - the variant to decorate.
* @param {string} optionId - the option from product.
* @param {string} optionValue - option value to add.
* @return {Promise} the result of the update operation.
* @param variantId - the variant to decorate.
* @param optionId - the option from product.
* @param optionValue - option value to add.
* @return the result of the update operation.
*/
async updateOptionValue(
variantId: string,
optionId: string,
optionValue: string
): Promise<ProductOptionValue> {
return this.atomicPhase_(async (manager: EntityManager) => {
return await this.atomicPhase_(async (manager: EntityManager) => {
const productOptionValueRepo = manager.getCustomRepository(
this.productOptionValueRepository_
)
@@ -528,17 +490,17 @@ class ProductVariantService extends BaseService {
* if that product does not have an option with the given
* option id. Fails if given variant is not found.
* Option value must be of type string or number.
* @param {string} variantId - the variant to decorate.
* @param {string} optionId - the option from product.
* @param {string} optionValue - option value to add.
* @return {Promise} the result of the update operation.
* @param variantId - the variant to decorate.
* @param optionId - the option from product.
* @param optionValue - option value to add.
* @return the result of the update operation.
*/
async addOptionValue(
variantId: string,
optionId: string,
optionValue: string
): Promise<ProductOptionValue> {
return this.atomicPhase_(async (manager: EntityManager) => {
return await this.atomicPhase_(async (manager: EntityManager) => {
const productOptionValueRepo = manager.getCustomRepository(
this.productOptionValueRepository_
)
@@ -556,12 +518,12 @@ class ProductVariantService extends BaseService {
/**
* Deletes option value from given variant.
* Will never fail due to delete being idempotent.
* @param {string} variantId - the variant to decorate.
* @param {string} optionId - the option from product.
* @return {Promise} empty promise
* @param variantId - the variant to decorate.
* @param optionId - the option from product.
* @return empty promise
*/
async deleteOptionValue(variantId: string, optionId: string): Promise<void> {
return this.atomicPhase_(async (manager: EntityManager) => {
return await this.atomicPhase_(async (manager: EntityManager) => {
const productOptionValueRepo: ProductOptionValueRepository =
manager.getCustomRepository(this.productOptionValueRepository_)
@@ -583,9 +545,9 @@ class ProductVariantService extends BaseService {
}
/**
* @param {object} selector - the query object for find
* @param {FindConfig<ProductVariant>} config - query config object for variant retrieval
* @return {Promise} the result of the find operation
* @param selector - the query object for find
* @param config - query config object for variant retrieval
* @return the result of the find operation
*/
async listAndCount(
selector: FilterableProductVariantProps,
@@ -624,9 +586,9 @@ class ProductVariantService extends BaseService {
}
/**
* @param {FilterableProductVariantProps} selector - the query object for find
* @param {FindConfig<ProductVariant>} config - query config object for variant retrieval
* @return {Promise} the result of the find operation
* @param selector - the query object for find
* @param config - query config object for variant retrieval
* @return the result of the find operation
*/
async list(
selector: FilterableProductVariantProps,
@@ -652,7 +614,7 @@ class ProductVariantService extends BaseService {
delete selector.q
}
const query = this.buildQuery_(selector, config)
const query = buildQuery(selector, config)
if (q) {
const where = query.where
@@ -682,12 +644,12 @@ class ProductVariantService extends BaseService {
/**
* Deletes variant.
* Will never fail due to delete being idempotent.
* @param {string} variantId - the id of the variant to delete. Must be
* @param variantId - the id of the variant to delete. Must be
* castable as an ObjectId
* @return {Promise<void>} empty promise
* @return empty promise
*/
async delete(variantId: string): Promise<void> {
return this.atomicPhase_(async (manager: EntityManager) => {
return await this.atomicPhase_(async (manager: EntityManager) => {
const variantRepo = manager.getCustomRepository(
this.productVariantRepository_
)
@@ -710,47 +672,14 @@ class ProductVariantService extends BaseService {
product_id: variant.product_id,
metadata: variant.metadata,
})
return Promise.resolve()
})
}
/**
* Dedicated method to set metadata for a variant.
* @param {string} variant - the variant to set metadata for.
* @param {Object} metadata - the metadata to set
* @return {Object} updated metadata object
*/
setMetadata_(
variant: ProductVariant,
metadata: object
): Record<string, unknown> {
const existing = variant.metadata || {}
const newData = {}
for (const [key, value] of Object.entries(metadata)) {
if (typeof key !== "string") {
throw new MedusaError(
MedusaError.Types.INVALID_ARGUMENT,
"Key type is invalid. Metadata keys must be strings"
)
}
newData[key] = value
}
const updated = {
...existing,
...newData,
}
return updated
}
/**
* Creates a query object to be used for list queries.
* @param {object} selector - the selector to create the query from
* @param {object} config - the config to use for the query
* @return {object} an object containing the query, relations and free-text
* @param selector - the selector to create the query from
* @param config - the config to use for the query
* @return an object containing the query, relations and free-text
* search param.
*/
prepareListQuery_(
@@ -763,7 +692,7 @@ class ProductVariantService extends BaseService {
delete selector.q
}
const query = this.buildQuery_(selector, config)
const query = buildQuery(selector, config)
if (config.relations && config.relations.length > 0) {
query.relations = config.relations
@@ -773,7 +702,7 @@ class ProductVariantService extends BaseService {
query.select = config.select
}
const rels = query.relations
const rels = query.relations as string[]
delete query.relations
return {
@@ -786,10 +715,10 @@ class ProductVariantService extends BaseService {
/**
* Lists variants based on the provided parameters and includes the count of
* variants that match the query.
* @param {object} variantRepo - the variant repository
* @param {object} query - object that defines the scope for what should be returned
* @param {object} q - free text query
* @return {Promise<[ProductVariant[], number]>} an array containing the products as the first element and the total
* @param variantRepo - the variant repository
* @param query - object that defines the scope for what should be returned
* @param q - free text query
* @return an array containing the products as the first element and the total
* count of products that matches the query as the second element.
*/
getFreeTextQueryBuilder_(
-1
View File
@@ -39,7 +39,6 @@ type InjectedDependencies = {
/**
* Provides layer to manipulate regions.
* @extends BaseService
*/
class RegionService extends TransactionBaseService {
static Events = {
+1 -13
View File
@@ -74,19 +74,7 @@ class ReturnService extends TransactionBaseService {
inventoryService,
orderService,
}: InjectedDependencies) {
super({
manager,
totalsService,
lineItemService,
returnRepository,
returnItemRepository,
shippingOptionService,
returnReasonService,
taxProviderService,
fulfillmentProviderService,
inventoryService,
orderService,
})
super(arguments[0])
this.manager_ = manager
this.totalsService_ = totalsService
@@ -41,12 +41,7 @@ class SalesChannelService extends TransactionBaseService {
storeService,
}: InjectedDependencies) {
// eslint-disable-next-line prefer-rest-params
super({
salesChannelRepository,
eventBusService,
manager,
storeService,
})
super(arguments[0])
this.manager_ = manager
this.salesChannelRepository_ = salesChannelRepository
@@ -27,6 +27,7 @@ type InjectedDependencies = {
shippingProfileRepository: typeof ShippingProfileRepository
productRepository: typeof ProductRepository
}
/**
* Provides layer to manipulate profiles.
* @constructor
@@ -51,14 +52,7 @@ class ShippingProfileService extends TransactionBaseService {
shippingOptionService,
customShippingOptionService,
}: InjectedDependencies) {
super({
manager,
shippingProfileRepository,
productService,
productRepository,
shippingOptionService,
customShippingOptionService,
})
super(arguments[0])
this.manager_ = manager
this.shippingProfileRepository_ = shippingProfileRepository
@@ -1,43 +1,24 @@
import { BaseService } from "medusa-interfaces"
import { EntityManager } from "typeorm"
import { ShippingTaxRate } from "../models/shipping-tax-rate"
import { ShippingTaxRate } from "../models"
import { ShippingTaxRateRepository } from "../repositories/shipping-tax-rate"
import { FindConfig } from "../types/common"
import { FilterableShippingTaxRateProps } from "../types/shipping-tax-rate"
import { TransactionBaseService } from "../interfaces"
import { buildQuery } from "../utils"
/**
* Provides layer to manipulate Shipping variants.
* @extends BaseService
*/
class ShippingTaxRateService extends BaseService {
private manager_: EntityManager
private shippingTaxRateRepository_: typeof ShippingTaxRateRepository
class ShippingTaxRateService extends TransactionBaseService {
protected manager_: EntityManager
protected transactionManager_: EntityManager | undefined
protected readonly shippingTaxRateRepository_: typeof ShippingTaxRateRepository
constructor({ manager, shippingTaxRateRepository }) {
super()
super(arguments[0])
/** @private @const {EntityManager} */
this.manager_ = manager
/** @private @const {ShippingVariantModel} */
this.shippingTaxRateRepository_ = shippingTaxRateRepository
}
withTransaction(transactionManager: EntityManager): ShippingTaxRateService {
if (!transactionManager) {
return this
}
const cloned = new ShippingTaxRateService({
manager: transactionManager,
shippingTaxRateRepository: this.ShippingTaxRateRepository_,
})
cloned.transactionManager_ = transactionManager
return cloned
}
/**
* Lists Shipping Tax Rates given a certain query.
* @param selector - the query object for find
@@ -52,7 +33,7 @@ class ShippingTaxRateService extends BaseService {
this.shippingTaxRateRepository_
)
const query = this.buildQuery_(selector, config)
const query = buildQuery(selector, config)
return await sTaxRateRepo.find(query)
}
-1
View File
@@ -19,7 +19,6 @@ type InjectedDependencies = {
/**
* Provides layer to manipulate store settings.
* @extends BaseService
*/
class StoreService extends TransactionBaseService {
protected manager_: EntityManager
+18 -34
View File
@@ -1,5 +1,4 @@
import { MedusaError } from "medusa-core-utils"
import { BaseService } from "medusa-interfaces"
import { EntityManager } from "typeorm"
import { ProductTaxRate } from "../models/product-tax-rate"
import { ProductTypeTaxRate } from "../models/product-type-tax-rate"
@@ -16,14 +15,18 @@ import {
TaxRateListByConfig,
UpdateTaxRateInput,
} from "../types/tax-rate"
import { isDefined, PostgresError } from "../utils"
import { buildQuery, isDefined, PostgresError } from "../utils"
import { TransactionBaseService } from "../interfaces"
import { FindConditions } from "typeorm/find-options/FindConditions"
class TaxRateService extends BaseService {
private manager_: EntityManager
private productService_: ProductService
private productTypeService_: ProductTypeService
private shippingOptionService_: ShippingOptionService
private taxRateRepository_: typeof TaxRateRepository
class TaxRateService extends TransactionBaseService {
protected manager_: EntityManager
protected transactionManager_: EntityManager | undefined
protected readonly productService_: ProductService
protected readonly productTypeService_: ProductTypeService
protected readonly shippingOptionService_: ShippingOptionService
protected readonly taxRateRepository_: typeof TaxRateRepository
constructor({
manager,
@@ -32,7 +35,7 @@ class TaxRateService extends BaseService {
shippingOptionService,
taxRateRepository,
}) {
super()
super(arguments[0])
this.manager_ = manager
this.taxRateRepository_ = taxRateRepository
@@ -41,25 +44,6 @@ class TaxRateService extends BaseService {
this.shippingOptionService_ = shippingOptionService
}
withTransaction(transactionManager: EntityManager): TaxRateService {
if (!transactionManager) {
return this
}
const cloned = new TaxRateService({
manager: transactionManager,
taxRateRepository: this.taxRateRepository_,
productService: this.productService_,
productTypeService: this.productTypeService_,
shippingOptionService: this.shippingOptionService_,
})
cloned.transactionManager_ = transactionManager
cloned.manager_ = transactionManager
return cloned
}
async list(
selector: FilterableTaxRateProps,
config: FindConfig<TaxRate> = {}
@@ -67,7 +51,7 @@ class TaxRateService extends BaseService {
const taxRateRepo = this.manager_.getCustomRepository(
this.taxRateRepository_
)
const query = this.buildQuery_(selector, config)
const query = buildQuery(selector, config)
return await taxRateRepo.findWithResolution(query)
}
@@ -78,7 +62,7 @@ class TaxRateService extends BaseService {
const taxRateRepo = this.manager_.getCustomRepository(
this.taxRateRepository_
)
const query = this.buildQuery_(selector, config)
const query = buildQuery(selector, config)
return await taxRateRepo.findAndCountWithResolution(query)
}
@@ -88,7 +72,7 @@ class TaxRateService extends BaseService {
): Promise<TaxRate> {
const manager = this.manager_
const taxRateRepo = manager.getCustomRepository(this.taxRateRepository_)
const query = this.buildQuery_({ id }, config)
const query = buildQuery({ id }, config)
const taxRate = await taxRateRepo.findOneWithResolution(query)
if (!taxRate) {
@@ -135,8 +119,8 @@ class TaxRateService extends BaseService {
async delete(id: string | string[]): Promise<void> {
return await this.atomicPhase_(async (manager: EntityManager) => {
const taxRateRepo = manager.getCustomRepository(this.taxRateRepository_)
const query = this.buildQuery_({ id })
await taxRateRepo.delete(query.where)
const query = buildQuery({ id })
await taxRateRepo.delete(query.where as FindConditions<TaxRate>)
})
}
@@ -274,7 +258,7 @@ class TaxRateService extends BaseService {
id: string,
optionIds: string | string[],
replace = false
): Promise<ShippingTaxRate> {
): Promise<ShippingTaxRate[]> {
let ids: string[]
if (typeof optionIds === "string") {
ids = [optionIds]
+1 -6
View File
@@ -111,12 +111,7 @@ class TotalsService extends TransactionBaseService {
taxCalculationStrategy,
featureFlagRouter,
}: TotalsServiceProps) {
super({
taxProviderService,
taxCalculationStrategy,
manager,
featureFlagRouter,
})
super(arguments[0])
this.manager_ = manager
this.taxProviderService_ = taxProviderService
-1
View File
@@ -23,7 +23,6 @@ type UserServiceProps = {
/**
* Provides layer to manipulate users.
* @extends BaseService
*/
class UserService extends TransactionBaseService {
static Events = {
+1 -1
View File
@@ -54,7 +54,7 @@ export type CartCreateProps = {
customer_id?: string
type?: CartType
context?: object
metadata?: object
metadata?: Record<string, unknown>
sales_channel_id?: string
country_code?: string
}
+2 -2
View File
@@ -14,7 +14,7 @@ export type CreateClaimInput = {
refund_amount?: number
shipping_address?: AddressPayload
no_notification?: boolean
metadata?: object
metadata?: Record<string, unknown>
order: Order
claim_order_id?: string
shipping_address_id?: string
@@ -67,7 +67,7 @@ type UpdateClaimItemInput = {
reason?: string
images: UpdateClaimItemImageInput[]
tags: UpdateClaimItemTagInput[]
metadata?: object
metadata?: Record<string, unknown>
}
type UpdateClaimItemImageInput = {
+1 -1
View File
@@ -37,5 +37,5 @@ export class CustomerGroupsBatchCustomer {
export class CustomerGroupUpdate {
name?: string
metadata?: object
metadata?: Record<string, unknown>
}
+1 -1
View File
@@ -161,5 +161,5 @@ export type CreateDynamicDiscountInput = {
code: string
ends_at?: Date
usage_limit: number
metadata?: object
metadata?: Record<string, unknown>
}
+2 -2
View File
@@ -57,7 +57,7 @@ export type CreateProductVariantInput = {
width?: number
options: ProductVariantOption[]
prices: ProductVariantPrice[]
metadata?: object
metadata?: Record<string, unknown>
}
export type UpdateProductVariantInput = {
@@ -81,7 +81,7 @@ export type UpdateProductVariantInput = {
width?: number
options?: ProductVariantOption[]
prices?: ProductVariantPrice[]
metadata?: object
metadata?: Record<string, unknown>
}
export class FilterableProductVariantProps {
+2 -2
View File
@@ -197,7 +197,7 @@ export type CreateProductProductVariantInput = {
origin_country?: string
mid_code?: string
material?: string
metadata?: object
metadata?: Record<string, unknown>
prices?: CreateProductProductVariantPriceInput[]
options?: { value: string }[]
}
@@ -220,7 +220,7 @@ export type UpdateProductProductVariantDTO = {
origin_country?: string
mid_code?: string
material?: string
metadata?: object
metadata?: Record<string, unknown>
prices?: CreateProductProductVariantPriceInput[]
options?: { value: string; option_id: string }[]
}