Skip to content

Commit

Permalink
chore: abstract the modules repository (#6035)
Browse files Browse the repository at this point in the history
**What**
Reduce the work effort to create repositories when building new modules by abstracting the most common cases into the base class default implementation returned by a factory

- [x] Migrate all modules

Co-authored-by: Riqwan Thamir <5105988+riqwan@users.noreply.github.com>
  • Loading branch information
adrien2p and riqwan authored Jan 10, 2024
1 parent ef50249 commit b6ac768
Show file tree
Hide file tree
Showing 38 changed files with 409 additions and 2,830 deletions.
9 changes: 9 additions & 0 deletions .changeset/swift-mice-leave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@medusajs/authentication": patch
"@medusajs/link-modules": patch
"@medusajs/pricing": patch
"@medusajs/product": patch
"@medusajs/utils": patch
---

chore: Attempt to abstract the modules repository
82 changes: 6 additions & 76 deletions packages/authentication/src/repositories/auth-provider.ts
Original file line number Diff line number Diff line change
@@ -1,86 +1,16 @@
import { Context, DAL } from "@medusajs/types"
import { DALUtils } from "@medusajs/utils"
import {
FilterQuery as MikroFilterQuery,
FindOptions as MikroOptions,
LoadStrategy,
} from "@mikro-orm/core"

import { AuthProvider } from "@models"
import { RepositoryTypes } from "@types"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { Context } from "@medusajs/types"

export class AuthProviderRepository extends DALUtils.MikroOrmBaseRepository {
protected readonly manager_: SqlEntityManager

constructor({ manager }: { manager: SqlEntityManager }) {
// @ts-ignore
// eslint-disable-next-line prefer-rest-params
super(...arguments)
this.manager_ = manager
}

async find(
findOptions: DAL.FindOptions<AuthProvider> = { where: {} },
context: Context = {}
): Promise<AuthProvider[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)

const findOptions_ = { ...findOptions }
findOptions_.options ??= {}

Object.assign(findOptions_.options, {
strategy: LoadStrategy.SELECT_IN,
})

return await manager.find(
AuthProvider,
findOptions_.where as MikroFilterQuery<AuthProvider>,
findOptions_.options as MikroOptions<AuthProvider>
)
}

async findAndCount(
findOptions: DAL.FindOptions<AuthProvider> = { where: {} },
context: Context = {}
): Promise<[AuthProvider[], number]> {
const manager = this.getActiveManager<SqlEntityManager>(context)

const findOptions_ = { ...findOptions }
findOptions_.options ??= {}

Object.assign(findOptions_.options, {
strategy: LoadStrategy.SELECT_IN,
})

return await manager.findAndCount(
AuthProvider,
findOptions_.where as MikroFilterQuery<AuthProvider>,
findOptions_.options as MikroOptions<AuthProvider>
)
}

async delete(ids: string[], context: Context = {}): Promise<void> {
const manager = this.getActiveManager<SqlEntityManager>(context)
await manager.nativeDelete(AuthProvider, { provider: { $in: ids } }, {})
}

async create(
data: RepositoryTypes.CreateAuthProviderDTO[],
context: Context = {}
): Promise<AuthProvider[]> {
const manager: SqlEntityManager =
this.getActiveManager<SqlEntityManager>(context)

const authProviders = data.map((authProviderData) => {
return manager.create(AuthProvider, authProviderData)
})

manager.persist(authProviders)

return authProviders
export class AuthProviderRepository extends DALUtils.mikroOrmBaseRepositoryFactory<
AuthProvider,
{
create: RepositoryTypes.CreateAuthProviderDTO
}

>(AuthProvider, "provider") {
async update(
data: RepositoryTypes.UpdateAuthProviderDTO[],
context: Context = {}
Expand Down
76 changes: 5 additions & 71 deletions packages/authentication/src/repositories/auth-user.ts
Original file line number Diff line number Diff line change
@@ -1,77 +1,17 @@
import { Context, DAL } from "@medusajs/types"
import { Context } from "@medusajs/types"
import { DALUtils } from "@medusajs/utils"
import {
FilterQuery as MikroFilterQuery,
FindOptions as MikroOptions,
LoadStrategy,
} from "@mikro-orm/core"

import { AuthUser } from "@models"
import { RepositoryTypes } from "@types"
import { SqlEntityManager } from "@mikro-orm/postgresql"

export class AuthUserRepository extends DALUtils.MikroOrmBaseRepository {
protected readonly manager_: SqlEntityManager

constructor({ manager }: { manager: SqlEntityManager }) {
// @ts-ignore
// eslint-disable-next-line prefer-rest-params
super(...arguments)
this.manager_ = manager
}

async find(
findOptions: DAL.FindOptions<AuthUser> = { where: {} },
context: Context = {}
): Promise<AuthUser[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)

const findOptions_ = { ...findOptions }
findOptions_.options ??= {}

Object.assign(findOptions_.options, {
strategy: LoadStrategy.SELECT_IN,
})

return await manager.find(
AuthUser,
findOptions_.where as MikroFilterQuery<AuthUser>,
findOptions_.options as MikroOptions<AuthUser>
)
}

async findAndCount(
findOptions: DAL.FindOptions<AuthUser> = { where: {} },
context: Context = {}
): Promise<[AuthUser[], number]> {
const manager = this.getActiveManager<SqlEntityManager>(context)

const findOptions_ = { ...findOptions }
findOptions_.options ??= {}

Object.assign(findOptions_.options, {
strategy: LoadStrategy.SELECT_IN,
})

return await manager.findAndCount(
AuthUser,
findOptions_.where as MikroFilterQuery<AuthUser>,
findOptions_.options as MikroOptions<AuthUser>
)
}

async delete(ids: string[], context: Context = {}): Promise<void> {
const manager = this.getActiveManager<SqlEntityManager>(context)
await manager.nativeDelete(AuthUser, { id: { $in: ids } }, {})
}

export class AuthUserRepository extends DALUtils.mikroOrmBaseRepositoryFactory(
AuthUser
) {
async create(
data: RepositoryTypes.CreateAuthUserDTO[],
context: Context = {}
): Promise<AuthUser[]> {
const manager: SqlEntityManager =
this.getActiveManager<SqlEntityManager>(context)

const toCreate = data.map((authUser) => {
const authUserClone = { ...authUser } as any

Expand All @@ -80,13 +20,7 @@ export class AuthUserRepository extends DALUtils.MikroOrmBaseRepository {
return authUserClone
})

const authUsers = toCreate.map((authUserData) => {
return manager.create(AuthUser, authUserData)
})

manager.persist(authUsers)

return authUsers
return await super.create(toCreate, context)
}

async update(
Expand Down
71 changes: 8 additions & 63 deletions packages/link-modules/src/repositories/link.ts
Original file line number Diff line number Diff line change
@@ -1,77 +1,22 @@
import { Context, FindOptions, ModuleJoinerConfig } from "@medusajs/types"
import {
EntitySchema,
LoadStrategy,
FilterQuery as MikroFilterQuery,
FindOptions as MikroOptions,
} from "@mikro-orm/core"
import { Context, ModuleJoinerConfig } from "@medusajs/types"
import { EntitySchema } from "@mikro-orm/core"

import {
MikroOrmAbstractBaseRepository,
generateEntityId,
mikroOrmBaseRepositoryFactory,
} from "@medusajs/utils"
import { SqlEntityManager } from "@mikro-orm/postgresql"

export function getLinkRepository(model: EntitySchema) {
return class LinkRepository extends MikroOrmAbstractBaseRepository<object> {
readonly manager_: SqlEntityManager
readonly model_: EntitySchema
return class LinkRepository extends mikroOrmBaseRepositoryFactory(model) {
readonly joinerConfig_: ModuleJoinerConfig

constructor({
manager,
joinerConfig,
}: {
manager: SqlEntityManager
joinerConfig: ModuleJoinerConfig
}) {
constructor({ joinerConfig }: { joinerConfig: ModuleJoinerConfig }) {
// @ts-ignore
super(...arguments)
this.manager_ = manager
this.model_ = model
this.joinerConfig_ = joinerConfig
}

async find(
findOptions: FindOptions<unknown> = { where: {} },
context: Context = {}
): Promise<unknown[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)

const findOptions_ = { ...findOptions }
findOptions_.options ??= {}

Object.assign(findOptions_.options, {
strategy: LoadStrategy.SELECT_IN,
})

return await manager.find(
this.model_,
findOptions_.where as MikroFilterQuery<unknown>,
findOptions_.options as MikroOptions<any>
)
}

async findAndCount(
findOptions: FindOptions<object> = { where: {} },
context: Context = {}
): Promise<[object[], number]> {
const manager = this.getActiveManager<SqlEntityManager>(context)

const findOptions_ = { ...findOptions }
findOptions_.options ??= {}

Object.assign(findOptions_.options, {
strategy: LoadStrategy.SELECT_IN,
})

return await manager.findAndCount(
this.model_,
findOptions_.where as MikroFilterQuery<unknown>,
findOptions_.options as MikroOptions<any>
)
}

async delete(data: any, context: Context = {}): Promise<void> {
const filter = {}
for (const key in data) {
Expand All @@ -81,7 +26,7 @@ export function getLinkRepository(model: EntitySchema) {
}

const manager = this.getActiveManager<SqlEntityManager>(context)
await manager.nativeDelete(this.model_, data, {})
await manager.nativeDelete(model, data, {})
}

async create(data: object[], context: Context = {}): Promise<object[]> {
Expand All @@ -93,10 +38,10 @@ export function getLinkRepository(model: EntitySchema) {
this.joinerConfig_.databaseConfig?.idPrefix ?? "link"
)

return manager.create(this.model_, link)
return manager.create(model, link)
})

await manager.upsertMany(this.model_, links)
await manager.upsertMany(model, links)

return links
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ describe("PriceListRule Service", () => {
}

expect(error.message).toEqual(
'PriceListRule with id(s) "does-not-exist" not found'
'PriceListRule with id "does-not-exist" not found'
)
})
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ describe("PriceRule Service", () => {
error = e
}

expect(error.message).toEqual('PriceRule with id "undefined" not found')
expect(error.message).toEqual('PriceRule with id "" not found')
})

it("should create a priceRule successfully", async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ describe("PriceSet Service", () => {
error = e
}

expect(error.message).toEqual('PriceSet with id "undefined" not found')
expect(error.message).toEqual('PriceSet with id "" not found')
})

it("should create a priceSet successfully", async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ describe("PriceListRule Service", () => {
}

expect(error.message).toEqual(
'PriceListRule with id(s) "does-not-exist" not found'
'PriceListRule with id "does-not-exist" not found'
)
})
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { CreatePriceRuleDTO, IPricingModuleService } from "@medusajs/types"
import { SqlEntityManager } from "@mikro-orm/postgresql"

import { PriceSetMoneyAmount, initialize } from "../../../../src"
import { initialize, PriceSetMoneyAmount } from "../../../../src"
import { createCurrencies } from "../../../__fixtures__/currency"
import { createMoneyAmounts } from "../../../__fixtures__/money-amount"
import { createPriceRules } from "../../../__fixtures__/price-rule"
Expand Down Expand Up @@ -279,7 +279,7 @@ describe("PricingModule Service - PriceRule", () => {
error = e
}

expect(error.message).toEqual('PriceRule with id "undefined" not found')
expect(error.message).toEqual('PriceRule with id "" not found')
})

it("should create a PriceRule successfully", async () => {
Expand Down
Loading

1 comment on commit b6ac768

@vercel
Copy link

@vercel vercel bot commented on b6ac768 Jan 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

medusa-dashboard – ./packages/admin-next/dashboard

medusa-dashboard-medusajs.vercel.app
medusa-dashboard.vercel.app
medusa-dashboard-git-develop-medusajs.vercel.app
admin-preview.medusajs.com

Please sign in to comment.