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 13:02:16 +00:00
committed by GitHub
co-authored by Stevche Radevski Oli Juhl
parent 2895ccfba8
commit 48963f55ef
533 changed files with 6469 additions and 9769 deletions
@@ -1,40 +0,0 @@
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { SalesChannel } from "@models"
const salesChannelData = [
{
id: "channel-1",
name: "Channel 1",
description: "Channel description 1",
is_disabled: false,
},
{
id: "channel-2",
name: "Channel 2",
description: "Channel description 2",
is_disabled: false,
},
{
id: "channel-3",
name: "Channel 3",
description: "Channel description 3",
is_disabled: true,
},
]
export async function createSalesChannels(
manager: SqlEntityManager,
channelData: any[] = salesChannelData
): Promise<SalesChannel[]> {
const channels: SalesChannel[] = []
for (let data of channelData) {
const sc = manager.create(SalesChannel, data)
channels.push(sc)
}
await manager.persistAndFlush(channels)
return channels
}
@@ -1,46 +1,48 @@
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { ISalesChannelModuleService } from "@medusajs/types"
import { createSalesChannels } from "../../__fixtures__"
import { moduleIntegrationTestRunner, SuiteOptions } from "medusa-test-utils"
import { Modules } from "@medusajs/modules-sdk"
jest.setTimeout(30000)
moduleIntegrationTestRunner({
const salesChannelData = [
{
id: "channel-1",
name: "Channel 1",
description: "Channel description 1",
is_disabled: false,
},
{
id: "channel-2",
name: "Channel 2",
description: "Channel description 2",
is_disabled: false,
},
{
id: "channel-3",
name: "Channel 3",
description: "Channel description 3",
is_disabled: true,
},
]
moduleIntegrationTestRunner<ISalesChannelModuleService>({
moduleName: Modules.SALES_CHANNEL,
testSuite: ({
MikroOrmWrapper,
medusaApp,
}: SuiteOptions<ISalesChannelModuleService>) => {
let service: ISalesChannelModuleService
beforeEach(() => {
service = medusaApp.modules[Modules.SALES_CHANNEL]
})
testSuite: ({ service }) => {
describe("Sales Channel Service", () => {
let testManager: SqlEntityManager
let repositoryManager: SqlEntityManager
beforeEach(async () => {
repositoryManager = await MikroOrmWrapper.forkManager()
testManager = await MikroOrmWrapper.forkManager()
await createSalesChannels(testManager)
await service.createSalesChannels(salesChannelData)
})
describe("create", () => {
it("should create a SalesChannel successfully", async () => {
const [created] = await service.create([
const [created] = await service.createSalesChannels([
{
name: "test",
description: "test",
},
])
const [channel] = await service.list({
const [channel] = await service.listSalesChannels({
name: [created.name],
})
@@ -53,7 +55,7 @@ moduleIntegrationTestRunner({
const id = "channel-1"
it("should return SalesChannel for the given id", async () => {
const result = await service.retrieve(id)
const result = await service.retrieveSalesChannel(id)
expect(result).toEqual(
expect.objectContaining({
@@ -66,7 +68,7 @@ moduleIntegrationTestRunner({
let error
try {
await service.retrieve("does-not-exist")
await service.retrieveSalesChannel("does-not-exist")
} catch (e) {
error = e
}
@@ -81,12 +83,12 @@ moduleIntegrationTestRunner({
const id = "channel-2"
it("should update the name of the SalesChannel successfully", async () => {
await service.update(id, {
await service.updateSalesChannels(id, {
name: "Update name 2",
is_disabled: true,
})
const channel = await service.retrieve(id)
const channel = await service.retrieveSalesChannel(id)
expect(channel.name).toEqual("Update name 2")
expect(channel.is_disabled).toEqual(true)
@@ -96,7 +98,7 @@ moduleIntegrationTestRunner({
let error
try {
await service.update("does-not-exist", {
await service.updateSalesChannels("does-not-exist", {
name: "does-not-exist",
})
} catch (e) {
@@ -111,7 +113,7 @@ moduleIntegrationTestRunner({
describe("list", () => {
it("should return a list of SalesChannels", async () => {
const result = await service.list()
const result = await service.listSalesChannels()
expect(result).toEqual([
expect.objectContaining({
@@ -127,7 +129,7 @@ moduleIntegrationTestRunner({
})
it("should list SalesChannels by name", async () => {
const result = await service.list({
const result = await service.listSalesChannels({
name: ["Channel 2", "Channel 3"],
})
@@ -144,7 +146,7 @@ moduleIntegrationTestRunner({
describe("listAndCount", () => {
it("should return sales channels and count", async () => {
const [result, count] = await service.listAndCount()
const [result, count] = await service.listAndCountSalesChannels()
expect(count).toEqual(3)
expect(result).toEqual([
@@ -161,7 +163,7 @@ moduleIntegrationTestRunner({
})
it("should return sales channels and count when filtered", async () => {
const [result, count] = await service.listAndCount({
const [result, count] = await service.listAndCountSalesChannels({
id: ["channel-2"],
})
@@ -174,7 +176,7 @@ moduleIntegrationTestRunner({
})
it("should return sales channels and count when using skip and take", async () => {
const [results, count] = await service.listAndCount(
const [results, count] = await service.listAndCountSalesChannels(
{},
{ skip: 1, take: 1 }
)
@@ -188,7 +190,7 @@ moduleIntegrationTestRunner({
})
it("should return requested fields", async () => {
const [result, count] = await service.listAndCount(
const [result, count] = await service.listAndCountSalesChannels(
{},
{
take: 1,
@@ -208,7 +210,7 @@ moduleIntegrationTestRunner({
})
it("should filter disabled channels", async () => {
const [result, count] = await service.listAndCount(
const [result, count] = await service.listAndCountSalesChannels(
{ is_disabled: true },
{ select: ["id"] }
)
@@ -228,9 +230,9 @@ moduleIntegrationTestRunner({
const id = "channel-2"
it("should delete the SalesChannel given an id successfully", async () => {
await service.delete([id])
await service.deleteSalesChannels([id])
const result = await service.list({
const result = await service.listSalesChannels({
id: [id],
})
@@ -1,6 +0,0 @@
if (typeof process.env.DB_TEMP_NAME === "undefined") {
const tempName = parseInt(process.env.JEST_WORKER_ID || "1")
process.env.DB_TEMP_NAME = `medusa-sales-channel-integration-${tempName}`
}
process.env.MEDUSA_SALES_CHANNEL_DB_SCHEMA = "public"
@@ -1,3 +0,0 @@
import { JestUtils } from "medusa-test-utils"
JestUtils.afterAllHookDropDatabase()
@@ -1,6 +0,0 @@
import { ModuleServiceInitializeOptions } from "@medusajs/types"
export const databaseOptions: ModuleServiceInitializeOptions["database"] = {
schema: "public",
clientUrl: "medusa-sales-channel-test",
}
@@ -1,18 +0,0 @@
import {TestDatabaseUtils} from "medusa-test-utils"
import * as SalesChannelModels from "@models"
const pathToMigrations = "../../src/migrations"
const mikroOrmEntities = SalesChannelModels as unknown as any[]
export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper({
mikroOrmEntities,
pathToMigrations,
})
export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig({
mikroOrmEntities,
pathToMigrations,
})
export const DB_URL = TestDatabaseUtils.getDatabaseURL()
@@ -1 +0,0 @@
export * from "./database"
@@ -17,6 +17,4 @@ module.exports = {
testEnvironment: `node`,
moduleFileExtensions: [`js`, `ts`],
modulePathIgnorePatterns: ["dist/"],
setupFiles: ["<rootDir>/integration-tests/setup-env.js"],
setupFilesAfterEnv: ["<rootDir>/integration-tests/setup.js"],
}
+1 -4
View File
@@ -8,10 +8,7 @@
"dist"
],
"engines": {
"node": ">=16"
},
"bin": {
"medusa-sales-channel-seed": "dist/scripts/bin/run-seed.js"
"node": ">=20"
},
"repository": {
"type": "git",
+5 -5
View File
@@ -1,7 +1,7 @@
import { moduleDefinition } from "./module-definition"
import { ModuleExports } from "@medusajs/types"
import { SalesChannelModuleService } from "@services"
const moduleDefinition: ModuleExports = {
service: SalesChannelModuleService,
}
export default moduleDefinition
export * from "./types"
export * from "./models"
export * from "./services"
@@ -1,31 +1,11 @@
import { Modules } from "@medusajs/modules-sdk"
import { ModuleJoinerConfig } from "@medusajs/types"
import { MapToConfig } from "@medusajs/utils"
import { SalesChannel } from "@models"
import {
buildEntitiesNameToLinkableKeysMap,
defineJoinerConfig,
MapToConfig,
} from "@medusajs/utils"
export const LinkableKeys = {
sales_channel_id: SalesChannel.name,
}
export const joinerConfig = defineJoinerConfig(Modules.SALES_CHANNEL)
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.SALES_CHANNEL,
primaryKeys: ["id"],
linkableKeys: LinkableKeys,
alias: [
{
name: ["sales_channel", "sales_channels"],
args: { entity: "SalesChannel" },
},
],
} as ModuleJoinerConfig
export const entityNameToLinkableKeysMap: MapToConfig =
buildEntitiesNameToLinkableKeysMap(joinerConfig.linkableKeys)
@@ -1,8 +0,0 @@
import { ModuleExports } from "@medusajs/types"
import { SalesChannelModuleService } from "@services"
const service = SalesChannelModuleService
export const moduleDefinition: ModuleExports = {
service,
}
@@ -1,31 +0,0 @@
#!/usr/bin/env node
import { ModulesSdkUtils } from "@medusajs/utils"
import { Modules } from "@medusajs/modules-sdk"
import * as ProductModels from "@models"
import { createSalesChannels } from "../seed-utils"
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-product-seed <filePath>`
)
}
const run = ModulesSdkUtils.buildSeedScript({
moduleName: Modules.PRODUCT,
models: ProductModels,
pathToMigrations: __dirname + "/../../migrations",
seedHandler: async ({ manager, data }) => {
const { salesChannelData } = data
await createSalesChannels(manager, salesChannelData)
},
})
await run({ path })
})()
@@ -1,16 +0,0 @@
import { SalesChannel } from "@models"
import { RequiredEntityData } from "@mikro-orm/core"
import { SqlEntityManager } from "@mikro-orm/postgresql"
export async function createSalesChannels(
manager: SqlEntityManager,
data: RequiredEntityData<SalesChannel>[]
) {
const channels = data.map((channel) => {
return manager.create(SalesChannel, channel)
})
await manager.persistAndFlush(channels)
return channels
}
@@ -15,7 +15,7 @@ import {
InjectTransactionManager,
isString,
MedusaContext,
ModulesSdkUtils,
MedusaService,
promiseAll,
} from "@medusajs/utils"
@@ -30,18 +30,15 @@ type InjectedDependencies = {
salesChannelService: ModulesSdkTypes.IMedusaInternalService<any>
}
export default class SalesChannelModuleService<
TEntity extends SalesChannel = SalesChannel
>
extends ModulesSdkUtils.MedusaService<SalesChannelDTO>(
SalesChannel,
{},
export default class SalesChannelModuleService
extends MedusaService<{ SalesChannel: { dto: SalesChannelDTO } }>(
{ SalesChannel },
entityNameToLinkableKeysMap
)
implements ISalesChannelModuleService
{
protected baseRepository_: DAL.RepositoryService
protected readonly salesChannelService_: ModulesSdkTypes.IMedusaInternalService<TEntity>
protected readonly salesChannelService_: ModulesSdkTypes.IMedusaInternalService<SalesChannel>
constructor(
{ baseRepository, salesChannelService }: InjectedDependencies,
@@ -57,22 +54,24 @@ export default class SalesChannelModuleService<
return joinerConfig
}
async create(
// @ts-expect-error
async createSalesChannels(
data: CreateSalesChannelDTO[],
sharedContext?: Context
): Promise<SalesChannelDTO[]>
async create(
async createSalesChannels(
data: CreateSalesChannelDTO,
sharedContext?: Context
): Promise<SalesChannelDTO>
@InjectManager("baseRepository_")
async create(
async createSalesChannels(
data: CreateSalesChannelDTO | CreateSalesChannelDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<SalesChannelDTO | SalesChannelDTO[]> {
const input = Array.isArray(data) ? data : [data]
const result = await this.create_(input, sharedContext)
const result = await this.createSalesChannels_(input, sharedContext)
return await this.baseRepository_.serialize<SalesChannelDTO[]>(
Array.isArray(data) ? result : result[0],
@@ -83,25 +82,27 @@ export default class SalesChannelModuleService<
}
@InjectTransactionManager("baseRepository_")
async create_(
async createSalesChannels_(
data: CreateSalesChannelDTO[],
@MedusaContext() sharedContext: Context
): Promise<SalesChannel[]> {
return await this.salesChannelService_.create(data, sharedContext)
}
async update(
// @ts-expect-error
async updateSalesChannels(
id: string,
data: UpdateSalesChannelDTO,
sharedContext?: Context
): Promise<SalesChannelDTO>
async update(
async updateSalesChannels(
selector: FilterableSalesChannelProps,
data: UpdateSalesChannelDTO,
sharedContext?: Context
): Promise<SalesChannelDTO[]>
@InjectManager("baseRepository_")
async update(
async updateSalesChannels(
idOrSelector: string | FilterableSalesChannelProps,
data: UpdateSalesChannelDTO | UpdateSalesChannelDTO[],
@MedusaContext() sharedContext: Context = {}
@@ -122,7 +123,10 @@ export default class SalesChannelModuleService<
}))
}
const result = await this.update_(normalizedInput, sharedContext)
const result = await this.updateSalesChannels_(
normalizedInput,
sharedContext
)
return await this.baseRepository_.serialize<SalesChannelDTO[]>(
Array.isArray(data) ? result : result[0],
@@ -133,20 +137,23 @@ export default class SalesChannelModuleService<
}
@InjectTransactionManager("baseRepository_")
async update_(data: UpdateSalesChannelDTO[], sharedContext: Context) {
async updateSalesChannels_(
data: UpdateSalesChannelDTO[],
sharedContext: Context
) {
return await this.salesChannelService_.update(data, sharedContext)
}
async upsert(
async upsertSalesChannels(
data: UpsertSalesChannelDTO[],
sharedContext?: Context
): Promise<SalesChannelDTO[]>
async upsert(
async upsertSalesChannels(
data: UpsertSalesChannelDTO,
sharedContext?: Context
): Promise<SalesChannelDTO>
@InjectTransactionManager("baseRepository_")
async upsert(
async upsertSalesChannels(
data: UpsertSalesChannelDTO | UpsertSalesChannelDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<SalesChannelDTO | SalesChannelDTO[]> {
@@ -161,10 +168,10 @@ export default class SalesChannelModuleService<
const operations: Promise<SalesChannel[]>[] = []
if (forCreate.length) {
operations.push(this.create_(forCreate, sharedContext))
operations.push(this.createSalesChannels_(forCreate, sharedContext))
}
if (forUpdate.length) {
operations.push(this.update_(forUpdate, sharedContext))
operations.push(this.updateSalesChannels_(forUpdate, sharedContext))
}
const result = (await promiseAll(operations)).flat()