feat(utils): autogenerates create and update methods when dto is provided (#6751)
what:
when you provide an optional create_dto or update_dto to the model factory types, the abstract service will generate a simple service method for the public services of the modules.
```
MoneyAmount: {
dto: PricingTypes.MoneyAmountDTO
create_dto: PricingTypes.CreateMoneyAmountDTO
}
```
In the above example, only a create method will be generated, but the update will be skipped.
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/utils": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
feat(utils): autogenerates create and update methods when dto is provided
|
||||||
@@ -94,13 +94,21 @@ export default class PricingModuleService<
|
|||||||
InjectedDependencies,
|
InjectedDependencies,
|
||||||
PricingTypes.PriceSetDTO,
|
PricingTypes.PriceSetDTO,
|
||||||
{
|
{
|
||||||
MoneyAmount: { dto: PricingTypes.MoneyAmountDTO }
|
MoneyAmount: {
|
||||||
|
dto: PricingTypes.MoneyAmountDTO
|
||||||
|
create: PricingTypes.CreateMoneyAmountDTO
|
||||||
|
update: PricingTypes.UpdateMoneyAmountDTO
|
||||||
|
}
|
||||||
PriceSetMoneyAmount: { dto: PricingTypes.PriceSetMoneyAmountDTO }
|
PriceSetMoneyAmount: { dto: PricingTypes.PriceSetMoneyAmountDTO }
|
||||||
PriceSetMoneyAmountRules: {
|
PriceSetMoneyAmountRules: {
|
||||||
dto: PricingTypes.PriceSetMoneyAmountRulesDTO
|
dto: PricingTypes.PriceSetMoneyAmountRulesDTO
|
||||||
}
|
}
|
||||||
PriceRule: { dto: PricingTypes.PriceRuleDTO }
|
PriceRule: { dto: PricingTypes.PriceRuleDTO }
|
||||||
RuleType: { dto: PricingTypes.RuleTypeDTO }
|
RuleType: {
|
||||||
|
dto: PricingTypes.RuleTypeDTO
|
||||||
|
create: PricingTypes.CreateRuleTypeDTO
|
||||||
|
update: PricingTypes.UpdateRuleTypeDTO
|
||||||
|
}
|
||||||
PriceList: { dto: PricingTypes.PriceListDTO }
|
PriceList: { dto: PricingTypes.PriceListDTO }
|
||||||
PriceListRule: { dto: PricingTypes.PriceListRuleDTO }
|
PriceListRule: { dto: PricingTypes.PriceListRuleDTO }
|
||||||
}
|
}
|
||||||
@@ -705,72 +713,6 @@ export default class PricingModuleService<
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@InjectTransactionManager("baseRepository_")
|
|
||||||
async createMoneyAmounts(
|
|
||||||
data: PricingTypes.CreateMoneyAmountDTO[],
|
|
||||||
@MedusaContext() sharedContext: Context = {}
|
|
||||||
) {
|
|
||||||
const moneyAmounts = await this.moneyAmountService_.create(
|
|
||||||
data,
|
|
||||||
sharedContext
|
|
||||||
)
|
|
||||||
|
|
||||||
return await this.baseRepository_.serialize<PricingTypes.MoneyAmountDTO[]>(
|
|
||||||
moneyAmounts,
|
|
||||||
{
|
|
||||||
populate: true,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@InjectTransactionManager("baseRepository_")
|
|
||||||
async updateMoneyAmounts(
|
|
||||||
data: PricingTypes.UpdateMoneyAmountDTO[],
|
|
||||||
@MedusaContext() sharedContext: Context = {}
|
|
||||||
) {
|
|
||||||
const moneyAmounts = await this.moneyAmountService_.update(
|
|
||||||
data,
|
|
||||||
sharedContext
|
|
||||||
)
|
|
||||||
|
|
||||||
return await this.baseRepository_.serialize<PricingTypes.MoneyAmountDTO[]>(
|
|
||||||
moneyAmounts,
|
|
||||||
{
|
|
||||||
populate: true,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@InjectTransactionManager("baseRepository_")
|
|
||||||
async createRuleTypes(
|
|
||||||
data: PricingTypes.CreateRuleTypeDTO[],
|
|
||||||
@MedusaContext() sharedContext: Context = {}
|
|
||||||
): Promise<PricingTypes.RuleTypeDTO[]> {
|
|
||||||
const ruleTypes = await this.ruleTypeService_.create(data, sharedContext)
|
|
||||||
|
|
||||||
return await this.baseRepository_.serialize<PricingTypes.RuleTypeDTO[]>(
|
|
||||||
ruleTypes,
|
|
||||||
{
|
|
||||||
populate: true,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@InjectTransactionManager("baseRepository_")
|
|
||||||
async updateRuleTypes(
|
|
||||||
data: PricingTypes.UpdateRuleTypeDTO[],
|
|
||||||
@MedusaContext() sharedContext: Context = {}
|
|
||||||
): Promise<PricingTypes.RuleTypeDTO[]> {
|
|
||||||
const ruleTypes = await this.ruleTypeService_.update(data, sharedContext)
|
|
||||||
|
|
||||||
return await this.baseRepository_.serialize<PricingTypes.RuleTypeDTO[]>(
|
|
||||||
ruleTypes,
|
|
||||||
{
|
|
||||||
populate: true,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@InjectTransactionManager("baseRepository_")
|
@InjectTransactionManager("baseRepository_")
|
||||||
async createPriceSetMoneyAmountRules(
|
async createPriceSetMoneyAmountRules(
|
||||||
data: PricingTypes.CreatePriceSetMoneyAmountRulesDTO[],
|
data: PricingTypes.CreatePriceSetMoneyAmountRulesDTO[],
|
||||||
|
|||||||
@@ -1218,6 +1218,11 @@ export interface IPricingModuleService extends IModuleService {
|
|||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
): Promise<MoneyAmountDTO[]>
|
): Promise<MoneyAmountDTO[]>
|
||||||
|
|
||||||
|
createMoneyAmounts(
|
||||||
|
data: CreateMoneyAmountDTO,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<MoneyAmountDTO>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method updates existing money amounts.
|
* This method updates existing money amounts.
|
||||||
*
|
*
|
||||||
@@ -1248,6 +1253,11 @@ export interface IPricingModuleService extends IModuleService {
|
|||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
): Promise<MoneyAmountDTO[]>
|
): Promise<MoneyAmountDTO[]>
|
||||||
|
|
||||||
|
updateMoneyAmounts(
|
||||||
|
data: UpdateMoneyAmountDTO,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<MoneyAmountDTO>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method deletes money amounts by their IDs.
|
* This method deletes money amounts by their IDs.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ import {
|
|||||||
SoftDeleteReturn,
|
SoftDeleteReturn,
|
||||||
} from "@medusajs/types"
|
} from "@medusajs/types"
|
||||||
import {
|
import {
|
||||||
|
MapToConfig,
|
||||||
isString,
|
isString,
|
||||||
kebabCase,
|
kebabCase,
|
||||||
lowerCaseFirst,
|
lowerCaseFirst,
|
||||||
mapObjectTo,
|
mapObjectTo,
|
||||||
MapToConfig,
|
|
||||||
pluralize,
|
pluralize,
|
||||||
upperCaseFirst,
|
upperCaseFirst,
|
||||||
} from "../common"
|
} from "../common"
|
||||||
@@ -33,14 +33,28 @@ type BaseMethods =
|
|||||||
| "delete"
|
| "delete"
|
||||||
| "softDelete"
|
| "softDelete"
|
||||||
| "restore"
|
| "restore"
|
||||||
|
| "create"
|
||||||
|
| "update"
|
||||||
|
|
||||||
const readMethods = ["retrieve", "list", "listAndCount"] as BaseMethods[]
|
const readMethods = ["retrieve", "list", "listAndCount"] as BaseMethods[]
|
||||||
const writeMethods = ["delete", "softDelete", "restore"] as BaseMethods[]
|
const writeMethods = [
|
||||||
|
"delete",
|
||||||
|
"softDelete",
|
||||||
|
"restore",
|
||||||
|
"create",
|
||||||
|
"update",
|
||||||
|
] as BaseMethods[]
|
||||||
|
|
||||||
const methods: BaseMethods[] = [...readMethods, ...writeMethods]
|
const methods: BaseMethods[] = [...readMethods, ...writeMethods]
|
||||||
|
|
||||||
type ModelsConfigTemplate = {
|
type ModelsConfigTemplate = {
|
||||||
[ModelName: string]: { singular?: string; plural?: string; dto: object }
|
[ModelName: string]: {
|
||||||
|
singular?: string
|
||||||
|
plural?: string
|
||||||
|
dto: object
|
||||||
|
create?: object
|
||||||
|
update?: object
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExtractSingularName<
|
type ExtractSingularName<
|
||||||
@@ -48,6 +62,20 @@ type ExtractSingularName<
|
|||||||
K = keyof T
|
K = keyof T
|
||||||
> = T[K] extends { singular?: string } ? T[K]["singular"] : K
|
> = T[K] extends { singular?: string } ? T[K]["singular"] : K
|
||||||
|
|
||||||
|
type CreateMethodName<
|
||||||
|
ModelConfig extends Record<any, any>,
|
||||||
|
ModelKey = keyof ModelConfig
|
||||||
|
> = ModelConfig[ModelKey] extends { create?: object }
|
||||||
|
? `create${ExtractPluralName<ModelConfig, ModelKey>}`
|
||||||
|
: never
|
||||||
|
|
||||||
|
type UpdateMethodName<
|
||||||
|
ModelConfig extends Record<any, any>,
|
||||||
|
ModelKey = keyof ModelConfig
|
||||||
|
> = ModelConfig[ModelKey] extends { update?: object }
|
||||||
|
? `update${ExtractPluralName<ModelConfig, ModelKey>}`
|
||||||
|
: never
|
||||||
|
|
||||||
type ExtractPluralName<T extends Record<any, any>, K = keyof T> = T[K] extends {
|
type ExtractPluralName<T extends Record<any, any>, K = keyof T> = T[K] extends {
|
||||||
plural?: string
|
plural?: string
|
||||||
}
|
}
|
||||||
@@ -100,42 +128,33 @@ export interface AbstractModuleServiceBase<TContainer, TMainModelDTO> {
|
|||||||
export type AbstractModuleService<
|
export type AbstractModuleService<
|
||||||
TContainer,
|
TContainer,
|
||||||
TMainModelDTO,
|
TMainModelDTO,
|
||||||
TOtherModelNamesAndAssociatedDTO extends ModelsConfigTemplate
|
ModelsConfig extends ModelsConfigTemplate
|
||||||
> = AbstractModuleServiceBase<TContainer, TMainModelDTO> & {
|
> = AbstractModuleServiceBase<TContainer, TMainModelDTO> & {
|
||||||
[K in keyof TOtherModelNamesAndAssociatedDTO as `retrieve${ExtractSingularName<
|
[K in keyof ModelsConfig as `retrieve${ExtractSingularName<ModelsConfig, K> &
|
||||||
TOtherModelNamesAndAssociatedDTO,
|
|
||||||
K
|
|
||||||
> &
|
|
||||||
string}`]: (
|
string}`]: (
|
||||||
id: string,
|
id: string,
|
||||||
config?: FindConfig<any>,
|
config?: FindConfig<any>,
|
||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
) => Promise<TOtherModelNamesAndAssociatedDTO[K & string]["dto"]>
|
) => Promise<ModelsConfig[K & string]["dto"]>
|
||||||
} & {
|
} & {
|
||||||
[K in keyof TOtherModelNamesAndAssociatedDTO as `list${ExtractPluralName<
|
[K in keyof ModelsConfig as `list${ExtractPluralName<ModelsConfig, K> &
|
||||||
TOtherModelNamesAndAssociatedDTO,
|
|
||||||
K
|
|
||||||
> &
|
|
||||||
string}`]: (
|
string}`]: (
|
||||||
filters?: any,
|
filters?: any,
|
||||||
config?: FindConfig<any>,
|
config?: FindConfig<any>,
|
||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
) => Promise<TOtherModelNamesAndAssociatedDTO[K & string]["dto"][]>
|
) => Promise<ModelsConfig[K & string]["dto"][]>
|
||||||
} & {
|
} & {
|
||||||
[K in keyof TOtherModelNamesAndAssociatedDTO as `listAndCount${ExtractPluralName<
|
[K in keyof ModelsConfig as `listAndCount${ExtractPluralName<
|
||||||
TOtherModelNamesAndAssociatedDTO,
|
ModelsConfig,
|
||||||
K
|
K
|
||||||
> &
|
> &
|
||||||
string}`]: {
|
string}`]: {
|
||||||
(filters?: any, config?: FindConfig<any>, sharedContext?: Context): Promise<
|
(filters?: any, config?: FindConfig<any>, sharedContext?: Context): Promise<
|
||||||
[TOtherModelNamesAndAssociatedDTO[K & string]["dto"][], number]
|
[ModelsConfig[K & string]["dto"][], number]
|
||||||
>
|
>
|
||||||
}
|
}
|
||||||
} & {
|
} & {
|
||||||
[K in keyof TOtherModelNamesAndAssociatedDTO as `delete${ExtractPluralName<
|
[K in keyof ModelsConfig as `delete${ExtractPluralName<ModelsConfig, K> &
|
||||||
TOtherModelNamesAndAssociatedDTO,
|
|
||||||
K
|
|
||||||
> &
|
|
||||||
string}`]: {
|
string}`]: {
|
||||||
(
|
(
|
||||||
primaryKeyValues: string | object | string[] | object[],
|
primaryKeyValues: string | object | string[] | object[],
|
||||||
@@ -143,10 +162,7 @@ export type AbstractModuleService<
|
|||||||
): Promise<void>
|
): Promise<void>
|
||||||
}
|
}
|
||||||
} & {
|
} & {
|
||||||
[K in keyof TOtherModelNamesAndAssociatedDTO as `softDelete${ExtractPluralName<
|
[K in keyof ModelsConfig as `softDelete${ExtractPluralName<ModelsConfig, K> &
|
||||||
TOtherModelNamesAndAssociatedDTO,
|
|
||||||
K
|
|
||||||
> &
|
|
||||||
string}`]: {
|
string}`]: {
|
||||||
<TReturnableLinkableKeys extends string>(
|
<TReturnableLinkableKeys extends string>(
|
||||||
primaryKeyValues: string | object | string[] | object[],
|
primaryKeyValues: string | object | string[] | object[],
|
||||||
@@ -155,10 +171,7 @@ export type AbstractModuleService<
|
|||||||
): Promise<Record<string, string[]> | void>
|
): Promise<Record<string, string[]> | void>
|
||||||
}
|
}
|
||||||
} & {
|
} & {
|
||||||
[K in keyof TOtherModelNamesAndAssociatedDTO as `restore${ExtractPluralName<
|
[K in keyof ModelsConfig as `restore${ExtractPluralName<ModelsConfig, K> &
|
||||||
TOtherModelNamesAndAssociatedDTO,
|
|
||||||
K
|
|
||||||
> &
|
|
||||||
string}`]: {
|
string}`]: {
|
||||||
<TReturnableLinkableKeys extends string>(
|
<TReturnableLinkableKeys extends string>(
|
||||||
primaryKeyValues: string | object | string[] | object[],
|
primaryKeyValues: string | object | string[] | object[],
|
||||||
@@ -166,6 +179,44 @@ export type AbstractModuleService<
|
|||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
): Promise<Record<string, string[]> | void>
|
): Promise<Record<string, string[]> | void>
|
||||||
}
|
}
|
||||||
|
} & {
|
||||||
|
[ModelName in keyof ModelsConfig as CreateMethodName<
|
||||||
|
ModelsConfig,
|
||||||
|
ModelName
|
||||||
|
>]: {
|
||||||
|
(
|
||||||
|
data: ModelsConfig[ModelName]["create"][],
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<ModelsConfig[ModelName]["dto"][]>
|
||||||
|
}
|
||||||
|
} & {
|
||||||
|
[ModelName in keyof ModelsConfig as CreateMethodName<
|
||||||
|
ModelsConfig,
|
||||||
|
ModelName
|
||||||
|
>]: {
|
||||||
|
(data: ModelsConfig[ModelName]["create"], sharedContext?: Context): Promise<
|
||||||
|
ModelsConfig[ModelName]["dto"]
|
||||||
|
>
|
||||||
|
}
|
||||||
|
} & {
|
||||||
|
[ModelName in keyof ModelsConfig as UpdateMethodName<
|
||||||
|
ModelsConfig,
|
||||||
|
ModelName
|
||||||
|
>]: {
|
||||||
|
(
|
||||||
|
data: ModelsConfig[ModelName]["update"][],
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<ModelsConfig[ModelName]["dto"][]>
|
||||||
|
}
|
||||||
|
} & {
|
||||||
|
[ModelName in keyof ModelsConfig as UpdateMethodName<
|
||||||
|
ModelsConfig,
|
||||||
|
ModelName
|
||||||
|
>]: {
|
||||||
|
(data: ModelsConfig[ModelName]["update"], sharedContext?: Context): Promise<
|
||||||
|
ModelsConfig[ModelName]["dto"]
|
||||||
|
>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -211,7 +262,7 @@ export type AbstractModuleService<
|
|||||||
export function abstractModuleServiceFactory<
|
export function abstractModuleServiceFactory<
|
||||||
TContainer,
|
TContainer,
|
||||||
TMainModelDTO,
|
TMainModelDTO,
|
||||||
TOtherModelNamesAndAssociatedDTO extends ModelsConfigTemplate
|
ModelsConfig extends ModelsConfigTemplate
|
||||||
>(
|
>(
|
||||||
mainModel: Constructor<any>,
|
mainModel: Constructor<any>,
|
||||||
otherModels: ModelConfiguration[],
|
otherModels: ModelConfiguration[],
|
||||||
@@ -220,7 +271,7 @@ export function abstractModuleServiceFactory<
|
|||||||
new (container: TContainer): AbstractModuleService<
|
new (container: TContainer): AbstractModuleService<
|
||||||
TContainer,
|
TContainer,
|
||||||
TMainModelDTO,
|
TMainModelDTO,
|
||||||
TOtherModelNamesAndAssociatedDTO
|
ModelsConfig
|
||||||
>
|
>
|
||||||
} {
|
} {
|
||||||
const buildMethodNamesFromModel = (
|
const buildMethodNamesFromModel = (
|
||||||
@@ -303,6 +354,44 @@ export function abstractModuleServiceFactory<
|
|||||||
|
|
||||||
applyMethod(methodImplementation, 2)
|
applyMethod(methodImplementation, 2)
|
||||||
|
|
||||||
|
break
|
||||||
|
case "create":
|
||||||
|
methodImplementation = async function <T extends object>(
|
||||||
|
this: AbstractModuleService_,
|
||||||
|
data = [],
|
||||||
|
sharedContext: Context = {}
|
||||||
|
): Promise<T | T[]> {
|
||||||
|
const serviceData = Array.isArray(data) ? data : [data]
|
||||||
|
const service = this.__container__[serviceRegistrationName]
|
||||||
|
const entities = await service.create(serviceData, sharedContext)
|
||||||
|
const response = Array.isArray(data) ? entities : entities[0]
|
||||||
|
|
||||||
|
return await this.baseRepository_.serialize<T | T[]>(response, {
|
||||||
|
populate: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
applyMethod(methodImplementation, 1)
|
||||||
|
|
||||||
|
break
|
||||||
|
case "update":
|
||||||
|
methodImplementation = async function <T extends object>(
|
||||||
|
this: AbstractModuleService_,
|
||||||
|
data = [],
|
||||||
|
sharedContext: Context = {}
|
||||||
|
): Promise<T | T[]> {
|
||||||
|
const serviceData = Array.isArray(data) ? data : [data]
|
||||||
|
const service = this.__container__[serviceRegistrationName]
|
||||||
|
const entities = await service.update(serviceData, sharedContext)
|
||||||
|
const response = Array.isArray(data) ? entities : entities[0]
|
||||||
|
|
||||||
|
return await this.baseRepository_.serialize<T | T[]>(response, {
|
||||||
|
populate: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
applyMethod(methodImplementation, 1)
|
||||||
|
|
||||||
break
|
break
|
||||||
case "list":
|
case "list":
|
||||||
methodImplementation = async function <T extends object>(
|
methodImplementation = async function <T extends object>(
|
||||||
@@ -532,9 +621,5 @@ export function abstractModuleServiceFactory<
|
|||||||
|
|
||||||
return AbstractModuleService_ as unknown as new (
|
return AbstractModuleService_ as unknown as new (
|
||||||
container: TContainer
|
container: TContainer
|
||||||
) => AbstractModuleService<
|
) => AbstractModuleService<TContainer, TMainModelDTO, ModelsConfig>
|
||||||
TContainer,
|
|
||||||
TMainModelDTO,
|
|
||||||
TOtherModelNamesAndAssociatedDTO
|
|
||||||
>
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user