diff --git a/.changeset/slow-plants-clean.md b/.changeset/slow-plants-clean.md new file mode 100644 index 0000000000000..a3c3bde0ed72b --- /dev/null +++ b/.changeset/slow-plants-clean.md @@ -0,0 +1,5 @@ +--- +"@medusajs/utils": patch +--- + +feat(utils): autogenerates create and update methods when dto is provided diff --git a/packages/pricing/src/services/pricing-module.ts b/packages/pricing/src/services/pricing-module.ts index f55d92f3bad7b..c6ea777992496 100644 --- a/packages/pricing/src/services/pricing-module.ts +++ b/packages/pricing/src/services/pricing-module.ts @@ -94,13 +94,21 @@ export default class PricingModuleService< InjectedDependencies, PricingTypes.PriceSetDTO, { - MoneyAmount: { dto: PricingTypes.MoneyAmountDTO } + MoneyAmount: { + dto: PricingTypes.MoneyAmountDTO + create: PricingTypes.CreateMoneyAmountDTO + update: PricingTypes.UpdateMoneyAmountDTO + } PriceSetMoneyAmount: { dto: PricingTypes.PriceSetMoneyAmountDTO } PriceSetMoneyAmountRules: { dto: PricingTypes.PriceSetMoneyAmountRulesDTO } PriceRule: { dto: PricingTypes.PriceRuleDTO } - RuleType: { dto: PricingTypes.RuleTypeDTO } + RuleType: { + dto: PricingTypes.RuleTypeDTO + create: PricingTypes.CreateRuleTypeDTO + update: PricingTypes.UpdateRuleTypeDTO + } PriceList: { dto: PricingTypes.PriceListDTO } 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( - 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( - moneyAmounts, - { - populate: true, - } - ) - } - - @InjectTransactionManager("baseRepository_") - async createRuleTypes( - data: PricingTypes.CreateRuleTypeDTO[], - @MedusaContext() sharedContext: Context = {} - ): Promise { - const ruleTypes = await this.ruleTypeService_.create(data, sharedContext) - - return await this.baseRepository_.serialize( - ruleTypes, - { - populate: true, - } - ) - } - - @InjectTransactionManager("baseRepository_") - async updateRuleTypes( - data: PricingTypes.UpdateRuleTypeDTO[], - @MedusaContext() sharedContext: Context = {} - ): Promise { - const ruleTypes = await this.ruleTypeService_.update(data, sharedContext) - - return await this.baseRepository_.serialize( - ruleTypes, - { - populate: true, - } - ) - } - @InjectTransactionManager("baseRepository_") async createPriceSetMoneyAmountRules( data: PricingTypes.CreatePriceSetMoneyAmountRulesDTO[], diff --git a/packages/types/src/pricing/service.ts b/packages/types/src/pricing/service.ts index c502c34f5d6db..200f11cf9d7ee 100644 --- a/packages/types/src/pricing/service.ts +++ b/packages/types/src/pricing/service.ts @@ -1218,6 +1218,11 @@ export interface IPricingModuleService extends IModuleService { sharedContext?: Context ): Promise + createMoneyAmounts( + data: CreateMoneyAmountDTO, + sharedContext?: Context + ): Promise + /** * This method updates existing money amounts. * @@ -1248,6 +1253,11 @@ export interface IPricingModuleService extends IModuleService { sharedContext?: Context ): Promise + updateMoneyAmounts( + data: UpdateMoneyAmountDTO, + sharedContext?: Context + ): Promise + /** * This method deletes money amounts by their IDs. * diff --git a/packages/utils/src/modules-sdk/abstract-module-service-factory.ts b/packages/utils/src/modules-sdk/abstract-module-service-factory.ts index 33b56db2a94ea..a6c4cd430f26c 100644 --- a/packages/utils/src/modules-sdk/abstract-module-service-factory.ts +++ b/packages/utils/src/modules-sdk/abstract-module-service-factory.ts @@ -12,11 +12,11 @@ import { SoftDeleteReturn, } from "@medusajs/types" import { + MapToConfig, isString, kebabCase, lowerCaseFirst, mapObjectTo, - MapToConfig, pluralize, upperCaseFirst, } from "../common" @@ -33,14 +33,28 @@ type BaseMethods = | "delete" | "softDelete" | "restore" + | "create" + | "update" 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] type ModelsConfigTemplate = { - [ModelName: string]: { singular?: string; plural?: string; dto: object } + [ModelName: string]: { + singular?: string + plural?: string + dto: object + create?: object + update?: object + } } type ExtractSingularName< @@ -48,6 +62,20 @@ type ExtractSingularName< K = keyof T > = T[K] extends { singular?: string } ? T[K]["singular"] : K +type CreateMethodName< + ModelConfig extends Record, + ModelKey = keyof ModelConfig +> = ModelConfig[ModelKey] extends { create?: object } + ? `create${ExtractPluralName}` + : never + +type UpdateMethodName< + ModelConfig extends Record, + ModelKey = keyof ModelConfig +> = ModelConfig[ModelKey] extends { update?: object } + ? `update${ExtractPluralName}` + : never + type ExtractPluralName, K = keyof T> = T[K] extends { plural?: string } @@ -100,42 +128,33 @@ export interface AbstractModuleServiceBase { export type AbstractModuleService< TContainer, TMainModelDTO, - TOtherModelNamesAndAssociatedDTO extends ModelsConfigTemplate + ModelsConfig extends ModelsConfigTemplate > = AbstractModuleServiceBase & { - [K in keyof TOtherModelNamesAndAssociatedDTO as `retrieve${ExtractSingularName< - TOtherModelNamesAndAssociatedDTO, - K - > & + [K in keyof ModelsConfig as `retrieve${ExtractSingularName & string}`]: ( id: string, config?: FindConfig, sharedContext?: Context - ) => Promise + ) => Promise } & { - [K in keyof TOtherModelNamesAndAssociatedDTO as `list${ExtractPluralName< - TOtherModelNamesAndAssociatedDTO, - K - > & + [K in keyof ModelsConfig as `list${ExtractPluralName & string}`]: ( filters?: any, config?: FindConfig, sharedContext?: Context - ) => Promise + ) => Promise } & { - [K in keyof TOtherModelNamesAndAssociatedDTO as `listAndCount${ExtractPluralName< - TOtherModelNamesAndAssociatedDTO, + [K in keyof ModelsConfig as `listAndCount${ExtractPluralName< + ModelsConfig, K > & string}`]: { (filters?: any, config?: FindConfig, sharedContext?: Context): Promise< - [TOtherModelNamesAndAssociatedDTO[K & string]["dto"][], number] + [ModelsConfig[K & string]["dto"][], number] > } } & { - [K in keyof TOtherModelNamesAndAssociatedDTO as `delete${ExtractPluralName< - TOtherModelNamesAndAssociatedDTO, - K - > & + [K in keyof ModelsConfig as `delete${ExtractPluralName & string}`]: { ( primaryKeyValues: string | object | string[] | object[], @@ -143,10 +162,7 @@ export type AbstractModuleService< ): Promise } } & { - [K in keyof TOtherModelNamesAndAssociatedDTO as `softDelete${ExtractPluralName< - TOtherModelNamesAndAssociatedDTO, - K - > & + [K in keyof ModelsConfig as `softDelete${ExtractPluralName & string}`]: { ( primaryKeyValues: string | object | string[] | object[], @@ -155,10 +171,7 @@ export type AbstractModuleService< ): Promise | void> } } & { - [K in keyof TOtherModelNamesAndAssociatedDTO as `restore${ExtractPluralName< - TOtherModelNamesAndAssociatedDTO, - K - > & + [K in keyof ModelsConfig as `restore${ExtractPluralName & string}`]: { ( primaryKeyValues: string | object | string[] | object[], @@ -166,6 +179,44 @@ export type AbstractModuleService< sharedContext?: Context ): Promise | void> } +} & { + [ModelName in keyof ModelsConfig as CreateMethodName< + ModelsConfig, + ModelName + >]: { + ( + data: ModelsConfig[ModelName]["create"][], + sharedContext?: Context + ): Promise + } +} & { + [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 + } +} & { + [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< TContainer, TMainModelDTO, - TOtherModelNamesAndAssociatedDTO extends ModelsConfigTemplate + ModelsConfig extends ModelsConfigTemplate >( mainModel: Constructor, otherModels: ModelConfiguration[], @@ -220,7 +271,7 @@ export function abstractModuleServiceFactory< new (container: TContainer): AbstractModuleService< TContainer, TMainModelDTO, - TOtherModelNamesAndAssociatedDTO + ModelsConfig > } { const buildMethodNamesFromModel = ( @@ -303,6 +354,44 @@ export function abstractModuleServiceFactory< applyMethod(methodImplementation, 2) + break + case "create": + methodImplementation = async function ( + this: AbstractModuleService_, + data = [], + sharedContext: Context = {} + ): Promise { + 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(response, { + populate: true, + }) + } + + applyMethod(methodImplementation, 1) + + break + case "update": + methodImplementation = async function ( + this: AbstractModuleService_, + data = [], + sharedContext: Context = {} + ): Promise { + 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(response, { + populate: true, + }) + } + + applyMethod(methodImplementation, 1) + break case "list": methodImplementation = async function ( @@ -532,9 +621,5 @@ export function abstractModuleServiceFactory< return AbstractModuleService_ as unknown as new ( container: TContainer - ) => AbstractModuleService< - TContainer, - TMainModelDTO, - TOtherModelNamesAndAssociatedDTO - > + ) => AbstractModuleService }