chore: Abstract module service (#6188)

**What**
- Remove services that do not have any custom business and replace them with a simple interfaces
- Abstract module service provide the following base implementation
  - retrieve
  - list
  - listAndCount
  - delete
  - softDelete
  - restore

The above methods are created for the main model and also for each other models for which a config is provided

all method such as list, listAndCount, delete, softDelete and restore are pluralized with the model it refers to

**Migration**
- [x] product
- [x] pricing
- [x] promotion
- [x] cart
- [x] auth
- [x] customer
- [x] payment
- [x] Sales channel
- [x] Workflow-*


**Usage**

**Module**

The module service can now extend the ` ModulesSdkUtils.abstractModuleServiceFactory` which returns a class with the default implementation for each method and each model following the standard naming convention mentioned above.
This factory have 3 template arguments being the container, the main model DTO and an object representing the other model with a config object that contains at list the DTO and optionally a singular and plural property in case it needs to be set manually. It looks like the following:

```ts
export default class PricingModuleService</* ... */>
  extends ModulesSdkUtils.abstractModuleServiceFactory<
    InjectedDependencies,
    PricingTypes.PriceSetDTO,
    {
      Currency: { dto: PricingTypes.CurrencyDTO }
      MoneyAmount: { dto: PricingTypes.MoneyAmountDTO }
      PriceSetMoneyAmount: { dto: PricingTypes.PriceSetMoneyAmountDTO }
      PriceSetMoneyAmountRules: {
        dto: PricingTypes.PriceSetMoneyAmountRulesDTO
      }
      PriceRule: { dto: PricingTypes.PriceRuleDTO }
      RuleType: { dto: PricingTypes.RuleTypeDTO }
      PriceList: { dto: PricingTypes.PriceListDTO }
      PriceListRule: { dto: PricingTypes.PriceListRuleDTO }
    }
  >(PriceSet, generateMethodForModels, entityNameToLinkableKeysMap)
  implements PricingTypes.IPricingModuleService
{
// ...
}
```

In the above, the singular and plural can be inferred as there is no tricky naming. Also, the default implementation does not remove the fact that you need to provides all the overloads etc in your module service interface. The above will provide a default implementation following the interface `AbstractModuleService` which is also auto generated, hence you will have the following methods available:

**for the main model**
- list
- retrieve
- listAndCount 
- delete
- softDelete
- restore


**for the other models**
- list**MyModels**
- retrieve**MyModel**
- listAndCount**MyModels**
- delete**MyModels**
- softDelete**MyModels**
- restore**MyModels**

**Internal module service**

The internal module service can now extend `ModulesSdkUtils.internalModuleServiceFactory` which takes only one template argument which is the container type. 
All internal services provides a default implementation for all retrieve, list, listAndCount, create, update, delete, softDelete, restore methods which follow the following interface `ModulesSdkTypes.InternalModuleService`:

```ts
export interface InternalModuleService<
  TEntity extends {},
  TContainer extends object = object
> {
  get __container__(): TContainer

  retrieve(
    idOrObject: string,
    config?: FindConfig<any>,
    sharedContext?: Context
  ): Promise<TEntity>
  retrieve(
    idOrObject: object,
    config?: FindConfig<any>,
    sharedContext?: Context
  ): Promise<TEntity>

  list(
    filters?: FilterQuery<any> | BaseFilterable<FilterQuery<any>>,
    config?: FindConfig<any>,
    sharedContext?: Context
  ): Promise<TEntity[]>

  listAndCount(
    filters?: FilterQuery<any> | BaseFilterable<FilterQuery<any>>,
    config?: FindConfig<any>,
    sharedContext?: Context
  ): Promise<[TEntity[], number]>

  create(data: any[], sharedContext?: Context): Promise<TEntity[]>
  create(data: any, sharedContext?: Context): Promise<TEntity>

  update(data: any[], sharedContext?: Context): Promise<TEntity[]>
  update(data: any, sharedContext?: Context): Promise<TEntity>
  update(
    selectorAndData: {
      selector: FilterQuery<any> | BaseFilterable<FilterQuery<any>>
      data: any
    },
    sharedContext?: Context
  ): Promise<TEntity[]>
  update(
    selectorAndData: {
      selector: FilterQuery<any> | BaseFilterable<FilterQuery<any>>
      data: any
    }[],
    sharedContext?: Context
  ): Promise<TEntity[]>

  delete(idOrSelector: string, sharedContext?: Context): Promise<void>
  delete(idOrSelector: string[], sharedContext?: Context): Promise<void>
  delete(idOrSelector: object, sharedContext?: Context): Promise<void>
  delete(idOrSelector: object[], sharedContext?: Context): Promise<void>
  delete(
    idOrSelector: {
      selector: FilterQuery<any> | BaseFilterable<FilterQuery<any>>
    },
    sharedContext?: Context
  ): Promise<void>

  softDelete(
    idsOrFilter: string[] | InternalFilterQuery,
    sharedContext?: Context
  ): Promise<[TEntity[], Record<string, unknown[]>]>

  restore(
    idsOrFilter: string[] | InternalFilterQuery,
    sharedContext?: Context
  ): Promise<[TEntity[], Record<string, unknown[]>]>

  upsert(data: any[], sharedContext?: Context): Promise<TEntity[]>
  upsert(data: any, sharedContext?: Context): Promise<TEntity>
}
```

When a service is auto generated you can use that interface to type your class property representing the expected internal service.

**Repositories**

The repositories can now extend `DALUtils.mikroOrmBaseRepositoryFactory` which takes one template argument being the entity or the template entity and provides all the default implementation. If the repository is auto generated you can type it using the `RepositoryService` interface. Here is the new interface typings.

```ts
export interface RepositoryService<T = any> extends BaseRepositoryService<T> {
  find(options?: FindOptions<T>, context?: Context): Promise<T[]>

  findAndCount(
    options?: FindOptions<T>,
    context?: Context
  ): Promise<[T[], number]>

  create(data: any[], context?: Context): Promise<T[]>

  // Becareful here, if you have a custom internal service, the update data should never be the entity otherwise
 // both entity and update will point to the same ref and create issues with mikro orm
  update(data: { entity; update }[], context?: Context): Promise<T[]>

  delete(
    idsOrPKs: FilterQuery<T> & BaseFilterable<FilterQuery<T>>,
    context?: Context
  ): Promise<void>

  /**
   * Soft delete entities and cascade to related entities if configured.
   *
   * @param idsOrFilter
   * @param context
   *
   * @returns [T[], Record<string, string[]>] the second value being the map of the entity names and ids that were soft deleted
   */
  softDelete(
    idsOrFilter: string[] | InternalFilterQuery,
    context?: Context
  ): Promise<[T[], Record<string, unknown[]>]>

  restore(
    idsOrFilter: string[] | InternalFilterQuery,
    context?: Context
  ): Promise<[T[], Record<string, unknown[]>]>

  upsert(data: any[], context?: Context): Promise<T[]>
}
```
This commit is contained in:
Adrien de Peretti
2024-02-02 15:20:32 +01:00
committed by GitHub
parent abc30517cb
commit a7be5d7b6d
163 changed files with 2867 additions and 5080 deletions

View File

@@ -1,6 +1,5 @@
import { Currency } from "@models"
import { CurrencyService } from "@services"
import { asClass, asValue, createContainer } from "awilix"
import { asValue } from "awilix"
;(Currency as any).meta = {
/**
@@ -10,10 +9,7 @@ import { asClass, asValue, createContainer } from "awilix"
}
export const nonExistingCurrencyCode = "non-existing-code"
export const mockContainer = createContainer()
mockContainer.register({
transaction: asValue(async (task) => await task()),
export const currencyRepositoryMock = {
currencyRepository: asValue({
find: jest.fn().mockImplementation(async ({ where: { code } }) => {
if (code === nonExistingCurrencyCode) {
@@ -25,5 +21,4 @@ mockContainer.register({
findAndCount: jest.fn().mockResolvedValue([[], 0]),
getFreshManager: jest.fn().mockResolvedValue({}),
}),
currencyService: asClass(CurrencyService),
})
}

View File

@@ -1,18 +1,31 @@
import {
mockContainer,
currencyRepositoryMock,
nonExistingCurrencyCode,
} from "../__fixtures__/currency"
import { createMedusaContainer } from "@medusajs/utils"
import { asValue } from "awilix"
import ContainerLoader from "../../loaders/container"
import { MedusaContainer } from "@medusajs/types"
const code = "existing-currency"
describe("Currency service", function () {
beforeEach(function () {
let container: MedusaContainer
beforeEach(async function () {
jest.clearAllMocks()
container = createMedusaContainer()
container.register("manager", asValue({}))
await ContainerLoader({ container })
container.register(currencyRepositoryMock)
})
it("should retrieve a currency", async function () {
const currencyService = mockContainer.resolve("currencyService")
const currencyRepository = mockContainer.resolve("currencyRepository")
const currencyService = container.resolve("currencyService")
const currencyRepository = container.resolve("currencyRepository")
await currencyService.retrieve(code)
@@ -33,8 +46,8 @@ describe("Currency service", function () {
})
it("should fail to retrieve a currency", async function () {
const currencyService = mockContainer.resolve("currencyService")
const currencyRepository = mockContainer.resolve("currencyRepository")
const currencyService = container.resolve("currencyService")
const currencyRepository = container.resolve("currencyRepository")
const err = await currencyService
.retrieve(nonExistingCurrencyCode)
@@ -62,8 +75,8 @@ describe("Currency service", function () {
})
it("should list currencys", async function () {
const currencyService = mockContainer.resolve("currencyService")
const currencyRepository = mockContainer.resolve("currencyRepository")
const currencyService = container.resolve("currencyService")
const currencyRepository = container.resolve("currencyRepository")
const filters = {}
const config = {
@@ -88,8 +101,8 @@ describe("Currency service", function () {
})
it("should list currencys with filters", async function () {
const currencyService = mockContainer.resolve("currencyService")
const currencyRepository = mockContainer.resolve("currencyRepository")
const currencyService = container.resolve("currencyService")
const currencyRepository = container.resolve("currencyRepository")
const filters = {
tags: {
@@ -126,8 +139,8 @@ describe("Currency service", function () {
})
it("should list currencys with filters and relations", async function () {
const currencyService = mockContainer.resolve("currencyService")
const currencyRepository = mockContainer.resolve("currencyRepository")
const currencyService = container.resolve("currencyService")
const currencyRepository = container.resolve("currencyRepository")
const filters = {
tags: {
@@ -163,9 +176,9 @@ describe("Currency service", function () {
)
})
it("should list and count the currencys with filters and relations", async function () {
const currencyService = mockContainer.resolve("currencyService")
const currencyRepository = mockContainer.resolve("currencyRepository")
it("should list and count the currencies with filters and relations", async function () {
const currencyService = container.resolve("currencyService")
const currencyRepository = container.resolve("currencyRepository")
const filters = {
tags: {

View File

@@ -1,23 +0,0 @@
import { DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { Currency } from "@models"
import { ServiceTypes } from "@types"
type InjectedDependencies = {
currencyRepository: DAL.RepositoryService
}
export default class CurrencyService<
TEntity extends Currency = Currency
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: ServiceTypes.CreateCurrencyDTO
update: ServiceTypes.UpdateCurrencyDTO
}
>(Currency)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}

View File

@@ -1,12 +1,6 @@
export { default as CurrencyService } from "./currency"
export { default as MoneyAmountService } from "./money-amount"
export { default as PriceListService } from "./price-list"
export { default as PriceListRuleService } from "./price-list-rule"
export { default as PriceListRuleValueService } from "./price-list-rule-value"
export { default as PriceRuleService } from "./price-rule"
export { default as PriceSetService } from "./price-set"
export { default as PriceSetMoneyAmountService } from "./price-set-money-amount"
export { default as PriceSetMoneyAmountRulesService } from "./price-set-money-amount-rules"
export { default as PriceSetRuleTypeService } from "./price-set-rule-type"
export { default as PricingModuleService } from "./pricing-module"
export { default as RuleTypeService } from "./rule-type"

View File

@@ -1,27 +0,0 @@
import { DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { MoneyAmount } from "@models"
import { ServiceTypes } from "@types"
type InjectedDependencies = {
moneyAmountRepository: DAL.RepositoryService
}
export default class MoneyAmountService<
TEntity extends MoneyAmount = MoneyAmount
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: ServiceTypes.CreateMoneyAmountDTO
update: ServiceTypes.UpdateMoneyAmountDTO
},
{
list: ServiceTypes.FilterableMoneyAmountProps
listAndCount: ServiceTypes.FilterableMoneyAmountProps
}
>(MoneyAmount)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}

View File

@@ -9,26 +9,32 @@ type InjectedDependencies = {
export default class PriceListRuleValueService<
TEntity extends PriceListRuleValue = PriceListRuleValue
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
update: ServiceTypes.UpdatePriceListRuleValueDTO
},
{
list: ServiceTypes.FilterablePriceListRuleValueProps
listAndCount: ServiceTypes.FilterablePriceListRuleValueProps
}
>(PriceListRuleValue)<TEntity> {
> extends ModulesSdkUtils.internalModuleServiceFactory<InjectedDependencies>(
PriceListRuleValue
)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
async create(
create(
data: ServiceTypes.CreatePriceListRuleValueDTO[],
context: Context
): Promise<TEntity[]>
create(
data: ServiceTypes.CreatePriceListRuleValueDTO,
context: Context
): Promise<TEntity>
async create(
data:
| ServiceTypes.CreatePriceListRuleValueDTO
| ServiceTypes.CreatePriceListRuleValueDTO[],
context: Context = {}
): Promise<TEntity[]> {
const priceListRuleValues = data.map((priceRuleValueData) => {
): Promise<TEntity | TEntity[]> {
const data_ = Array.isArray(data) ? data : [data]
const priceListRuleValues = data_.map((priceRuleValueData) => {
const { price_list_rule_id: priceListRuleId, ...priceRuleValue } =
priceRuleValueData

View File

@@ -9,27 +9,31 @@ type InjectedDependencies = {
export default class PriceListRuleService<
TEntity extends PriceListRule = PriceListRule
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: ServiceTypes.CreatePriceListRuleDTO
update: ServiceTypes.UpdatePriceListRuleDTO
},
{
list: ServiceTypes.FilterablePriceListRuleProps
listAndCount: ServiceTypes.FilterablePriceListRuleProps
}
>(PriceListRule)<TEntity> {
> extends ModulesSdkUtils.internalModuleServiceFactory<InjectedDependencies>(
PriceListRule
)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
async create(
create(
data: ServiceTypes.CreatePriceListRuleDTO[],
sharedContext?: Context
): Promise<TEntity[]>
create(
data: ServiceTypes.CreatePriceListRuleDTO,
sharedContext?: Context
): Promise<TEntity>
async create(
data:
| ServiceTypes.CreatePriceListRuleDTO
| ServiceTypes.CreatePriceListRuleDTO[],
context: Context = {}
): Promise<TEntity[]> {
const priceListRule = data.map((priceListRule) => {
): Promise<TEntity | TEntity[]> {
const data_ = Array.isArray(data) ? data : [data]
const priceListRule = data_.map((priceListRule) => {
const {
price_list_id: priceListId,
rule_type_id: ruleTypeId,
@@ -50,11 +54,28 @@ export default class PriceListRuleService<
return await super.create(priceListRule, context)
}
async update(
// @ts-ignore
update(
data: ServiceTypes.UpdatePriceListRuleDTO[],
context: Context
): Promise<TEntity[]>
// @ts-ignore
update(
data: ServiceTypes.UpdatePriceListRuleDTO,
context: Context
): Promise<TEntity>
// TODO add support for selector? and then rm ts ignore
// @ts-ignore
async update(
data:
| ServiceTypes.UpdatePriceListRuleDTO
| ServiceTypes.UpdatePriceListRuleDTO[],
context: Context = {}
): Promise<TEntity[]> {
const priceListRules = data.map((priceListRule) => {
): Promise<TEntity | TEntity[]> {
const data_ = Array.isArray(data) ? data : [data]
const priceListRules = data_.map((priceListRule) => {
const { price_list_id, rule_type_id, ...priceListRuleData } =
priceListRule

View File

@@ -9,32 +9,45 @@ type InjectedDependencies = {
export default class PriceListService<
TEntity extends PriceList = PriceList
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{},
{
list: ServiceTypes.FilterablePriceListProps
listAndCount: ServiceTypes.FilterablePriceListProps
}
>(PriceList)<TEntity> {
> extends ModulesSdkUtils.internalModuleServiceFactory<InjectedDependencies>(
PriceList
)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
async create(
create(
data: ServiceTypes.CreatePriceListDTO[],
sharedContext?: Context
): Promise<TEntity[]> {
const priceLists = this.normalizePriceListDate(data)
): Promise<TEntity[]>
create(
data: ServiceTypes.CreatePriceListDTO,
sharedContext?: Context
): Promise<TEntity>
async create(
data: ServiceTypes.CreatePriceListDTO | ServiceTypes.CreatePriceListDTO[],
sharedContext?: Context
): Promise<TEntity | TEntity[]> {
const data_ = Array.isArray(data) ? data : [data]
const priceLists = this.normalizePriceListDate(data_)
return await super.create(priceLists, sharedContext)
}
// @ts-ignore
update(data: any[], sharedContext?: Context): Promise<TEntity[]>
// @ts-ignore
update(data: any, sharedContext?: Context): Promise<TEntity>
// TODO: Add support for selector? and then rm ts ignore
// @ts-ignore
async update(
data: ServiceTypes.UpdatePriceListDTO[],
data: ServiceTypes.UpdatePriceListDTO | ServiceTypes.UpdatePriceListDTO[],
sharedContext?: Context
): Promise<TEntity[]> {
const priceLists = this.normalizePriceListDate(data)
): Promise<TEntity | TEntity[]> {
const data_ = Array.isArray(data) ? data : [data]
const priceLists = this.normalizePriceListDate(data_)
return await super.update(priceLists, sharedContext)
}

View File

@@ -10,26 +10,29 @@ type InjectedDependencies = {
export default class PriceRuleService<
TEntity extends PriceRule = PriceRule
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
update: ServiceTypes.UpdatePriceRuleDTO
},
{
list: ServiceTypes.FilterablePriceRuleProps
listAndCount: ServiceTypes.FilterablePriceRuleProps
}
>(PriceRule)<TEntity> {
> extends ModulesSdkUtils.internalModuleServiceFactory<InjectedDependencies>(
PriceRule
)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
async create(
create(
data: ServiceTypes.CreatePriceRuleDTO[],
sharedContext?: Context
): Promise<TEntity[]> {
const toCreate = data.map((ruleData) => {
): Promise<TEntity[]>
create(
data: ServiceTypes.CreatePriceRuleDTO,
sharedContext?: Context
): Promise<TEntity>
async create(
data: ServiceTypes.CreatePriceRuleDTO | ServiceTypes.CreatePriceRuleDTO[],
sharedContext: Context = {}
): Promise<TEntity | TEntity[]> {
const data_ = Array.isArray(data) ? data : [data]
const toCreate = data_.map((ruleData) => {
const ruleDataClone = { ...ruleData } as any
ruleDataClone.rule_type ??= ruleData.rule_type_id

View File

@@ -1,27 +0,0 @@
import { DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { PriceSetMoneyAmountRules } from "@models"
import { ServiceTypes } from "@types"
type InjectedDependencies = {
priceSetMoneyAmountRulesRepository: DAL.RepositoryService
}
export default class PriceSetMoneyAmountRulesService<
TEntity extends PriceSetMoneyAmountRules = PriceSetMoneyAmountRules
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: ServiceTypes.CreatePriceSetMoneyAmountRulesDTO
update: ServiceTypes.UpdatePriceSetMoneyAmountRulesDTO
},
{
list: ServiceTypes.FilterablePriceSetMoneyAmountRulesProps
listAndCount: ServiceTypes.FilterablePriceSetMoneyAmountRulesProps
}
>(PriceSetMoneyAmountRules)<TEntity> {
constructor({ priceSetMoneyAmountRulesRepository }: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}

View File

@@ -1,27 +0,0 @@
import { DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { PriceSetMoneyAmount } from "@models"
import { ServiceTypes } from "@types"
type InjectedDependencies = {
priceSetMoneyAmountRepository: DAL.RepositoryService
}
export default class PriceSetMoneyAmountService<
TEntity extends PriceSetMoneyAmount = PriceSetMoneyAmount
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: ServiceTypes.CreatePriceSetMoneyAmountDTO
update: ServiceTypes.UpdatePriceSetMoneyAmountDTO
},
{
list: ServiceTypes.FilterablePriceSetMoneyAmountProps
listAndCount: ServiceTypes.FilterablePriceSetMoneyAmountProps
}
>(PriceSetMoneyAmount)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}

View File

@@ -1,27 +0,0 @@
import { DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { PriceSetRuleType } from "@models"
import { ServiceTypes } from "@types"
type InjectedDependencies = {
priceSetRuleTypeRepository: DAL.RepositoryService
}
export default class PriceSetRuleTypeService<
TEntity extends PriceSetRuleType = PriceSetRuleType
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: ServiceTypes.CreatePriceSetRuleTypeDTO
update: ServiceTypes.UpdatePriceSetRuleTypeDTO
},
{
list: ServiceTypes.FilterablePriceSetRuleTypeProps
listAndCount: ServiceTypes.FilterablePriceSetRuleTypeProps
}
>(PriceSetRuleType)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}

View File

@@ -1,28 +0,0 @@
import { DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { PriceSet } from "@models"
import { ServiceTypes } from "@types"
type InjectedDependencies = {
priceSetRepository: DAL.RepositoryService
}
export default class PriceSetService<
TEntity extends PriceSet = PriceSet
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: Omit<ServiceTypes.CreatePriceSetDTO, "rules">
update: Omit<ServiceTypes.UpdatePriceSetDTO, "rules">
},
{
list: ServiceTypes.FilterablePriceSetProps
listAndCount: ServiceTypes.FilterablePriceSetProps
}
>(PriceSet)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -14,17 +14,9 @@ type InjectedDependencies = {
export default class RuleTypeService<
TEntity extends RuleType = RuleType
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: ServiceTypes.CreateRuleTypeDTO
update: ServiceTypes.UpdateRuleTypeDTO
},
{
list: ServiceTypes.FilterableRuleTypeProps
listAndCount: ServiceTypes.FilterableRuleTypeProps
}
>(RuleType)<TEntity> {
> extends ModulesSdkUtils.internalModuleServiceFactory<InjectedDependencies>(
RuleType
)<TEntity> {
protected readonly ruleTypeRepository_: DAL.RepositoryService<TEntity>
constructor({ ruleTypeRepository }: InjectedDependencies) {
@@ -33,21 +25,45 @@ export default class RuleTypeService<
this.ruleTypeRepository_ = ruleTypeRepository
}
@InjectTransactionManager("ruleTypeRepository_")
async create(
create(
data: ServiceTypes.CreateRuleTypeDTO,
sharedContext: Context
): Promise<TEntity>
create(
data: ServiceTypes.CreateRuleTypeDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<TEntity[]> {
validateRuleAttributes(data.map((d) => d.rule_attribute))
return await this.ruleTypeRepository_.create(data, sharedContext)
}
sharedContext: Context
): Promise<TEntity[]>
@InjectTransactionManager("ruleTypeRepository_")
async update(
data: ServiceTypes.UpdateRuleTypeDTO[],
async create(
data: ServiceTypes.CreateRuleTypeDTO | ServiceTypes.CreateRuleTypeDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<TEntity[]> {
validateRuleAttributes(data.map((d) => d.rule_attribute))
return await this.ruleTypeRepository_.update(data, sharedContext)
): Promise<TEntity | TEntity[]> {
const data_ = Array.isArray(data) ? data : [data]
validateRuleAttributes(data_.map((d) => d.rule_attribute))
return await super.create(data, sharedContext)
}
// @ts-ignore
update(
data: ServiceTypes.UpdateRuleTypeDTO[],
sharedContext: Context
): Promise<TEntity[]>
// @ts-ignore
update(
data: ServiceTypes.UpdateRuleTypeDTO,
sharedContext: Context
): Promise<TEntity>
@InjectTransactionManager("ruleTypeRepository_")
// TODO: add support for selector? and then rm ts ignore
// @ts-ignore
async update(
data: ServiceTypes.UpdateRuleTypeDTO | ServiceTypes.UpdateRuleTypeDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<TEntity | TEntity[]> {
const data_ = Array.isArray(data) ? data : [data]
validateRuleAttributes(data_.map((d) => d.rule_attribute))
return await super.update(data, sharedContext)
}
}

View File

@@ -1,44 +1,3 @@
import {
Currency,
MoneyAmount,
PriceList,
PriceListRule,
PriceListRuleValue,
PriceRule,
PriceSet,
PriceSetMoneyAmount,
PriceSetMoneyAmountRules,
PriceSetRuleType,
RuleType,
} from "@models"
import { DAL } from "@medusajs/types"
import { CreateCurrencyDTO, UpdateCurrencyDTO } from "./currency"
import { CreateMoneyAmountDTO, UpdateMoneyAmountDTO } from "./money-amount"
import {
CreatePriceListRuleValueDTO,
UpdatePriceListRuleValueDTO,
} from "./price-list-rule-value"
import {
CreatePriceListRuleDTO,
UpdatePriceListRuleDTO,
} from "./price-list-rule"
import { CreatePriceListDTO, UpdatePriceListDTO } from "./price-list"
import { CreatePriceRuleDTO, UpdatePriceRuleDTO } from "./price-rule"
import {
CreatePriceSetMoneyAmountRulesDTO,
UpdatePriceSetMoneyAmountRulesDTO,
} from "./price-set-money-amount-rules"
import {
CreatePriceSetMoneyAmountDTO,
UpdatePriceSetMoneyAmountDTO,
} from "./price-set-money-amount"
import {
CreatePriceSetRuleTypeDTO,
UpdatePriceSetRuleTypeDTO,
} from "./price-set-rule-type"
import { CreatePriceSetDTO, UpdatePriceSetDTO } from "./price-set"
import { CreateRuleTypeDTO, UpdateRuleTypeDTO } from "./rule-type"
export * from "./currency"
export * from "./money-amount"
export * from "./price-list-rule-value"
@@ -50,119 +9,3 @@ export * from "./price-set-money-amount"
export * from "./price-set-rule-type"
export * from "./price-set"
export * from "./rule-type"
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface ICurrencyRepository<TEntity extends Currency = Currency>
extends DAL.RepositoryService<
TEntity,
{
create: CreateCurrencyDTO
update: UpdateCurrencyDTO
}
> {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IMoneyAmountRepository<
TEntity extends MoneyAmount = MoneyAmount
> extends DAL.RepositoryService<
TEntity,
{
create: CreateMoneyAmountDTO
update: UpdateMoneyAmountDTO
}
> {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IPriceListRuleValueRepository<
TEntity extends PriceListRuleValue = PriceListRuleValue
> extends DAL.RepositoryService<
TEntity,
{
create: CreatePriceListRuleValueDTO
update: UpdatePriceListRuleValueDTO
}
> {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IPriceListRuleRepository<
TEntity extends PriceListRule = PriceListRule
> extends DAL.RepositoryService<
TEntity,
{
create: CreatePriceListRuleDTO
update: UpdatePriceListRuleDTO
}
> {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IPriceListRepository<TEntity extends PriceList = PriceList>
extends DAL.RepositoryService<
TEntity,
{
create: CreatePriceListDTO
update: UpdatePriceListDTO
}
> {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IPriceRuleRepository<TEntity extends PriceRule = PriceRule>
extends DAL.RepositoryService<
TEntity,
{
create: CreatePriceRuleDTO
update: UpdatePriceRuleDTO
}
> {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IPriceSetMoneyAmountRulesRepository<
TEntity extends PriceSetMoneyAmountRules = PriceSetMoneyAmountRules
> extends DAL.RepositoryService<
TEntity,
{
create: CreatePriceSetMoneyAmountRulesDTO
update: UpdatePriceSetMoneyAmountRulesDTO
}
> {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IPriceSetMoneyAmountRepository<
TEntity extends PriceSetMoneyAmount = PriceSetMoneyAmount
> extends DAL.RepositoryService<
TEntity,
{
create: CreatePriceSetMoneyAmountDTO
update: UpdatePriceSetMoneyAmountDTO
}
> {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IPriceSetRuleTypeRepository<
TEntity extends PriceSetRuleType = PriceSetRuleType
> extends DAL.RepositoryService<
TEntity,
{
create: CreatePriceSetRuleTypeDTO
update: UpdatePriceSetRuleTypeDTO
}
> {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IPriceSetRepository<TEntity extends PriceSet = PriceSet>
extends DAL.RepositoryService<
TEntity,
{
create: CreatePriceSetDTO
update: UpdatePriceSetDTO
}
> {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IRuleTypeRepository<TEntity extends RuleType = RuleType>
extends DAL.RepositoryService<
TEntity,
{
create: CreateRuleTypeDTO
update: UpdateRuleTypeDTO
}
> {}