feat: sales channel module (#5923)

This commit is contained in:
Frane Polić authored and GitHub committed 2024-01-29 09:47:28 +01:00
1 parent dfd9e7c772
commit 3db2f95e65
54 files changed
+1364 -61

No files matched your search

@@ -0,0 +1,17 @@
import { SalesChannelService, SalesChannelModuleService } from "@services"
import { asClass, asValue, createContainer } from "awilix"
export const mockContainer = createContainer()
mockContainer.register({
transaction: asValue(async (task) => await task()),
salesChannelRepository: asValue({
find: jest.fn().mockImplementation(async ({ where: { code } }) => {
return [{}]
}),
findAndCount: jest.fn().mockResolvedValue([[], 0]),
getFreshManager: jest.fn().mockResolvedValue({}),
}),
salesChannelService: asClass(SalesChannelService),
salesChannelModuleService: asClass(SalesChannelModuleService),
})
@@ -0,0 +1,34 @@
import { mockContainer } from "../__fixtures__/sales-channel"
describe("Sales channel service", function () {
beforeEach(function () {
jest.clearAllMocks()
})
it("should list sales channels with filters and relations", async function () {
const salesChannelRepository = mockContainer.resolve(
"salesChannelRepository"
)
const salesChannelService = mockContainer.resolve("salesChannelService")
const config = {
select: ["id", "name"],
}
await salesChannelService.list({}, config)
expect(salesChannelRepository.find).toHaveBeenCalledWith(
{
where: {},
options: {
fields: ["id", "name"],
limit: 15,
offset: 0,
withDeleted: undefined,
populate: [],
},
},
expect.any(Object)
)
})
})
@@ -0,0 +1,2 @@
export { default as SalesChannelService } from "./sales-channel"
export { default as SalesChannelModuleService } from "./sales-channel-module"
@@ -0,0 +1,247 @@
import {
Context,
DAL,
FilterableSalesChannelProps,
FindConfig,
InternalModuleDeclaration,
ISalesChannelModuleService,
ModuleJoinerConfig,
RestoreReturn,
SalesChannelDTO,
SoftDeleteReturn,
} from "@medusajs/types"
import {
InjectManager,
InjectTransactionManager,
mapObjectTo,
MedusaContext,
} from "@medusajs/utils"
import { CreateSalesChannelDTO, UpdateSalesChannelDTO } from "@medusajs/types"
import { SalesChannel } from "@models"
import SalesChannelService from "./sales-channel"
import {
joinerConfig,
entityNameToLinkableKeysMap,
LinkableKeys,
} from "../joiner-config"
type InjectedDependencies = {
baseRepository: DAL.RepositoryService
salesChannelService: SalesChannelService<any>
}
export default class SalesChannelModuleService<
TEntity extends SalesChannel = SalesChannel
> implements ISalesChannelModuleService
{
protected baseRepository_: DAL.RepositoryService
protected readonly salesChannelService_: SalesChannelService<TEntity>
constructor(
{ baseRepository, salesChannelService }: InjectedDependencies,
protected readonly moduleDeclaration: InternalModuleDeclaration
) {
this.baseRepository_ = baseRepository
this.salesChannelService_ = salesChannelService
}
__joinerConfig(): ModuleJoinerConfig {
return joinerConfig
}
async create(
data: CreateSalesChannelDTO[],
sharedContext?: Context
): Promise<SalesChannelDTO[]>
async create(
data: CreateSalesChannelDTO,
sharedContext?: Context
): Promise<SalesChannelDTO>
@InjectTransactionManager("baseRepository_")
async create(
data: CreateSalesChannelDTO | CreateSalesChannelDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<SalesChannelDTO | SalesChannelDTO[]> {
const input = Array.isArray(data) ? data : [data]
const result = await this.salesChannelService_.create(input, sharedContext)
return await this.baseRepository_.serialize<SalesChannelDTO[]>(
Array.isArray(data) ? result : result[0],
{
populate: true,
}
)
}
async delete(ids: string[], sharedContext?: Context): Promise<void>
async delete(id: string, sharedContext?: Context): Promise<void>
@InjectTransactionManager("baseRepository_")
async delete(
ids: string | string[],
@MedusaContext() sharedContext: Context = {}
): Promise<void> {
const salesChannelIds = Array.isArray(ids) ? ids : [ids]
await this.salesChannelService_.delete(salesChannelIds, sharedContext)
}
@InjectTransactionManager("baseRepository_")
protected async softDelete_(
salesChannelIds: string[],
@MedusaContext() sharedContext: Context = {}
): Promise<[TEntity[], Record<string, unknown[]>]> {
return await this.salesChannelService_.softDelete(
salesChannelIds,
sharedContext
)
}
@InjectManager("baseRepository_")
async softDelete<
TReturnableLinkableKeys extends string = Lowercase<
keyof typeof LinkableKeys
>
>(
salesChannelIds: string[],
{ returnLinkableKeys }: SoftDeleteReturn<TReturnableLinkableKeys> = {},
sharedContext: Context = {}
): Promise<Record<Lowercase<keyof typeof LinkableKeys>, string[]> | void> {
const [_, cascadedEntitiesMap] = await this.softDelete_(
salesChannelIds,
sharedContext
)
let mappedCascadedEntitiesMap
if (returnLinkableKeys) {
mappedCascadedEntitiesMap = mapObjectTo<
Record<Lowercase<keyof typeof LinkableKeys>, string[]>
>(cascadedEntitiesMap, entityNameToLinkableKeysMap, {
pick: returnLinkableKeys,
})
}
return mappedCascadedEntitiesMap ? mappedCascadedEntitiesMap : void 0
}
@InjectTransactionManager("baseRepository_")
async restore_(
salesChannelIds: string[],
@MedusaContext() sharedContext: Context = {}
): Promise<[TEntity[], Record<string, unknown[]>]> {
return await this.salesChannelService_.restore(
salesChannelIds,
sharedContext
)
}
@InjectManager("baseRepository_")
async restore<
TReturnableLinkableKeys extends string = Lowercase<
keyof typeof LinkableKeys
>
>(
salesChannelIds: string[],
{ returnLinkableKeys }: RestoreReturn<TReturnableLinkableKeys> = {},
sharedContext: Context = {}
): Promise<Record<Lowercase<keyof typeof LinkableKeys>, string[]> | void> {
const [_, cascadedEntitiesMap] = await this.restore_(
salesChannelIds,
sharedContext
)
let mappedCascadedEntitiesMap
if (returnLinkableKeys) {
mappedCascadedEntitiesMap = mapObjectTo<
Record<Lowercase<keyof typeof LinkableKeys>, string[]>
>(cascadedEntitiesMap, entityNameToLinkableKeysMap, {
pick: returnLinkableKeys,
})
}
return mappedCascadedEntitiesMap ? mappedCascadedEntitiesMap : void 0
}
async update(
data: UpdateSalesChannelDTO[],
sharedContext?: Context
): Promise<SalesChannelDTO[]>
async update(
data: UpdateSalesChannelDTO,
sharedContext?: Context
): Promise<SalesChannelDTO>
@InjectTransactionManager("baseRepository_")
async update(
data: UpdateSalesChannelDTO | UpdateSalesChannelDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<SalesChannelDTO | SalesChannelDTO[]> {
const input = Array.isArray(data) ? data : [data]
const result = await this.salesChannelService_.update(input, sharedContext)
return await this.baseRepository_.serialize<SalesChannelDTO[]>(
Array.isArray(data) ? result : result[0],
{
populate: true,
}
)
}
@InjectManager("baseRepository_")
async retrieve(
salesChannelId: string,
config: FindConfig<SalesChannelDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<SalesChannelDTO> {
const salesChannel = await this.salesChannelService_.retrieve(
salesChannelId,
config
)
return await this.baseRepository_.serialize<SalesChannelDTO>(salesChannel, {
populate: true,
})
}
@InjectManager("baseRepository_")
async list(
filters: {} = {},
config: FindConfig<SalesChannelDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<SalesChannelDTO[]> {
const salesChannels = await this.salesChannelService_.list(filters, config)
return await this.baseRepository_.serialize<SalesChannelDTO[]>(
salesChannels,
{
populate: true,
}
)
}
@InjectManager("baseRepository_")
async listAndCount(
filters: FilterableSalesChannelProps = {},
config: FindConfig<SalesChannelDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<[SalesChannelDTO[], number]> {
const [salesChannels, count] = await this.salesChannelService_.listAndCount(
filters,
config
)
return [
await this.baseRepository_.serialize<SalesChannelDTO[]>(salesChannels, {
populate: true,
}),
count,
]
}
}
@@ -0,0 +1,24 @@
import { DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { CreateSalesChannelDTO, UpdateSalesChannelDTO } from "@medusajs/types"
import { SalesChannel } from "@models"
type InjectedDependencies = {
salesChannelRepository: DAL.RepositoryService
}
export default class SalesChannelService<
TEntity extends SalesChannel = SalesChannel
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: CreateSalesChannelDTO
update: UpdateSalesChannelDTO
}
>(SalesChannel)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}