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:
authored and GitHub committed 2024-06-19 13:02:16 +00:00
1 parent 2895ccfba8
commit 48963f55ef
533 files changed
+6469 -9769

No files matched your search

@@ -1,13 +1,13 @@
import { moduleIntegrationTestRunner, SuiteOptions } from "medusa-test-utils"
import { moduleIntegrationTestRunner } from "medusa-test-utils"
import { ITaxModuleService } from "@medusajs/types"
import { Modules } from "@medusajs/modules-sdk"
import { setupTaxStructure } from "../utils/setup-tax-structure"
jest.setTimeout(30000)
moduleIntegrationTestRunner({
moduleIntegrationTestRunner<ITaxModuleService>({
moduleName: Modules.TAX,
testSuite: ({ service }: SuiteOptions<ITaxModuleService>) => {
testSuite: ({ service }) => {
describe("TaxModuleService", function () {
it("should create tax rates and update them", async () => {
const region = await service.createTaxRegions({
@@ -18,14 +18,14 @@ moduleIntegrationTestRunner({
},
})
const rate = await service.create({
const rate = await service.createTaxRates({
tax_region_id: region.id,
name: "Shipping Rate",
code: "test",
rate: 8.23,
})
const updatedRate = await service.update(rate.id, {
const updatedRate = await service.updateTaxRates(rate.id, {
name: "Updated Rate",
code: "TEST",
rate: 8.25,
@@ -41,7 +41,7 @@ moduleIntegrationTestRunner({
})
)
const updatedDefaultRate = await service.update(
const updatedDefaultRate = await service.updateTaxRates(
{ tax_region_id: region.id, is_default: true },
{ rate: 2 }
)
@@ -56,7 +56,7 @@ moduleIntegrationTestRunner({
}),
])
const rates = await service.list()
const rates = await service.listTaxRates()
expect(rates).toEqual(
expect.arrayContaining([
expect.objectContaining({
@@ -85,14 +85,14 @@ moduleIntegrationTestRunner({
},
})
const rate = await service.create({
const rate = await service.createTaxRates({
tax_region_id: region.id,
name: "Shipping Rate",
code: "test",
rate: 8.23,
})
await service.update(rate.id, {
await service.updateTaxRates(rate.id, {
name: "Updated Rate",
code: "TEST",
rate: 8.25,
@@ -117,7 +117,7 @@ moduleIntegrationTestRunner({
])
)
await service.update(rate.id, {
await service.updateTaxRates(rate.id, {
rules: [
{ reference: "product", reference_id: "product_id_1" },
{ reference: "product", reference_id: "product_id_2" },
@@ -198,7 +198,7 @@ moduleIntegrationTestRunner({
])
)
const rates = await service.list()
const rates = await service.listTaxRates()
expect(rates).toEqual(
expect.arrayContaining([
expect.objectContaining({
@@ -228,7 +228,7 @@ moduleIntegrationTestRunner({
},
])
const rate = await service.create({
const rate = await service.createTaxRates({
tax_region_id: region.id,
name: "Shipping Rate",
rate: 8.23,
@@ -453,16 +453,16 @@ moduleIntegrationTestRunner({
country_code: "US",
})
const taxRate = await service.create({
const taxRate = await service.createTaxRates({
tax_region_id: region.id,
value: 10,
code: "test",
name: "test",
})
await service.delete(taxRate.id)
await service.deleteTaxRates(taxRate.id)
const rates = await service.list({ tax_region_id: region.id })
const rates = await service.listTaxRates({ tax_region_id: region.id })
expect(rates).toEqual([])
})
@@ -472,16 +472,16 @@ moduleIntegrationTestRunner({
country_code: "US",
})
const taxRate = await service.create({
const taxRate = await service.createTaxRates({
tax_region_id: region.id,
value: 10,
code: "test",
name: "test",
})
await service.softDelete([taxRate.id])
await service.softDeleteTaxRates([taxRate.id])
const rates = await service.list(
const rates = await service.listTaxRates(
{ tax_region_id: region.id },
{ withDeleted: true }
)
@@ -504,7 +504,7 @@ moduleIntegrationTestRunner({
},
})
await service.create({
await service.createTaxRates({
tax_region_id: region.id,
value: 10,
code: "test",
@@ -514,7 +514,7 @@ moduleIntegrationTestRunner({
await service.deleteTaxRegions(region.id)
const taxRegions = await service.listTaxRegions()
const rates = await service.list()
const rates = await service.listTaxRates()
expect(taxRegions).toEqual([])
expect(rates).toEqual([])
@@ -530,7 +530,7 @@ moduleIntegrationTestRunner({
},
})
await service.create({
await service.createTaxRates({
tax_region_id: region.id,
value: 10,
code: "test",
@@ -543,7 +543,7 @@ moduleIntegrationTestRunner({
{},
{ withDeleted: true }
)
const rates = await service.list({}, { withDeleted: true })
const rates = await service.listTaxRates({}, { withDeleted: true })
expect(taxRegions).toEqual([
expect.objectContaining({
@@ -567,7 +567,7 @@ moduleIntegrationTestRunner({
country_code: "US",
})
const rate = await service.create({
const rate = await service.createTaxRates({
tax_region_id: region.id,
value: 10,
code: "test",
@@ -578,10 +578,10 @@ moduleIntegrationTestRunner({
],
})
await service.delete(rate.id)
await service.deleteTaxRates(rate.id)
const taxRegions = await service.listTaxRegions()
const rates = await service.list()
const rates = await service.listTaxRates()
const rules = await service.listTaxRateRules()
expect(taxRegions).toEqual([expect.objectContaining({ id: region.id })])
@@ -594,7 +594,7 @@ moduleIntegrationTestRunner({
country_code: "US",
})
const rate = await service.create({
const rate = await service.createTaxRates({
tax_region_id: region.id,
value: 10,
code: "test",
@@ -605,13 +605,13 @@ moduleIntegrationTestRunner({
],
})
await service.softDelete(rate.id)
await service.softDeleteTaxRates(rate.id)
const taxRegions = await service.listTaxRegions(
{},
{ withDeleted: true }
)
const rates = await service.list({}, { withDeleted: true })
const rates = await service.listTaxRates({}, { withDeleted: true })
const rules = await service.listTaxRateRules({}, { withDeleted: true })
expect(taxRegions).toEqual([
@@ -640,7 +640,7 @@ moduleIntegrationTestRunner({
country_code: "US",
})
const rate = await service.create({
const rate = await service.createTaxRates({
tax_region_id: region.id,
value: 10,
code: "test",
@@ -676,7 +676,7 @@ moduleIntegrationTestRunner({
])
)
const rateWithRules = await service.retrieve(rate.id, {
const rateWithRules = await service.retrieveTaxRate(rate.id, {
relations: ["rules"],
})
expect(rateWithRules.rules.length).toBe(1)
@@ -688,7 +688,7 @@ moduleIntegrationTestRunner({
reference_id: ruleOne.reference_id,
})
const rateWithRulesAfterReAdd = await service.retrieve(rate.id, {
const rateWithRulesAfterReAdd = await service.retrieveTaxRate(rate.id, {
relations: ["rules"],
})
expect(rateWithRulesAfterReAdd.rules.length).toBe(2)
@@ -700,7 +700,7 @@ moduleIntegrationTestRunner({
})
await expect(
service.create({
service.createTaxRates({
tax_region_id: region.id,
value: 10,
code: "test",
@@ -714,7 +714,7 @@ moduleIntegrationTestRunner({
/Tax rate rule with tax_rate_id: .*?, reference_id: product_id_1, already exists./
)
const rate = await service.create({
const rate = await service.createTaxRates({
tax_region_id: region.id,
value: 10,
code: "test",
@@ -790,7 +790,7 @@ moduleIntegrationTestRunner({
})
await expect(
service.create({
service.createTaxRates({
tax_region_id: rate.id,
name: "Shipping Rate",
rate: 8.23,
@@ -102,7 +102,7 @@ export const setupTaxStructure = async (service: ITaxModuleService) => {
])
const [calProd, calType, deType, canProd, canType, qcType] =
await service.create([
await service.createTaxRates([
{
tax_region_id: cal.id,
name: "CA Reduced Rate for Products",
+1 -4
View File
@@ -8,10 +8,7 @@
"dist"
],
"engines": {
"node": ">=16"
},
"bin": {
"medusa-tax-seed": "dist/scripts/bin/run-seed.js"
"node": ">=20"
},
"repository": {
"type": "git",
+10 -3
View File
@@ -1,6 +1,13 @@
import { moduleDefinition } from "./module-definition"
import { ModuleExports } from "@medusajs/types"
import { TaxModuleService } from "@services"
import loadProviders from "./loaders/providers"
export * from "./models"
export * from "./services"
const service = TaxModuleService
const loaders = [loadProviders]
export const moduleDefinition: ModuleExports = {
service,
loaders,
}
export default moduleDefinition
+8 -54
View File
@@ -1,57 +1,11 @@
import { Modules } from "@medusajs/modules-sdk"
import { ModuleJoinerConfig } from "@medusajs/types"
import { MapToConfig } from "@medusajs/utils"
import { TaxProvider, TaxRate, TaxRateRule, TaxRegion } from "@models"
import {
buildEntitiesNameToLinkableKeysMap,
defineJoinerConfig,
MapToConfig,
} from "@medusajs/utils"
export const LinkableKeys: Record<string, string> = {
tax_rate_id: TaxRate.name,
tax_region_id: TaxRegion.name,
tax_rate_rule_id: TaxRateRule.name,
tax_provider_id: TaxProvider.name,
}
export const joinerConfig = defineJoinerConfig(Modules.TAX)
const entityLinkableKeysMap: MapToConfig = {}
Object.entries(LinkableKeys).forEach(([key, value]) => {
entityLinkableKeysMap[value] ??= []
entityLinkableKeysMap[value].push({
mapTo: key,
valueFrom: key.split("_").pop()!,
})
})
export const entityNameToLinkableKeysMap: MapToConfig = entityLinkableKeysMap
export const joinerConfig: ModuleJoinerConfig = {
serviceName: Modules.TAX,
primaryKeys: ["id"],
linkableKeys: LinkableKeys,
alias: [
{
name: ["tax_rate", "tax_rates"],
args: {
entity: TaxRate.name,
},
},
{
name: ["tax_region", "tax_regions"],
args: {
entity: TaxRegion.name,
methodSuffix: "TaxRegions",
},
},
{
name: ["tax_rate_rule", "tax_rate_rules"],
args: {
entity: TaxRateRule.name,
methodSuffix: "TaxRateRules",
},
},
{
name: ["tax_provider", "tax_providers"],
args: {
entity: TaxProvider.name,
methodSuffix: "TaxProviders",
},
},
],
} as ModuleJoinerConfig
export const entityNameToLinkableKeysMap: MapToConfig =
buildEntitiesNameToLinkableKeysMap(joinerConfig.linkableKeys)
@@ -1,11 +0,0 @@
import { ModuleExports } from "@medusajs/types"
import { TaxModuleService } from "@services"
import loadProviders from "./loaders/providers"
const service = TaxModuleService
const loaders = [loadProviders]
export const moduleDefinition: ModuleExports = {
service,
loaders,
}
@@ -1,29 +0,0 @@
#!/usr/bin/env node
import { Modules } from "@medusajs/modules-sdk"
import { ModulesSdkUtils } from "@medusajs/utils"
import * as Models from "@models"
import { EOL } from "os"
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-tax-seed <filePath>`
)
}
const run = ModulesSdkUtils.buildSeedScript({
moduleName: Modules.TAX,
models: Models,
pathToMigrations: __dirname + "/../../migrations",
seedHandler: async ({ manager, data }) => {
// TODO: Add seed logic
},
})
await run({ path })
})()
@@ -31,35 +31,28 @@ type InjectedDependencies = {
[key: `tp_${string}`]: ITaxProvider
}
const generateForModels = { TaxRegion, TaxRateRule, TaxProvider }
const generateForModels = { TaxRate, TaxRegion, TaxRateRule, TaxProvider }
type ItemWithRates = {
rates: TaxRate[]
item: TaxTypes.TaxableItemDTO | TaxTypes.TaxableShippingDTO
}
export default class TaxModuleService<
TTaxRate extends TaxRate = TaxRate,
TTaxRegion extends TaxRegion = TaxRegion,
TTaxRateRule extends TaxRateRule = TaxRateRule,
TTaxProvider extends TaxProvider = TaxProvider
>
extends ModulesSdkUtils.MedusaService<
TaxTypes.TaxRateDTO,
{
TaxRegion: { dto: TaxTypes.TaxRegionDTO }
TaxRateRule: { dto: TaxTypes.TaxRateRuleDTO }
TaxProvider: { dto: TaxTypes.TaxProviderDTO }
}
>(TaxRate, generateForModels, entityNameToLinkableKeysMap)
export default class TaxModuleService
extends ModulesSdkUtils.MedusaService<{
TaxRate: { dto: TaxTypes.TaxRateDTO }
TaxRegion: { dto: TaxTypes.TaxRegionDTO }
TaxRateRule: { dto: TaxTypes.TaxRateRuleDTO }
TaxProvider: { dto: TaxTypes.TaxProviderDTO }
}>(generateForModels, entityNameToLinkableKeysMap)
implements ITaxModuleService
{
protected readonly container_: InjectedDependencies
protected baseRepository_: DAL.RepositoryService
protected taxRateService_: ModulesSdkTypes.IMedusaInternalService<TTaxRate>
protected taxRegionService_: ModulesSdkTypes.IMedusaInternalService<TTaxRegion>
protected taxRateRuleService_: ModulesSdkTypes.IMedusaInternalService<TTaxRateRule>
protected taxProviderService_: ModulesSdkTypes.IMedusaInternalService<TTaxProvider>
protected taxRateService_: ModulesSdkTypes.IMedusaInternalService<TaxRate>
protected taxRegionService_: ModulesSdkTypes.IMedusaInternalService<TaxRegion>
protected taxRateRuleService_: ModulesSdkTypes.IMedusaInternalService<TaxRateRule>
protected taxProviderService_: ModulesSdkTypes.IMedusaInternalService<TaxProvider>
constructor(
{
@@ -86,28 +79,29 @@ export default class TaxModuleService<
return joinerConfig
}
async create(
// @ts-expect-error
async createTaxRates(
data: TaxTypes.CreateTaxRateDTO[],
sharedContext?: Context
): Promise<TaxTypes.TaxRateDTO[]>
async create(
async createTaxRates(
data: TaxTypes.CreateTaxRateDTO,
sharedContext?: Context
): Promise<TaxTypes.TaxRateDTO>
@InjectManager("baseRepository_")
async create(
async createTaxRates(
data: TaxTypes.CreateTaxRateDTO[] | TaxTypes.CreateTaxRateDTO,
@MedusaContext() sharedContext: Context = {}
): Promise<TaxTypes.TaxRateDTO[] | TaxTypes.TaxRateDTO> {
const input = Array.isArray(data) ? data : [data]
const rates = await this.create_(input, sharedContext)
const rates = await this.createTaxRates_(input, sharedContext)
return Array.isArray(data) ? rates : rates[0]
}
@InjectTransactionManager("baseRepository_")
protected async create_(
protected async createTaxRates_(
data: TaxTypes.CreateTaxRateDTO[],
@MedusaContext() sharedContext: Context = {}
) {
@@ -152,29 +146,30 @@ export default class TaxModuleService<
})
}
async update(
// @ts-expect-error
async updateTaxRates(
id: string,
data: TaxTypes.UpdateTaxRateDTO,
sharedContext?: Context
): Promise<TaxTypes.TaxRateDTO>
async update(
async updateTaxRates(
ids: string[],
data: TaxTypes.UpdateTaxRateDTO,
sharedContext?: Context
): Promise<TaxTypes.TaxRateDTO[]>
async update(
async updateTaxRates(
selector: TaxTypes.FilterableTaxRateProps,
data: TaxTypes.UpdateTaxRateDTO,
sharedContext?: Context
): Promise<TaxTypes.TaxRateDTO[]>
@InjectManager("baseRepository_")
async update(
async updateTaxRates(
selector: string | string[] | TaxTypes.FilterableTaxRateProps,
data: TaxTypes.UpdateTaxRateDTO,
@MedusaContext() sharedContext: Context = {}
): Promise<TaxTypes.TaxRateDTO | TaxTypes.TaxRateDTO[]> {
const rates = await this.update_(selector, data, sharedContext)
const rates = await this.updateTaxRates_(selector, data, sharedContext)
const serialized = await this.baseRepository_.serialize<
TaxTypes.TaxRateDTO[]
>(rates, { populate: true })
@@ -182,7 +177,7 @@ export default class TaxModuleService<
}
@InjectTransactionManager("baseRepository_")
protected async update_(
protected async updateTaxRates_(
idOrSelector: string | string[] | TaxTypes.FilterableTaxRateProps,
data: TaxTypes.UpdateTaxRateDTO,
@MedusaContext() sharedContext: Context = {}
@@ -271,17 +266,17 @@ export default class TaxModuleService<
return rates.map((r) => r.id)
}
async upsert(
async upsertTaxRates(
data: TaxTypes.UpsertTaxRateDTO[],
sharedContext?: Context
): Promise<TaxTypes.TaxRateDTO[]>
async upsert(
async upsertTaxRates(
data: TaxTypes.UpsertTaxRateDTO,
sharedContext?: Context
): Promise<TaxTypes.TaxRateDTO>
@InjectTransactionManager("baseRepository_")
async upsert(
async upsertTaxRates(
data: TaxTypes.UpsertTaxRateDTO | TaxTypes.UpsertTaxRateDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<TaxTypes.TaxRateDTO | TaxTypes.TaxRateDTO[]> {
@@ -340,7 +335,7 @@ export default class TaxModuleService<
.filter(Boolean) as TaxTypes.CreateTaxRateDTO[]
if (rates.length !== 0) {
await this.create(rates, sharedContext)
await this.createTaxRates(rates, sharedContext)
}
return await this.baseRepository_.serialize<TaxTypes.TaxRegionDTO[]>(
@@ -419,7 +414,7 @@ export default class TaxModuleService<
const toReturn = await promiseAll(
items.map(async (item) => {
const regionIds = regions.map((r) => r.id)
const rateQuery = this.getTaxRateQueryForItem(item, regionIds)
const rateQuery = this.geTaxRateQueryForItem(item, regionIds)
const candidateRates = await this.taxRateService_.list(
rateQuery,
{
@@ -428,7 +423,7 @@ export default class TaxModuleService<
sharedContext
)
const applicableRates = await this.getTaxRatesForItem(
const applicableRates = await this.geTaxRatesForItem(
item,
candidateRates
)
@@ -580,10 +575,10 @@ export default class TaxModuleService<
}
}
private async getTaxRatesForItem(
private async geTaxRatesForItem(
item: TaxTypes.TaxableItemDTO | TaxTypes.TaxableShippingDTO,
rates: TTaxRate[]
): Promise<TTaxRate[]> {
rates: TaxRate[]
): Promise<TaxRate[]> {
if (!rates.length) {
return []
}
@@ -612,7 +607,7 @@ export default class TaxModuleService<
return ratesToReturn
}
private getTaxRateQueryForItem(
private geTaxRateQueryForItem(
item: TaxTypes.TaxableItemDTO | TaxTypes.TaxableShippingDTO,
regionIds: string[]
) {
@@ -644,7 +639,7 @@ export default class TaxModuleService<
}
private checkRuleMatches(
rate: TTaxRate,
rate: TaxRate,
item: TaxTypes.TaxableItemDTO | TaxTypes.TaxableShippingDTO
) {
if (rate.rules.length === 0) {
@@ -684,12 +679,10 @@ export default class TaxModuleService<
}
private prioritizeRates(
rates: TTaxRate[],
rates: TaxRate[],
item: TaxTypes.TaxableItemDTO | TaxTypes.TaxableShippingDTO
) {
const decoratedRates: (TTaxRate & {
priority_score: number
})[] = rates.map((rate) => {
const decoratedRates = rates.map((rate) => {
const { isProductMatch, isProductTypeMatch, isShippingMatch } =
this.checkRuleMatches(rate, item)
@@ -715,7 +708,9 @@ export default class TaxModuleService<
decoratedRate.priority_score = 6
}
return decoratedRate
})
}) as (TaxRate & {
priority_score: number
})[]
return decoratedRates.sort(
(a, b) => (a as any).priority_score - (b as any).priority_score