chore(): Handle medusa service base methods events (#9179)

* chore(): Handle medusa service base methods events

* cleanup

* cleanup

* fix import

* fix decorator order

* fixes

* apply default event emition

* fix binding

* fix binding

* align tests with new event emition
This commit is contained in:
Adrien de Peretti authored and GitHub committed 2024-09-18 17:57:00 +02:00
1 parent 81d3ae01c7
commit a734184538
13 files changed
+290 -116

No files matched your search

@@ -15,6 +15,10 @@ export class MessageAggregator implements IMessageAggregator {
this.messages = [] this.messages = []
} }
count(): number {
return this.messages.length
}
save(msg: Message | Message[]): void { save(msg: Message | Message[]): void {
if (!msg || (Array.isArray(msg) && msg.length === 0)) { if (!msg || (Array.isArray(msg) && msg.length === 0)) {
return return
+26 -4
View File
@@ -28,6 +28,25 @@ type ReturnType<TNames extends string[]> = {
>}_DETACHED`]: `${KebabCase<K & string>}.detached` >}_DETACHED`]: `${KebabCase<K & string>}.detached`
} }
/**
* Build a conventional event name from the object name and the action and the prefix if provided
* @param prefix
* @param objectName
* @param action
*/
export function buildModuleResourceEventName({
prefix,
objectName,
action,
}: {
prefix?: string
objectName: string
action: string
}): string {
const kebabCaseName = lowerCaseFirst(kebabCase(objectName))
return `${prefix ? `${prefix}.` : ""}${kebabCaseName}.${action}`
}
/** /**
* From the given strings it will produce the event names accordingly. * From the given strings it will produce the event names accordingly.
* the result will look like: * the result will look like:
@@ -43,6 +62,7 @@ type ReturnType<TNames extends string[]> = {
* } * }
* *
* @param names * @param names
* @param prefix
*/ */
export function buildEventNamesFromEntityName<TNames extends string[]>( export function buildEventNamesFromEntityName<TNames extends string[]>(
names: TNames, names: TNames,
@@ -53,13 +73,15 @@ export function buildEventNamesFromEntityName<TNames extends string[]>(
for (let i = 0; i < names.length; i++) { for (let i = 0; i < names.length; i++) {
const name = names[i] const name = names[i]
const snakedCaseName = camelToSnakeCase(name).toUpperCase() const snakedCaseName = camelToSnakeCase(name).toUpperCase()
const kebabCaseName = lowerCaseFirst(kebabCase(name))
for (const event of Object.values(CommonEvents) as string[]) { for (const event of Object.values(CommonEvents) as string[]) {
const upperCasedEvent = event.toUpperCase() const upperCasedEvent = event.toUpperCase()
events[`${snakedCaseName}_${upperCasedEvent}`] = `${ events[`${snakedCaseName}_${upperCasedEvent}`] =
prefix ? prefix + "." : "" buildModuleResourceEventName({
}${kebabCaseName}.${event}` as `${KebabCase<typeof name>}.${typeof event}` prefix,
objectName: name,
action: event,
}) as `${KebabCase<typeof name>}.${typeof event}`
} }
} }
@@ -1,5 +1,7 @@
import { MedusaService } from "../medusa-service" import { MedusaService } from "../medusa-service"
import { model } from "../../dml" import { model } from "../../dml"
import { MessageAggregator } from "../../event-bus"
import { ModuleJoinerConfig } from "@medusajs/types"
const baseRepoMock = { const baseRepoMock = {
serialize: jest.fn().mockImplementation((item) => item), serialize: jest.fn().mockImplementation((item) => item),
@@ -7,10 +9,15 @@ const baseRepoMock = {
getFreshManager: jest.fn().mockReturnThis(), getFreshManager: jest.fn().mockReturnThis(),
} }
const defaultContext = { __type: "MedusaContext", manager: baseRepoMock } const defaultContext = {
__type: "MedusaContext",
manager: baseRepoMock,
messageAggregator: new MessageAggregator(),
}
const defaultTransactionContext = { const defaultTransactionContext = {
__type: "MedusaContext", __type: "MedusaContext",
manager: baseRepoMock, manager: baseRepoMock,
messageAggregator: new MessageAggregator(),
} }
describe("Abstract Module Service Factory", () => { describe("Abstract Module Service Factory", () => {
@@ -58,6 +65,9 @@ describe("Abstract Module Service Factory", () => {
beforeEach(() => { beforeEach(() => {
jest.clearAllMocks() jest.clearAllMocks()
instance = new medusaService(containerMock) instance = new medusaService(containerMock)
;(instance as any).__joinerConfig = {
serviceName: "serviceName",
} as ModuleJoinerConfig
}) })
it("should have retrieve method", async () => { it("should have retrieve method", async () => {
@@ -120,6 +130,9 @@ describe("Abstract Module Service Factory", () => {
beforeEach(() => { beforeEach(() => {
jest.clearAllMocks() jest.clearAllMocks()
instance = new medusaService(containerMock) instance = new medusaService(containerMock)
;(instance as any).__joinerConfig = {
serviceName: "serviceName",
}
}) })
it("should have retrieve method for other models", async () => { it("should have retrieve method for other models", async () => {
@@ -36,9 +36,12 @@ export function EmitEvents(
const argIndex = target.MedusaContextIndex_[propertyKey] const argIndex = target.MedusaContextIndex_[propertyKey]
const aggregator = args[argIndex].messageAggregator as MessageAggregator const aggregator = args[argIndex].messageAggregator as MessageAggregator
await target.emitEvents_.apply(this, [aggregator.getMessages(options)])
aggregator.clearMessages() if (aggregator.count() > 0) {
await target.emitEvents_.apply(this, [aggregator.getMessages(options)])
aggregator.clearMessages()
}
return result return result
} }
} }
@@ -1,13 +1,14 @@
import { Context, EventBusTypes } from "@medusajs/types" import { Context, EventBusTypes } from "@medusajs/types"
import { buildModuleResourceEventName } from "../event-bus"
// TODO should that move closer to the event bus? and maybe be rename to moduleEventBuilderFactory // TODO should that move closer to the event bus? and maybe be rename to modulemoduleEventBuilderFactory
/** /**
* *
* Factory function to create event builders for different entities * Factory function to create event builders for different entities
* *
* @example * @example
* const createdFulfillment = eventBuilderFactory({ * const createdFulfillment = moduleEventBuilderFactory({
* source: Modules.FULFILLMENT, * source: Modules.FULFILLMENT,
* action: CommonEvents.CREATED, * action: CommonEvents.CREATED,
* object: "fulfillment", * object: "fulfillment",
@@ -24,24 +25,31 @@ import { Context, EventBusTypes } from "@medusajs/types"
* @param eventsEnum * @param eventsEnum
* @param service * @param service
*/ */
export function eventBuilderFactory({ export function moduleEventBuilderFactory({
action, action,
object, object,
eventsEnum, eventsEnum,
eventName,
source, source,
}: { }: {
action: string action: string
object: string object: string
eventsEnum: Record<string, string> /**
* @deprecated use eventName instead
*/
eventsEnum?: Record<string, string>
eventName?: string
source: string source: string
}) { }) {
return function ({ return function ({
data, data,
sharedContext, sharedContext,
}: { }: {
data: { id: string }[] data: { id: string } | { id: string }[]
sharedContext: Context sharedContext: Context
}) { }) {
data = Array.isArray(data) ? data : [data]
if (!data.length) { if (!data.length) {
return return
} }
@@ -51,8 +59,17 @@ export function eventBuilderFactory({
// The event enums contains event formatted like so [object]_[action] e.g. PRODUCT_CREATED // The event enums contains event formatted like so [object]_[action] e.g. PRODUCT_CREATED
// We expect the keys of events to be fully uppercased // We expect the keys of events to be fully uppercased
const eventName = let eventName_ = eventsEnum
eventsEnum[`${object.toUpperCase()}_${action.toUpperCase()}`] ? eventsEnum[`${object.toUpperCase()}_${action.toUpperCase()}`]
: eventName
if (!eventName_) {
eventName_ = buildModuleResourceEventName({
prefix: source,
objectName: object,
action,
})
}
data.forEach((dataItem) => { data.forEach((dataItem) => {
messages.push({ messages.push({
@@ -60,7 +77,7 @@ export function eventBuilderFactory({
action, action,
context: sharedContext, context: sharedContext,
data: { id: dataItem.id }, data: { id: dataItem.id },
eventName, eventName: eventName_,
object, object,
}) })
}) })
@@ -11,16 +11,16 @@ import {
SoftDeleteReturn, SoftDeleteReturn,
} from "@medusajs/types" } from "@medusajs/types"
import { import {
MapToConfig, camelToSnakeCase,
isString, isString,
kebabCase,
lowerCaseFirst, lowerCaseFirst,
mapObjectTo, mapObjectTo,
MapToConfig,
pluralize, pluralize,
upperCaseFirst, upperCaseFirst,
} from "../common" } from "../common"
import { DmlEntity } from "../dml" import { DmlEntity } from "../dml"
import { InjectManager, MedusaContext } from "./decorators" import { EmitEvents, InjectManager, MedusaContext } from "./decorators"
import { Modules } from "./definition" import { Modules } from "./definition"
import { buildModelsNameToLinkableKeysMap } from "./joiner-config-builder" import { buildModelsNameToLinkableKeysMap } from "./joiner-config-builder"
import { import {
@@ -31,6 +31,8 @@ import {
ModelEntries, ModelEntries,
ModelsConfigTemplate, ModelsConfigTemplate,
} from "./types/medusa-service" } from "./types/medusa-service"
import { CommonEvents } from "../event-bus"
import { moduleEventBuilderFactory } from "./event-builder-factory"
const readMethods = ["retrieve", "list", "listAndCount"] as BaseMethods[] const readMethods = ["retrieve", "list", "listAndCount"] as BaseMethods[]
const writeMethods = [ const writeMethods = [
@@ -150,13 +152,10 @@ export function MedusaService<
value: klassPrototype[methodName], value: klassPrototype[methodName],
} }
// The order of the decorators is important, do not change it
MedusaContext()(klassPrototype, methodName, contextIndex) MedusaContext()(klassPrototype, methodName, contextIndex)
EmitEvents()(klassPrototype, methodName, descriptorMockRef)
InjectManager("baseRepository_")( InjectManager()(klassPrototype, methodName, descriptorMockRef)
klassPrototype,
methodName,
descriptorMockRef
)
klassPrototype[methodName] = descriptorMockRef.value klassPrototype[methodName] = descriptorMockRef.value
} }
@@ -194,6 +193,13 @@ export function MedusaService<
const models = await service.create(serviceData, sharedContext) const models = await service.create(serviceData, sharedContext)
const response = Array.isArray(data) ? models : models[0] const response = Array.isArray(data) ? models : models[0]
klassPrototype.aggregatedEvents.bind(this)({
action: CommonEvents.CREATED,
object: camelToSnakeCase(modelName).toLowerCase(),
data: response,
context: sharedContext,
})
return await this.baseRepository_.serialize<T | T[]>(response) return await this.baseRepository_.serialize<T | T[]>(response)
} }
@@ -211,6 +217,13 @@ export function MedusaService<
const models = await service.update(serviceData, sharedContext) const models = await service.update(serviceData, sharedContext)
const response = Array.isArray(data) ? models : models[0] const response = Array.isArray(data) ? models : models[0]
klassPrototype.aggregatedEvents.bind(this)({
action: CommonEvents.UPDATED,
object: camelToSnakeCase(modelName).toLowerCase(),
data: response,
context: sharedContext,
})
return await this.baseRepository_.serialize<T | T[]>(response) return await this.baseRepository_.serialize<T | T[]>(response)
} }
@@ -259,22 +272,21 @@ export function MedusaService<
const primaryKeyValues_ = Array.isArray(primaryKeyValues) const primaryKeyValues_ = Array.isArray(primaryKeyValues)
? primaryKeyValues ? primaryKeyValues
: [primaryKeyValues] : [primaryKeyValues]
await this.__container__[serviceRegistrationName].delete( await this.__container__[serviceRegistrationName].delete(
primaryKeyValues_, primaryKeyValues_,
sharedContext sharedContext
) )
await this.eventBusModuleService_?.emit( primaryKeyValues_.map((primaryKeyValue) =>
primaryKeyValues_.map((primaryKeyValue) => ({ klassPrototype.aggregatedEvents.bind(this)({
name: `${kebabCase(modelName)}.deleted`, action: CommonEvents.DELETED,
object: camelToSnakeCase(modelName).toLowerCase(),
data: isString(primaryKeyValue) data: isString(primaryKeyValue)
? { id: primaryKeyValue } ? { id: primaryKeyValue }
: primaryKeyValue, : primaryKeyValue,
metadata: { source: "", action: "", object: "" }, context: sharedContext,
})), })
{
internal: true,
}
) )
} }
@@ -292,25 +304,10 @@ export function MedusaService<
? primaryKeyValues ? primaryKeyValues
: [primaryKeyValues] : [primaryKeyValues]
const [models, cascadedModelsMap] = await this.__container__[ const [, cascadedModelsMap] = await this.__container__[
serviceRegistrationName serviceRegistrationName
].softDelete(primaryKeyValues_, sharedContext) ].softDelete(primaryKeyValues_, sharedContext)
const softDeletedModels = await this.baseRepository_.serialize<T[]>(
models
)
await this.eventBusModuleService_?.emit(
softDeletedModels.map(({ id }) => ({
name: `${kebabCase(modelName)}.deleted`,
metadata: { source: "", action: "", object: "" },
data: { id },
})),
{
internal: true,
}
)
// Map internal table/column names to their respective external linkable keys // Map internal table/column names to their respective external linkable keys
// eg: product.id = product_id, variant.id = variant_id // eg: product.id = product_id, variant.id = variant_id
const mappedCascadedModelsMap = mapObjectTo( const mappedCascadedModelsMap = mapObjectTo(
@@ -321,6 +318,31 @@ export function MedusaService<
} }
) )
if (mappedCascadedModelsMap) {
const joinerConfig = (
typeof this.__joinerConfig === "function"
? this.__joinerConfig()
: this.__joinerConfig
) as ModuleJoinerConfig
Object.entries(mappedCascadedModelsMap).forEach(
([linkableKey, ids]) => {
const entity = joinerConfig.linkableKeys?.[linkableKey]!
if (entity) {
const linkableKeyEntity =
camelToSnakeCase(entity).toLowerCase()
klassPrototype.aggregatedEvents.bind(this)({
action: CommonEvents.DELETED,
object: linkableKeyEntity,
data: { id: ids },
context: sharedContext,
})
}
}
)
}
return mappedCascadedModelsMap ? mappedCascadedModelsMap : void 0 return mappedCascadedModelsMap ? mappedCascadedModelsMap : void 0
} }
@@ -338,7 +360,7 @@ export function MedusaService<
? primaryKeyValues ? primaryKeyValues
: [primaryKeyValues] : [primaryKeyValues]
const [_, cascadedModelsMap] = await this.__container__[ const [, cascadedModelsMap] = await this.__container__[
serviceRegistrationName serviceRegistrationName
].restore(primaryKeyValues_, sharedContext) ].restore(primaryKeyValues_, sharedContext)
@@ -353,6 +375,30 @@ export function MedusaService<
} }
) )
if (mappedCascadedModelsMap) {
const joinerConfig = (
typeof this.__joinerConfig === "function"
? this.__joinerConfig()
: this.__joinerConfig
) as ModuleJoinerConfig
Object.entries(mappedCascadedModelsMap).forEach(
([linkableKey, ids]) => {
const entity = joinerConfig.linkableKeys?.[linkableKey]!
if (entity) {
const linkableKeyEntity =
camelToSnakeCase(entity).toLowerCase()
klassPrototype.aggregatedEvents.bind(this)({
action: CommonEvents.CREATED,
object: linkableKeyEntity,
data: { id: ids },
context: sharedContext,
})
}
}
)
}
return mappedCascadedModelsMap ? mappedCascadedModelsMap : void 0 return mappedCascadedModelsMap ? mappedCascadedModelsMap : void 0
} }
@@ -398,6 +444,50 @@ export function MedusaService<
) )
} }
/**
* helper function to aggregate events. Will format the message properly and store in
* the message aggregator from the context. The method must be decorated with `@EmitEvents`
* @param action
* @param object
* @param eventName optional, can be inferred from the module joiner config + action + object
* @param source optional, can be inferred from the module joiner config
* @param data
* @param context
*/
protected aggregatedEvents({
action,
object,
eventName,
source,
data,
context,
}: {
action: string
object: string
eventName?: string
source?: string
data: { id: any } | { id: any }[]
context: Context
}) {
const __joinerConfig = (
typeof this.__joinerConfig === "function"
? this.__joinerConfig()
: this.__joinerConfig
) as ModuleJoinerConfig
const eventBuilder = moduleEventBuilderFactory({
action,
object,
source: source || __joinerConfig.serviceName!,
eventName,
})
eventBuilder({
data,
sharedContext: context,
})
}
/** /**
* @internal this method is not meant to be used except by the internal team for now * @internal this method is not meant to be used except by the internal team for now
* @param groupedEvents * @param groupedEvents
@@ -265,4 +265,29 @@ export type MedusaServiceReturnType<ModelsConfig extends Record<string, any>> =
{ {
new (...args: any[]): AbstractModuleService<ModelsConfig> new (...args: any[]): AbstractModuleService<ModelsConfig>
$modelObjects: InferModelFromConfig<ModelsConfig> $modelObjects: InferModelFromConfig<ModelsConfig>
/**
* helper function to aggregate events. Will format the message properly and store in
* the message aggregator in the context
* @param action
* @param object
* @param eventName optional, can be inferred from the module joiner config + action + object
* @param source optional, can be inferred from the module joiner config
* @param data
* @param context
*/
aggregatedEvents({
action,
object,
eventName,
source,
data,
context,
}: {
action: string
object: string
eventName: string
source?: string
data: { id: any } | { id: any }[]
context: Context
}): void
} }
@@ -10,157 +10,157 @@ import {
import { Context } from "@medusajs/types" import { Context } from "@medusajs/types"
import { import {
CommonEvents, CommonEvents,
eventBuilderFactory,
FulfillmentEvents, FulfillmentEvents,
moduleEventBuilderFactory,
Modules, Modules,
} from "@medusajs/utils" } from "@medusajs/utils"
export const eventBuilders = { export const eventBuilders = {
createdFulfillment: eventBuilderFactory({ createdFulfillment: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.CREATED, action: CommonEvents.CREATED,
object: "fulfillment", object: "fulfillment",
eventsEnum: FulfillmentEvents, eventsEnum: FulfillmentEvents,
}), }),
updatedFulfillment: eventBuilderFactory({ updatedFulfillment: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.UPDATED, action: CommonEvents.UPDATED,
object: "fulfillment", object: "fulfillment",
eventsEnum: FulfillmentEvents, eventsEnum: FulfillmentEvents,
}), }),
createdFulfillmentAddress: eventBuilderFactory({ createdFulfillmentAddress: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.CREATED, action: CommonEvents.CREATED,
object: "fulfillment_address", object: "fulfillment_address",
eventsEnum: FulfillmentEvents, eventsEnum: FulfillmentEvents,
}), }),
createdFulfillmentItem: eventBuilderFactory({ createdFulfillmentItem: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.CREATED, action: CommonEvents.CREATED,
object: "fulfillment_item", object: "fulfillment_item",
eventsEnum: FulfillmentEvents, eventsEnum: FulfillmentEvents,
}), }),
createdFulfillmentLabel: eventBuilderFactory({ createdFulfillmentLabel: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.CREATED, action: CommonEvents.CREATED,
object: "fulfillment_label", object: "fulfillment_label",
eventsEnum: FulfillmentEvents, eventsEnum: FulfillmentEvents,
}), }),
updatedFulfillmentLabel: eventBuilderFactory({ updatedFulfillmentLabel: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.UPDATED, action: CommonEvents.UPDATED,
object: "fulfillment_label", object: "fulfillment_label",
eventsEnum: FulfillmentEvents, eventsEnum: FulfillmentEvents,
}), }),
deletedFulfillmentLabel: eventBuilderFactory({ deletedFulfillmentLabel: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.DELETED, action: CommonEvents.DELETED,
object: "fulfillment_label", object: "fulfillment_label",
eventsEnum: FulfillmentEvents, eventsEnum: FulfillmentEvents,
}), }),
createdShippingProfile: eventBuilderFactory({ createdShippingProfile: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.CREATED, action: CommonEvents.CREATED,
object: "shipping_profile", object: "shipping_profile",
eventsEnum: FulfillmentEvents, eventsEnum: FulfillmentEvents,
}), }),
createdShippingOptionType: eventBuilderFactory({ createdShippingOptionType: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.CREATED, action: CommonEvents.CREATED,
object: "shipping_option_type", object: "shipping_option_type",
eventsEnum: FulfillmentEvents, eventsEnum: FulfillmentEvents,
}), }),
updatedShippingOptionType: eventBuilderFactory({ updatedShippingOptionType: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.UPDATED, action: CommonEvents.UPDATED,
object: "shipping_option_type", object: "shipping_option_type",
eventsEnum: FulfillmentEvents, eventsEnum: FulfillmentEvents,
}), }),
deletedShippingOptionType: eventBuilderFactory({ deletedShippingOptionType: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.DELETED, action: CommonEvents.DELETED,
object: "shipping_option_type", object: "shipping_option_type",
eventsEnum: FulfillmentEvents, eventsEnum: FulfillmentEvents,
}), }),
createdShippingOptionRule: eventBuilderFactory({ createdShippingOptionRule: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.CREATED, action: CommonEvents.CREATED,
object: "shipping_option_rule", object: "shipping_option_rule",
eventsEnum: FulfillmentEvents, eventsEnum: FulfillmentEvents,
}), }),
updatedShippingOptionRule: eventBuilderFactory({ updatedShippingOptionRule: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.UPDATED, action: CommonEvents.UPDATED,
object: "shipping_option_rule", object: "shipping_option_rule",
eventsEnum: FulfillmentEvents, eventsEnum: FulfillmentEvents,
}), }),
deletedShippingOptionRule: eventBuilderFactory({ deletedShippingOptionRule: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.DELETED, action: CommonEvents.DELETED,
object: "shipping_option_rule", object: "shipping_option_rule",
eventsEnum: FulfillmentEvents, eventsEnum: FulfillmentEvents,
}), }),
createdShippingOption: eventBuilderFactory({ createdShippingOption: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.CREATED, action: CommonEvents.CREATED,
object: "shipping_option", object: "shipping_option",
eventsEnum: FulfillmentEvents, eventsEnum: FulfillmentEvents,
}), }),
updatedShippingOption: eventBuilderFactory({ updatedShippingOption: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.UPDATED, action: CommonEvents.UPDATED,
object: "shipping_option", object: "shipping_option",
eventsEnum: FulfillmentEvents, eventsEnum: FulfillmentEvents,
}), }),
createdFulfillmentSet: eventBuilderFactory({ createdFulfillmentSet: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.CREATED, action: CommonEvents.CREATED,
object: "fulfillment_set", object: "fulfillment_set",
eventsEnum: FulfillmentEvents, eventsEnum: FulfillmentEvents,
}), }),
updatedFulfillmentSet: eventBuilderFactory({ updatedFulfillmentSet: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.UPDATED, action: CommonEvents.UPDATED,
object: "fulfillment_set", object: "fulfillment_set",
eventsEnum: FulfillmentEvents, eventsEnum: FulfillmentEvents,
}), }),
deletedFulfillmentSet: eventBuilderFactory({ deletedFulfillmentSet: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.DELETED, action: CommonEvents.DELETED,
object: "fulfillment_set", object: "fulfillment_set",
eventsEnum: FulfillmentEvents, eventsEnum: FulfillmentEvents,
}), }),
createdServiceZone: eventBuilderFactory({ createdServiceZone: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.CREATED, action: CommonEvents.CREATED,
object: "service_zone", object: "service_zone",
eventsEnum: FulfillmentEvents, eventsEnum: FulfillmentEvents,
}), }),
updatedServiceZone: eventBuilderFactory({ updatedServiceZone: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.UPDATED, action: CommonEvents.UPDATED,
object: "service_zone", object: "service_zone",
eventsEnum: FulfillmentEvents, eventsEnum: FulfillmentEvents,
}), }),
deletedServiceZone: eventBuilderFactory({ deletedServiceZone: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.DELETED, action: CommonEvents.DELETED,
object: "service_zone", object: "service_zone",
eventsEnum: FulfillmentEvents, eventsEnum: FulfillmentEvents,
}), }),
createdGeoZone: eventBuilderFactory({ createdGeoZone: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.CREATED, action: CommonEvents.CREATED,
object: "geo_zone", object: "geo_zone",
eventsEnum: FulfillmentEvents, eventsEnum: FulfillmentEvents,
}), }),
updatedGeoZone: eventBuilderFactory({ updatedGeoZone: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.UPDATED, action: CommonEvents.UPDATED,
object: "geo_zone", object: "geo_zone",
eventsEnum: FulfillmentEvents, eventsEnum: FulfillmentEvents,
}), }),
deletedGeoZone: eventBuilderFactory({ deletedGeoZone: moduleEventBuilderFactory({
source: Modules.FULFILLMENT, source: Modules.FULFILLMENT,
action: CommonEvents.DELETED, action: CommonEvents.DELETED,
object: "geo_zone", object: "geo_zone",
@@ -1,12 +1,12 @@
import { import {
CommonEvents, CommonEvents,
eventBuilderFactory, moduleEventBuilderFactory,
Modules, Modules,
NotificationEvents, NotificationEvents,
} from "@medusajs/utils" } from "@medusajs/utils"
export const eventBuilders = { export const eventBuilders = {
createdNotification: eventBuilderFactory({ createdNotification: moduleEventBuilderFactory({
source: Modules.NOTIFICATION, source: Modules.NOTIFICATION,
action: CommonEvents.CREATED, action: CommonEvents.CREATED,
object: "notification", object: "notification",
+11 -11
View File
@@ -1,66 +1,66 @@
import { import {
CommonEvents, CommonEvents,
eventBuilderFactory, moduleEventBuilderFactory,
Modules, Modules,
PricingEvents, PricingEvents,
} from "@medusajs/utils" } from "@medusajs/utils"
export const eventBuilders = { export const eventBuilders = {
createdPriceSet: eventBuilderFactory({ createdPriceSet: moduleEventBuilderFactory({
source: Modules.PRICING, source: Modules.PRICING,
action: CommonEvents.CREATED, action: CommonEvents.CREATED,
object: "price_set", object: "price_set",
eventsEnum: PricingEvents, eventsEnum: PricingEvents,
}), }),
createdPrice: eventBuilderFactory({ createdPrice: moduleEventBuilderFactory({
source: Modules.PRICING, source: Modules.PRICING,
action: CommonEvents.CREATED, action: CommonEvents.CREATED,
object: "price", object: "price",
eventsEnum: PricingEvents, eventsEnum: PricingEvents,
}), }),
createdPriceRule: eventBuilderFactory({ createdPriceRule: moduleEventBuilderFactory({
source: Modules.PRICING, source: Modules.PRICING,
action: CommonEvents.CREATED, action: CommonEvents.CREATED,
object: "price_rule", object: "price_rule",
eventsEnum: PricingEvents, eventsEnum: PricingEvents,
}), }),
createdPriceList: eventBuilderFactory({ createdPriceList: moduleEventBuilderFactory({
source: Modules.PRICING, source: Modules.PRICING,
action: CommonEvents.CREATED, action: CommonEvents.CREATED,
object: "price_list", object: "price_list",
eventsEnum: PricingEvents, eventsEnum: PricingEvents,
}), }),
createdPriceListRule: eventBuilderFactory({ createdPriceListRule: moduleEventBuilderFactory({
source: Modules.PRICING, source: Modules.PRICING,
action: CommonEvents.CREATED, action: CommonEvents.CREATED,
object: "price_list_rule", object: "price_list_rule",
eventsEnum: PricingEvents, eventsEnum: PricingEvents,
}), }),
attachedPriceListRule: eventBuilderFactory({ attachedPriceListRule: moduleEventBuilderFactory({
source: Modules.PRICING, source: Modules.PRICING,
action: CommonEvents.ATTACHED, action: CommonEvents.ATTACHED,
object: "price_list_rule", object: "price_list_rule",
eventsEnum: PricingEvents, eventsEnum: PricingEvents,
}), }),
updatedPrice: eventBuilderFactory({ updatedPrice: moduleEventBuilderFactory({
source: Modules.PRICING, source: Modules.PRICING,
action: CommonEvents.UPDATED, action: CommonEvents.UPDATED,
object: "price", object: "price",
eventsEnum: PricingEvents, eventsEnum: PricingEvents,
}), }),
updatedPriceRule: eventBuilderFactory({ updatedPriceRule: moduleEventBuilderFactory({
source: Modules.PRICING, source: Modules.PRICING,
action: CommonEvents.UPDATED, action: CommonEvents.UPDATED,
object: "price_rule", object: "price_rule",
eventsEnum: PricingEvents, eventsEnum: PricingEvents,
}), }),
deletedPrice: eventBuilderFactory({ deletedPrice: moduleEventBuilderFactory({
source: Modules.PRICING, source: Modules.PRICING,
action: CommonEvents.DELETED, action: CommonEvents.DELETED,
object: "price", object: "price",
eventsEnum: PricingEvents, eventsEnum: PricingEvents,
}), }),
deletedPriceRule: eventBuilderFactory({ deletedPriceRule: moduleEventBuilderFactory({
source: Modules.PRICING, source: Modules.PRICING,
action: CommonEvents.DELETED, action: CommonEvents.DELETED,
object: "price_rule", object: "price_rule",
@@ -692,11 +692,11 @@ moduleIntegrationTestRunner<IProductModuleService>({
[ [
expect.objectContaining({ expect.objectContaining({
data: { id: productCategoryOne.id }, data: { id: productCategoryOne.id },
name: "product-category.deleted", name: "Product.product-category.deleted",
metadata: { metadata: {
action: "", action: CommonEvents.DELETED,
object: "", object: "product_category",
source: "", source: Modules.PRODUCT,
}, },
}), }),
], ],
@@ -1,5 +1,5 @@
import { IProductModuleService } from "@medusajs/types" import { IProductModuleService } from "@medusajs/types"
import { Modules, ProductStatus } from "@medusajs/utils" import { CommonEvents, Modules, ProductStatus } from "@medusajs/utils"
import { Product, ProductCollection } from "@models" import { Product, ProductCollection } from "@models"
import { import {
MockEventBusService, MockEventBusService,
@@ -281,12 +281,12 @@ moduleIntegrationTestRunner<IProductModuleService>({
expect(eventBusSpy).toHaveBeenCalledWith( expect(eventBusSpy).toHaveBeenCalledWith(
[ [
{ {
name: "product-collection.deleted", name: "Product.product-collection.deleted",
data: { id: collectionId }, data: { id: collectionId },
metadata: { metadata: {
action: "", action: CommonEvents.DELETED,
object: "", object: "product_collection",
source: "", source: Modules.PRODUCT,
}, },
}, },
], ],
+19 -19
View File
@@ -1,114 +1,114 @@
import { import {
CommonEvents, CommonEvents,
eventBuilderFactory, moduleEventBuilderFactory,
Modules, Modules,
ProductEvents, ProductEvents,
} from "@medusajs/utils" } from "@medusajs/utils"
export const eventBuilders = { export const eventBuilders = {
createdProduct: eventBuilderFactory({ createdProduct: moduleEventBuilderFactory({
source: Modules.PRODUCT, source: Modules.PRODUCT,
action: CommonEvents.CREATED, action: CommonEvents.CREATED,
object: "product", object: "product",
eventsEnum: ProductEvents, eventsEnum: ProductEvents,
}), }),
updatedProduct: eventBuilderFactory({ updatedProduct: moduleEventBuilderFactory({
source: Modules.PRODUCT, source: Modules.PRODUCT,
action: CommonEvents.UPDATED, action: CommonEvents.UPDATED,
object: "product", object: "product",
eventsEnum: ProductEvents, eventsEnum: ProductEvents,
}), }),
deletedProduct: eventBuilderFactory({ deletedProduct: moduleEventBuilderFactory({
source: Modules.PRODUCT, source: Modules.PRODUCT,
action: CommonEvents.DELETED, action: CommonEvents.DELETED,
object: "product", object: "product",
eventsEnum: ProductEvents, eventsEnum: ProductEvents,
}), }),
createdProductVariant: eventBuilderFactory({ createdProductVariant: moduleEventBuilderFactory({
source: Modules.PRODUCT, source: Modules.PRODUCT,
action: CommonEvents.CREATED, action: CommonEvents.CREATED,
object: "product_variant", object: "product_variant",
eventsEnum: ProductEvents, eventsEnum: ProductEvents,
}), }),
updatedProductVariant: eventBuilderFactory({ updatedProductVariant: moduleEventBuilderFactory({
source: Modules.PRODUCT, source: Modules.PRODUCT,
action: CommonEvents.UPDATED, action: CommonEvents.UPDATED,
object: "product_variant", object: "product_variant",
eventsEnum: ProductEvents, eventsEnum: ProductEvents,
}), }),
deletedProductVariant: eventBuilderFactory({ deletedProductVariant: moduleEventBuilderFactory({
source: Modules.PRODUCT, source: Modules.PRODUCT,
action: CommonEvents.DELETED, action: CommonEvents.DELETED,
object: "product_variant", object: "product_variant",
eventsEnum: ProductEvents, eventsEnum: ProductEvents,
}), }),
createdProductOption: eventBuilderFactory({ createdProductOption: moduleEventBuilderFactory({
source: Modules.PRODUCT, source: Modules.PRODUCT,
action: CommonEvents.CREATED, action: CommonEvents.CREATED,
object: "product_option", object: "product_option",
eventsEnum: ProductEvents, eventsEnum: ProductEvents,
}), }),
updatedProductOption: eventBuilderFactory({ updatedProductOption: moduleEventBuilderFactory({
source: Modules.PRODUCT, source: Modules.PRODUCT,
action: CommonEvents.UPDATED, action: CommonEvents.UPDATED,
object: "product_option", object: "product_option",
eventsEnum: ProductEvents, eventsEnum: ProductEvents,
}), }),
deletedProductOption: eventBuilderFactory({ deletedProductOption: moduleEventBuilderFactory({
source: Modules.PRODUCT, source: Modules.PRODUCT,
action: CommonEvents.DELETED, action: CommonEvents.DELETED,
object: "product_option", object: "product_option",
eventsEnum: ProductEvents, eventsEnum: ProductEvents,
}), }),
createdProductType: eventBuilderFactory({ createdProductType: moduleEventBuilderFactory({
source: Modules.PRODUCT, source: Modules.PRODUCT,
action: CommonEvents.CREATED, action: CommonEvents.CREATED,
object: "product_type", object: "product_type",
eventsEnum: ProductEvents, eventsEnum: ProductEvents,
}), }),
updatedProductType: eventBuilderFactory({ updatedProductType: moduleEventBuilderFactory({
source: Modules.PRODUCT, source: Modules.PRODUCT,
action: CommonEvents.UPDATED, action: CommonEvents.UPDATED,
object: "product_type", object: "product_type",
eventsEnum: ProductEvents, eventsEnum: ProductEvents,
}), }),
deletedProductType: eventBuilderFactory({ deletedProductType: moduleEventBuilderFactory({
source: Modules.PRODUCT, source: Modules.PRODUCT,
action: CommonEvents.DELETED, action: CommonEvents.DELETED,
object: "product_type", object: "product_type",
eventsEnum: ProductEvents, eventsEnum: ProductEvents,
}), }),
createdProductTag: eventBuilderFactory({ createdProductTag: moduleEventBuilderFactory({
source: Modules.PRODUCT, source: Modules.PRODUCT,
action: CommonEvents.CREATED, action: CommonEvents.CREATED,
object: "product_tag", object: "product_tag",
eventsEnum: ProductEvents, eventsEnum: ProductEvents,
}), }),
updatedProductTag: eventBuilderFactory({ updatedProductTag: moduleEventBuilderFactory({
source: Modules.PRODUCT, source: Modules.PRODUCT,
action: CommonEvents.UPDATED, action: CommonEvents.UPDATED,
object: "product_tag", object: "product_tag",
eventsEnum: ProductEvents, eventsEnum: ProductEvents,
}), }),
deletedProductTag: eventBuilderFactory({ deletedProductTag: moduleEventBuilderFactory({
source: Modules.PRODUCT, source: Modules.PRODUCT,
action: CommonEvents.DELETED, action: CommonEvents.DELETED,
object: "product_tag", object: "product_tag",
eventsEnum: ProductEvents, eventsEnum: ProductEvents,
}), }),
createdProductCategory: eventBuilderFactory({ createdProductCategory: moduleEventBuilderFactory({
source: Modules.PRODUCT, source: Modules.PRODUCT,
action: CommonEvents.CREATED, action: CommonEvents.CREATED,
object: "product_category", object: "product_category",
eventsEnum: ProductEvents, eventsEnum: ProductEvents,
}), }),
updatedProductCategory: eventBuilderFactory({ updatedProductCategory: moduleEventBuilderFactory({
source: Modules.PRODUCT, source: Modules.PRODUCT,
action: CommonEvents.UPDATED, action: CommonEvents.UPDATED,
object: "product_category", object: "product_category",
eventsEnum: ProductEvents, eventsEnum: ProductEvents,
}), }),
deletedProductCategory: eventBuilderFactory({ deletedProductCategory: moduleEventBuilderFactory({
source: Modules.PRODUCT, source: Modules.PRODUCT,
action: CommonEvents.DELETED, action: CommonEvents.DELETED,
object: "product_category", object: "product_category",