I replaced the custom test setup with the test runner. This should make migrating to mikroorm 6 a lot easier once we do it.
There are few more modules to be done, but I thought the PR is super big already so we can tackle them separately.
Note that there are no or very little test changes, it is mostly the setup around the tests.
what:
- promotion modules (application method and campaign budget) uses big number fields instead of numeric fields
- refreshes the migrations to include new fields for big numbers
- adds a promotion_ prefix to promotion models
- uses `take: null` within the module to prevent the default pagination on performing actions within the module
what:
- adds API + workflow to add/remove promotions in a cart
- minor fixes in promotions module
- minor type fixes in cart module
- typing fix in workflows-sdk (Thanks @adrien2p)
- fix step result in workflows-sdk (Thanks @adrien2p)
RESOLVES CORE-1768
Co-authored-by: Adrien de Peretti <25098370+adrien2p@users.noreply.github.com>
**What**
> [!NOTE]
> I can see this pr becoming huge, so I d like to get this partial one merged 👍
- Fixes shared connection usage (mikro orm compare the instance to its own package and therefore was resulting in not trully reusing the provided connection leading to exhausting the connection pool as multiple connections was created and end up not being all destroyed properly under the hood, discovered in my integration tests)
- Create shipping options method implementation
- DTO's definition and service interface update
- integration tests
- Re work of the indexes with new util update
- Test runner utils to remove a big chunk of the boilerplate of the packages integrations
FIXES CORE-1742
What:
- Event Aggregator Util
- Preparation for normalizing event in a new format (backward compatible with the current format)
- GQL Schema to joiner config and some Entities configured
- Link modules emmiting events
**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[]>
}
```
What:
- When calling a module's method inside a Local Workflow the MedusaContext is passed as the last argument to the method if not provided
- Add `requestId` to req
- A couple of fixes on Remote Joiner and the data fetcher for internal services
Why:
- The context used to initialize the workflow has to be shared with all modules. properties like transactionId will be used to emit events and requestId to trace logs for example.
what:
- adds create endpoint for promotions including workflows and endpoint (RESOLVES CORE-1678)
- adds update endpoint for promotions including workflows and endpoint (RESOLVES CORE-1679)
- adds create endpoint for campaigns including workflows and endpoint (RESOLVES CORE-1684)
- adds update endpoint for campaigns including workflows and endpoint (RESOLVES CORE-1685)
**What**
Create a service abstraction for the modules internal service layer. The objective is to reduce the effort of building new modules when the logic is the same or otherwise allow to override the default behavior.
Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
* chore: added item/shipping adjustments for order/items/shipping_methods
* chore: add validation for order type and target rules
* chore: add comment for applied promotions
* chore: add shipping method and item adjustments
* chore: include applied promotions to items/shipping_method for each case
* chore: handle case for items across and order to consider existing applications
* chore: handle case for applied promo values to shipping => across
* chore: added changeset
* chore: update return of function
* chore: campaigns and campaign budgets + services CRUD
* Apply suggestions from code review
Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
* chore: minor refactor
* chore: added single/bulk interfaces
* Apply suggestions from code review
Co-authored-by: Philip Korsholm <88927411+pKorsholm@users.noreply.github.com>
* chore: use DAL date entity
* chore: align nullable
* Update packages/promotion/src/models/promotion-rule.ts
* chore: fix types
* chore: review changes
* Update packages/promotion/src/utils/compute-actions/shipping-methods.ts
Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
---------
Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
Co-authored-by: Philip Korsholm <88927411+pKorsholm@users.noreply.github.com>
what:
- adds compute actions for the following cases:
- items => each & across
- shipping_method => each & across
- order
- adds a remove compute actions when code is no longer present in adjustments array
RESOLVES CORE-1625
RESOLVES CORE-1626
RESOLVES CORE-1627
RESOLVES CORE-1628
RESOLVES CORE-1585
**What**
Reduce the work effort to create repositories when building new modules by abstracting the most common cases into the base class default implementation returned by a factory
- [x] Migrate all modules
Co-authored-by: Riqwan Thamir <5105988+riqwan@users.noreply.github.com>
* feat(types,utils): added promotion create with rules
* chore: add rules to promotion and application method
* chore: use common code for rule and values
* chore: address pr reviews
* chore: fix test
What:
- Promotions can be created with its bare attributes
- Promotions one to one relationship with ApplicationMethod can be created with its attributes + validation
RESOLVES CORE-1592
RESOLVES CORE-1595