Chore/rm main entity concept (#7709)

**What**
Update the `MedusaService` class, factory and types to remove the concept of main modules. The idea being that all method will be explicitly named and suffixes to represent the object you are trying to manipulate.
This pr also includes various fixes in different modules

Co-authored-by: Stevche Radevski <4820812+sradevski@users.noreply.github.com>
Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
Adrien de Peretti
2024-06-19 15:02:16 +02:00
committed by GitHub
parent 2895ccfba8
commit 48963f55ef
533 changed files with 6469 additions and 9769 deletions

View File

@@ -1,7 +1,12 @@
import { moduleDefinition } from "./module-definition"
import { ModuleExports } from "@medusajs/types"
import { PricingModuleService } from "@services"
const service = PricingModuleService
export const moduleDefinition: ModuleExports = {
service,
}
export default moduleDefinition
export * from "./models"
export * from "./services"
export * from "./types"

View File

@@ -1,56 +1,20 @@
import { Modules } from "@medusajs/modules-sdk"
import { ModuleJoinerConfig } from "@medusajs/types"
import { MapToConfig } from "@medusajs/utils"
import {
buildEntitiesNameToLinkableKeysMap,
defineJoinerConfig,
MapToConfig,
} from "@medusajs/utils"
import { Price, PriceList, PriceSet, RuleType } from "@models"
import schema from "./schema"
export const LinkableKeys = {
price_set_id: PriceSet.name,
price_list_id: PriceList.name,
price_id: Price.name,
rule_type_id: RuleType.name,
}
const entityLinkableKeysMap: MapToConfig = {}
Object.entries(LinkableKeys).forEach(([key, value]) => {
entityLinkableKeysMap[value] ??= []
entityLinkableKeysMap[value].push({
mapTo: key,
valueFrom: key.split("_").pop()!,
})
export const joinerConfig = defineJoinerConfig(Modules.PRICING, {
entityQueryingConfig: [PriceSet, PriceList, Price, RuleType],
linkableKeys: {
price_set_id: PriceSet.name,
price_list_id: PriceList.name,
price_id: Price.name,
rule_type_id: RuleType.name,
},
})
export const entityNameToLinkableKeysMap: MapToConfig = entityLinkableKeysMap
export const joinerConfig: ModuleJoinerConfig = {
serviceName: Modules.PRICING,
primaryKeys: ["id"],
linkableKeys: LinkableKeys,
schema,
alias: [
{
name: ["price_set", "price_sets"],
args: {
entity: "PriceSet",
},
},
{
name: ["price_list", "price_lists"],
args: {
methodSuffix: "PriceLists",
},
},
{
name: ["price", "prices"],
args: {
methodSuffix: "Prices",
},
},
{
name: ["rule_type", "rule_types"],
args: {
methodSuffix: "RuleTypes",
},
},
],
}
export const entityNameToLinkableKeysMap: MapToConfig =
buildEntitiesNameToLinkableKeysMap(joinerConfig.linkableKeys)

View File

@@ -1,8 +0,0 @@
import { ModuleExports } from "@medusajs/types"
import { PricingModuleService } from "@services"
const service = PricingModuleService
export const moduleDefinition: ModuleExports = {
service,
}

View File

@@ -1,19 +0,0 @@
#!/usr/bin/env node
import { EOL } from "os"
import { run } from "../seed"
const args = process.argv
const path = args.pop() as string
export default (async () => {
const { config } = await import("dotenv")
config()
if (!path) {
throw new Error(
`filePath is required.${EOL}Example: medusa-pricing-seed <filePath>`
)
}
await run({ path })
})()

View File

@@ -1,84 +0,0 @@
import { LoaderOptions, Logger, ModulesSdkTypes } from "@medusajs/types"
import { DALUtils, ModulesSdkUtils } from "@medusajs/utils"
import { EntitySchema, RequiredEntityData } from "@mikro-orm/core"
import { PostgreSqlDriver, SqlEntityManager } from "@mikro-orm/postgresql"
import * as PricingModels from "@models"
import { EOL } from "os"
import { resolve } from "path"
export async function run({
options,
logger,
path,
}: Partial<
Pick<
LoaderOptions<ModulesSdkTypes.ModuleServiceInitializeOptions>,
"options" | "logger"
>
> & {
path: string
}) {
logger ??= console as unknown as Logger
logger.info(`Loading seed data from ${path}...`)
const { priceSetsData, pricesData } = await import(
resolve(process.cwd(), path)
).catch((e) => {
logger?.error(
`Failed to load seed data from ${path}. Please, provide a relative path and check that you export the following: priceSetsData and pricesData.${EOL}${e}`
)
throw e
})
const dbData = ModulesSdkUtils.loadDatabaseConfig("pricing", options)!
const entities = Object.values(PricingModels) as unknown as EntitySchema[]
const pathToMigrations = __dirname + "/../migrations"
const orm = await DALUtils.mikroOrmCreateConnection(
dbData,
entities,
pathToMigrations
)
const manager = orm.em.fork()
try {
logger.info("Inserting price_sets & prices")
await createPriceSets(manager, priceSetsData)
await createPrices(manager, pricesData)
} catch (e) {
logger.error(
`Failed to insert the seed data in the PostgreSQL database ${dbData.clientUrl}.${EOL}${e}`
)
}
await orm.close(true)
}
async function createPriceSets(
manager: SqlEntityManager<PostgreSqlDriver>,
data: RequiredEntityData<PricingModels.PriceSet>[]
) {
const priceSets = data.map((priceSetData) => {
return manager.create(PricingModels.PriceSet, priceSetData)
})
await manager.persistAndFlush(priceSets)
return priceSets
}
async function createPrices(
manager: SqlEntityManager<PostgreSqlDriver>,
data: RequiredEntityData<PricingModels.Price>[]
) {
const prices = data.map((priceData) => {
return manager.create(PricingModels.Price, priceData)
})
await manager.persistAndFlush(prices)
return prices
}

View File

@@ -68,6 +68,7 @@ type InjectedDependencies = {
}
const generateMethodForModels = {
PriceSet,
PriceList,
PriceListRule,
PriceListRuleValue,
@@ -77,46 +78,35 @@ const generateMethodForModels = {
RuleType,
}
export default class PricingModuleService<
TPriceSet extends PriceSet = PriceSet,
TRuleType extends RuleType = RuleType,
TPriceRule extends PriceRule = PriceRule,
TPriceSetRuleType extends PriceSetRuleType = PriceSetRuleType,
TPrice extends Price = Price,
TPriceList extends PriceList = PriceList,
TPriceListRule extends PriceListRule = PriceListRule,
TPriceListRuleValue extends PriceListRuleValue = PriceListRuleValue
>
extends ModulesSdkUtils.MedusaService<
PricingTypes.PriceSetDTO,
{
Price: { dto: PricingTypes.PriceDTO }
PriceRule: {
dto: PricingTypes.PriceRuleDTO
create: PricingTypes.CreatePriceRuleDTO
update: PricingTypes.UpdatePriceRuleDTO
}
RuleType: {
dto: PricingTypes.RuleTypeDTO
create: PricingTypes.CreateRuleTypeDTO
update: PricingTypes.UpdateRuleTypeDTO
}
PriceList: { dto: PricingTypes.PriceListDTO }
PriceListRule: { dto: PricingTypes.PriceListRuleDTO }
export default class PricingModuleService
extends ModulesSdkUtils.MedusaService<{
PriceSet: { dto: PricingTypes.PriceSetDTO }
Price: { dto: PricingTypes.PriceDTO }
PriceRule: {
dto: PricingTypes.PriceRuleDTO
create: PricingTypes.CreatePriceRuleDTO
update: PricingTypes.UpdatePriceRuleDTO
}
>(PriceSet, generateMethodForModels, entityNameToLinkableKeysMap)
RuleType: {
dto: PricingTypes.RuleTypeDTO
create: PricingTypes.CreateRuleTypeDTO
update: PricingTypes.UpdateRuleTypeDTO
}
PriceList: { dto: PricingTypes.PriceListDTO }
PriceListRule: { dto: PricingTypes.PriceListRuleDTO }
}>(generateMethodForModels, entityNameToLinkableKeysMap)
implements PricingTypes.IPricingModuleService
{
protected baseRepository_: DAL.RepositoryService
protected readonly pricingRepository_: PricingRepositoryService
protected readonly ruleTypeService_: RuleTypeService<TRuleType>
protected readonly priceSetService_: ModulesSdkTypes.IMedusaInternalService<TPriceSet>
protected readonly priceRuleService_: ModulesSdkTypes.IMedusaInternalService<TPriceRule>
protected readonly priceSetRuleTypeService_: ModulesSdkTypes.IMedusaInternalService<TPriceSetRuleType>
protected readonly priceService_: ModulesSdkTypes.IMedusaInternalService<TPrice>
protected readonly priceListService_: PriceListService<TPriceList>
protected readonly priceListRuleService_: ModulesSdkTypes.IMedusaInternalService<TPriceListRule>
protected readonly priceListRuleValueService_: ModulesSdkTypes.IMedusaInternalService<TPriceListRuleValue>
protected readonly ruleTypeService_: RuleTypeService<RuleType>
protected readonly priceSetService_: ModulesSdkTypes.IMedusaInternalService<PriceSet>
protected readonly priceRuleService_: ModulesSdkTypes.IMedusaInternalService<PriceRule>
protected readonly priceSetRuleTypeService_: ModulesSdkTypes.IMedusaInternalService<PriceSetRuleType>
protected readonly priceService_: ModulesSdkTypes.IMedusaInternalService<Price>
protected readonly priceListService_: PriceListService<PriceList>
protected readonly priceListRuleService_: ModulesSdkTypes.IMedusaInternalService<PriceListRule>
protected readonly priceListRuleValueService_: ModulesSdkTypes.IMedusaInternalService<PriceListRuleValue>
constructor(
{
@@ -174,14 +164,15 @@ export default class PricingModuleService<
}
@InjectManager("baseRepository_")
async list(
// @ts-expect-error
async listPriceSets(
filters: PricingTypes.FilterablePriceSetProps = {},
config: FindConfig<PricingTypes.PriceSetDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<PriceSetDTO[]> {
const pricingContext = this.setupCalculatedPriceConfig_(filters, config)
const priceSets = await super.list(filters, config, sharedContext)
const priceSets = await super.listPriceSets(filters, config, sharedContext)
if (pricingContext && priceSets.length) {
const priceSetIds: string[] = []
@@ -207,14 +198,15 @@ export default class PricingModuleService<
}
@InjectManager("baseRepository_")
async listAndCount(
// @ts-expect-error
async listAndCountPriceSets(
filters: PricingTypes.FilterablePriceSetProps = {},
config: FindConfig<PricingTypes.PriceSetDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<[PriceSetDTO[], number]> {
const pricingContext = this.setupCalculatedPriceConfig_(filters, config)
const [priceSets, count] = await super.listAndCount(
const [priceSets, count] = await super.listAndCountPriceSets(
filters,
config,
sharedContext
@@ -315,27 +307,28 @@ export default class PricingModuleService<
return JSON.parse(JSON.stringify(calculatedPrices))
}
async create(
// @ts-expect-error
async createPriceSets(
data: PricingTypes.CreatePriceSetDTO,
sharedContext?: Context
): Promise<PriceSetDTO>
async create(
async createPriceSets(
data: PricingTypes.CreatePriceSetDTO[],
sharedContext?: Context
): Promise<PriceSetDTO[]>
@InjectManager("baseRepository_")
@EmitEvents()
async create(
async createPriceSets(
data: PricingTypes.CreatePriceSetDTO | PricingTypes.CreatePriceSetDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<PriceSetDTO | PriceSetDTO[]> {
const input = Array.isArray(data) ? data : [data]
const priceSets = await this.create_(input, sharedContext)
const priceSets = await this.createPriceSets_(input, sharedContext)
// TODO: Remove the need to refetch the data here
const dbPriceSets = await this.list(
const dbPriceSets = await this.listPriceSets(
{ id: priceSets.map((p) => p.id) },
{
relations: [
@@ -358,17 +351,17 @@ export default class PricingModuleService<
)
}
async upsert(
async upsertPriceSets(
data: UpsertPriceSetDTO[],
sharedContext?: Context
): Promise<PriceSetDTO[]>
async upsert(
async upsertPriceSets(
data: UpsertPriceSetDTO,
sharedContext?: Context
): Promise<PriceSetDTO>
@InjectManager("baseRepository_")
async upsert(
async upsertPriceSets(
data: UpsertPriceSetDTO | UpsertPriceSetDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<PriceSetDTO | PriceSetDTO[]> {
@@ -383,10 +376,10 @@ export default class PricingModuleService<
const operations: Promise<PriceSet[]>[] = []
if (forCreate.length) {
operations.push(this.create_(forCreate, sharedContext))
operations.push(this.createPriceSets_(forCreate, sharedContext))
}
if (forUpdate.length) {
operations.push(this.update_(forUpdate, sharedContext))
operations.push(this.updatePriceSets_(forUpdate, sharedContext))
}
const result = (await promiseAll(operations)).flat()
@@ -395,19 +388,20 @@ export default class PricingModuleService<
)
}
async update(
// @ts-expect-error
async updatePriceSets(
id: string,
data: PricingTypes.UpdatePriceSetDTO,
sharedContext?: Context
): Promise<PriceSetDTO>
async update(
async updatePriceSets(
selector: PricingTypes.FilterablePriceSetProps,
data: PricingTypes.UpdatePriceSetDTO,
sharedContext?: Context
): Promise<PriceSetDTO[]>
@InjectManager("baseRepository_")
async update(
async updatePriceSets(
idOrSelector: string | PricingTypes.FilterablePriceSetProps,
data: PricingTypes.UpdatePriceSetDTO,
@MedusaContext() sharedContext: Context = {}
@@ -430,7 +424,10 @@ export default class PricingModuleService<
}))
}
const updateResult = await this.update_(normalizedInput, sharedContext)
const updateResult = await this.updatePriceSets_(
normalizedInput,
sharedContext
)
const priceSets = await this.baseRepository_.serialize<
PriceSetDTO[] | PriceSetDTO
>(updateResult)
@@ -487,7 +484,7 @@ export default class PricingModuleService<
}
@InjectTransactionManager("baseRepository_")
protected async update_(
protected async updatePriceSets_(
data: ServiceTypes.UpdatePriceSetInput[],
@MedusaContext() sharedContext: Context = {}
): Promise<PriceSet[]> {
@@ -549,7 +546,7 @@ export default class PricingModuleService<
const priceSets = await this.addRules_(inputs, sharedContext)
const dbPriceSets = await this.list(
const dbPriceSets = await this.listPriceSets(
{ id: priceSets.map(({ id }) => id) },
{ relations: ["rule_types"] }
)
@@ -581,7 +578,7 @@ export default class PricingModuleService<
await this.addPrices_(input, sharedContext)
const dbPrices = await this.list(
const dbPrices = await this.listPriceSets(
{ id: input.map((d) => d.priceSetId) },
{ relations: ["prices"] },
sharedContext
@@ -719,7 +716,7 @@ export default class PricingModuleService<
}
@InjectTransactionManager("baseRepository_")
protected async create_(
protected async createPriceSets_(
data: PricingTypes.CreatePriceSetDTO[],
@MedusaContext() sharedContext: Context = {}
) {
@@ -767,11 +764,11 @@ export default class PricingModuleService<
)
}
const ruleSetRuleTypeToCreateMap: Map<string, TPriceSetRuleType> = new Map()
const ruleSetRuleTypeToCreateMap: Map<string, PriceSetRuleType> = new Map()
const toCreate = input.map((inputData) => {
const id = generateEntityId(
(inputData as unknown as TPriceSet).id,
(inputData as unknown as PriceSet).id,
PriceSetIdPrefix
)
@@ -783,7 +780,7 @@ export default class PricingModuleService<
const priceSetRuleType = {
rule_type_id: ruleTypeMap.get(rule.rule_attribute).id,
price_set_id: id,
} as TPriceSetRuleType
} as PriceSetRuleType
ruleSetRuleTypeToCreateMap.set(
JSON.stringify(priceSetRuleType),
@@ -810,7 +807,7 @@ export default class PricingModuleService<
const priceSetRuleType = {
rule_type_id: ruleTypeMap.get(attribute).id,
price_set_id: id,
} as TPriceSetRuleType
} as PriceSetRuleType
ruleSetRuleTypeToCreateMap.set(
JSON.stringify(priceSetRuleType),
@@ -897,7 +894,7 @@ export default class PricingModuleService<
protected async addRules_(
inputs: PricingTypes.AddRulesDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<TPriceSet[]> {
): Promise<PriceSet[]> {
const priceSets = await this.priceSetService_.list(
{ id: inputs.map((d) => d.priceSetId) },
{ relations: ["rule_types"] },
@@ -981,7 +978,7 @@ export default class PricingModuleService<
input: AddPricesDTO[],
@MedusaContext() sharedContext: Context = {}
) {
const priceSets = await this.list(
const priceSets = await this.listPriceSets(
{ id: input.map((d) => d.priceSetId) },
{ relations: ["rule_types"] },
sharedContext
@@ -1137,7 +1134,7 @@ export default class PricingModuleService<
const priceListsToCreate: PricingTypes.CreatePriceListDTO[] = data.map(
(priceListData) => {
const id = generateEntityId(
(priceListData as unknown as TPriceList).id,
(priceListData as unknown as PriceList).id,
PriceListIdPrefix
)
@@ -1364,7 +1361,7 @@ export default class PricingModuleService<
protected async updatePriceListPrices_(
data: PricingTypes.UpdatePriceListPricesDTO[],
sharedContext: Context = {}
): Promise<TPrice[]> {
): Promise<Price[]> {
const ruleTypeAttributes: string[] = []
const priceListIds: string[] = []
const priceIds: string[] = []
@@ -1401,7 +1398,7 @@ export default class PricingModuleService<
ruleTypes.map((rt) => [rt.rule_attribute, rt])
)
const priceSets = await this.list(
const priceSets = await this.listPriceSets(
{ id: priceSetIds },
{ relations: ["rule_types"] },
sharedContext
@@ -1456,7 +1453,7 @@ export default class PricingModuleService<
const priceListMap = new Map(priceLists.map((p) => [p.id, p]))
const pricesToUpdate: Partial<TPrice>[] = []
const pricesToUpdate: Partial<Price>[] = []
const priceRuleIdsToDelete: string[] = []
const priceRulesToCreate: CreatePriceRuleDTO[] = []
@@ -1487,7 +1484,7 @@ export default class PricingModuleService<
pricesToUpdate.push({
...rest,
rules_count: Object.keys(rules).length,
} as unknown as TPrice)
} as unknown as Price)
priceRuleIdsToDelete.push(...priceRules.map((pr) => pr.id))
}
@@ -1515,7 +1512,7 @@ export default class PricingModuleService<
protected async addPriceListPrices_(
data: PricingTypes.AddPriceListPricesDTO[],
sharedContext: Context = {}
): Promise<TPrice[]> {
): Promise<Price[]> {
const ruleTypeAttributes: string[] = []
const priceListIds: string[] = []
const priceSetIds: string[] = []
@@ -1535,7 +1532,7 @@ export default class PricingModuleService<
sharedContext
)
const priceSets = await this.list(
const priceSets = await this.listPriceSets(
{ id: priceSetIds },
{ relations: ["rule_types"] },
sharedContext
@@ -1593,7 +1590,7 @@ export default class PricingModuleService<
const priceListMap = new Map(priceLists.map((p) => [p.id, p]))
const pricesToCreate: Partial<TPrice>[] = []
const pricesToCreate: Partial<Price>[] = []
for (const { price_list_id: priceListId, prices } of data) {
const priceList = priceListMap.get(priceListId)
@@ -1626,7 +1623,7 @@ export default class PricingModuleService<
price_list_id: priceList.id,
rules_count: noOfRules,
price_rules: priceRulesToCreate,
} as unknown as TPrice
} as unknown as Price
})
pricesToCreate.push(...priceListPricesToCreate)
@@ -1676,7 +1673,7 @@ export default class PricingModuleService<
protected async setPriceListRules_(
data: PricingTypes.SetPriceListRulesDTO[],
sharedContext: Context = {}
): Promise<TPriceList[]> {
): Promise<PriceList[]> {
// TODO: re think this method
const priceLists = await this.priceListService_.list(
@@ -1791,7 +1788,7 @@ export default class PricingModuleService<
protected async removePriceListRules_(
data: PricingTypes.RemovePriceListRulesDTO[],
sharedContext: Context = {}
): Promise<TPriceList[]> {
): Promise<PriceList[]> {
const priceLists = await this.priceListService_.list(
{ id: data.map((d) => d.price_list_id) },
{ relations: ["price_list_rules", "price_list_rules.rule_type"] },