UNPKG

@vendure/core

Version:

A modern, headless ecommerce framework

329 lines (328 loc) 13.3 kB
import { ConfigArg } from '@vendure/common/lib/generated-types'; import { RequestContext } from '../../api/common/request-context'; import { ConfigArgs, ConfigArgValues, ConfigurableOperationDef, ConfigurableOperationDefOptions } from '../../common/configurable-operation'; import { Promotion, PromotionState } from '../../entity'; import { Order } from '../../entity/order/order.entity'; import { OrderLine } from '../../entity/order-line/order-line.entity'; import { ShippingLine } from '../../entity/shipping-line/shipping-line.entity'; import { PromotionCondition } from './promotion-condition'; /** * Unwrap a promise type */ type Awaited<T> = T extends PromiseLike<infer U> ? Awaited<U> : T; /** * Extract the (non-false) return value of the PromotionCondition "check" function. */ type ConditionCheckReturnType<T extends PromotionCondition<any>> = Exclude<Awaited<ReturnType<T['check']>>, false>; /** * Converts an array of PromotionCondition types into a tuple, thus preserving the * distinct type of each condition in the array. */ export type ConditionTuple<C extends Array<PromotionCondition<any>>> = [...C]; /** * Converts an array of PromotionConditions into a tuple of the type: * [<condition code>, <check function return value>] */ type CodesStateTuple<T extends ConditionTuple<Array<PromotionCondition<any>>>> = { [K in keyof T]: T[K] extends PromotionCondition<any> ? [T[K]['code'], ConditionCheckReturnType<T[K]>] : never; }; /** * Convert a tuple into a union * [[string, number], [number, boolean]] => [string, number] | [number, boolean] */ type TupleToUnion<T extends any[]> = T[number]; /** * Converts an array of PromotionConditions into an object of the type: * { * [PromotionCondition.code]: ReturnType<PromotionCondition.check()> * } */ export type ConditionState<U extends Array<PromotionCondition<any>>, T extends [string, any] = TupleToUnion<CodesStateTuple<ConditionTuple<U>>>> = { [key in T[0]]: Extract<T, [key, any]>[1]; }; /** * @description * The function which is used by a PromotionItemAction to calculate the * discount on the OrderLine for each item. * * @docsCategory promotions * @docsPage promotion-action */ export type ExecutePromotionItemActionFn<T extends ConfigArgs, U extends Array<PromotionCondition<any>>> = (ctx: RequestContext, orderLine: OrderLine, args: ConfigArgValues<T>, state: ConditionState<U>, promotion: Promotion) => number | Promise<number>; /** * @description * The function which is used by a PromotionLineAction to calculate the * discount on the OrderLine. * * @docsCategory promotions * @docsPage promotion-action */ export type ExecutePromotionLineActionFn<T extends ConfigArgs, U extends Array<PromotionCondition<any>>> = (ctx: RequestContext, orderLine: OrderLine, args: ConfigArgValues<T>, state: ConditionState<U>, promotion: Promotion) => number | Promise<number>; /** * @description * The function which is used by a PromotionOrderAction to calculate the * discount on the Order. * * @docsCategory promotions * @docsPage promotion-action */ export type ExecutePromotionOrderActionFn<T extends ConfigArgs, U extends Array<PromotionCondition<any>>> = (ctx: RequestContext, order: Order, args: ConfigArgValues<T>, state: ConditionState<U>, promotion: Promotion) => number | Promise<number>; /** * @description * The function which is used by a PromotionOrderAction to calculate the * discount on the Order. * * @docsCategory promotions * @docsPage promotion-action */ export type ExecutePromotionShippingActionFn<T extends ConfigArgs, U extends Array<PromotionCondition<any>>> = (ctx: RequestContext, shippingLine: ShippingLine, order: Order, args: ConfigArgValues<T>, state: ConditionState<U>, promotion: Promotion) => number | Promise<number>; /** * @description * The signature of a PromotionAction's side-effect functions `onActivate` and `onDeactivate`. * * @docsCategory promotions * @docsPage promotion-action * @since 1.8.0 * @experimental */ type PromotionActionSideEffectFn<T extends ConfigArgs> = (ctx: RequestContext, order: Order, args: ConfigArgValues<T>, promotion: Promotion) => void | Promise<void>; /** * @description * Configuration for all types of {@link PromotionAction}. * * @docsCategory promotions * @docsPage promotion-action */ export interface PromotionActionConfig<T extends ConfigArgs, U extends Array<PromotionCondition<any>> | undefined> extends ConfigurableOperationDefOptions<T> { /** * @description * Used to determine the order of application of multiple Promotions * on the same Order. See the {@link Promotion} `priorityScore` field for * more information. * * @default 0 */ priorityValue?: number; /** * @description * Allows PromotionActions to define one or more PromotionConditions as dependencies. Having a PromotionCondition * as a dependency has the following consequences: * 1. A Promotion using this PromotionAction is only valid if it also contains all PromotionConditions * on which it depends. * 2. The `execute()` function will receive a statically-typed `state` argument which will contain * the return values of the PromotionConditions' `check()` function. */ conditions?: U extends undefined ? undefined : ConditionTuple<Exclude<U, undefined>>; /** * @description * An optional side effect function which is invoked when the promotion * becomes active. It can be used for things like adding a free gift to the order * or other side effects that are unrelated to price calculations. * * If used, make sure to use the corresponding `onDeactivate` function to clean up * or reverse any side effects as needed. * * @since 1.8.0 * @experimental */ onActivate?: PromotionActionSideEffectFn<T>; /** * @description * Used to reverse or clean up any side effects executed as part of the `onActivate` function. * * @since 1.8.0 * @experimental */ onDeactivate?: PromotionActionSideEffectFn<T>; } /** * @description * Configuration for a {@link PromotionItemAction} * * @docsCategory promotions * @docsPage promotion-action */ export interface PromotionItemActionConfig<T extends ConfigArgs, U extends PromotionCondition[]> extends PromotionActionConfig<T, U> { /** * @description * The function which contains the promotion calculation logic. * Should resolve to a number which represents the amount by which to discount * the OrderLine, i.e. the number should be negative. */ execute: ExecutePromotionItemActionFn<T, U>; } /** * @description * Configuration for a {@link PromotionLineAction} * * @docsCategory promotions * @docsPage promotion-action */ export interface PromotionLineActionConfig<T extends ConfigArgs, U extends PromotionCondition[]> extends PromotionActionConfig<T, U> { /** * @description * The function which contains the promotion calculation logic. * Should resolve to a number which represents the amount by which to discount * the OrderLine, i.e. the number should be negative. */ execute: ExecutePromotionLineActionFn<T, U>; } /** * @description * * @docsCategory promotions * @docsPage promotion-action */ export interface PromotionOrderActionConfig<T extends ConfigArgs, U extends PromotionCondition[]> extends PromotionActionConfig<T, U> { /** * @description * The function which contains the promotion calculation logic. * Should resolve to a number which represents the amount by which to discount * the Order, i.e. the number should be negative. */ execute: ExecutePromotionOrderActionFn<T, U>; } /** * @description * * @docsCategory promotions * @docsPage promotion-action */ export interface PromotionShippingActionConfig<T extends ConfigArgs, U extends PromotionCondition[]> extends PromotionActionConfig<T, U> { /** * @description * The function which contains the promotion calculation logic. * Should resolve to a number which represents the amount by which to discount * the Shipping, i.e. the number should be negative. */ execute: ExecutePromotionShippingActionFn<T, U>; } /** * @description * An abstract class which is extended by {@link PromotionItemAction}, {@link PromotionOrderAction}, * and {@link PromotionShippingAction}. * * @docsCategory promotions * @docsPage promotion-action * @docsWeight 0 */ export declare abstract class PromotionAction<T extends ConfigArgs = ConfigArgs, U extends PromotionCondition[] | undefined = any> extends ConfigurableOperationDef<T> { /** * @description * Used to determine the order of application of multiple Promotions * on the same Order. See the {@link Promotion} `priorityScore` field for * more information. * * @default 0 */ readonly priorityValue: number; /** @internal */ readonly conditions?: U; /** @internal */ protected readonly onActivateFn?: PromotionActionSideEffectFn<T>; /** @internal */ protected readonly onDeactivateFn?: PromotionActionSideEffectFn<T>; protected constructor(config: PromotionActionConfig<T, U>); /** @internal */ abstract execute(...arg: any[]): number | Promise<number>; /** @internal */ onActivate(ctx: RequestContext, order: Order, args: ConfigArg[], promotion: Promotion): void | Promise<void>; /** @internal */ onDeactivate(ctx: RequestContext, order: Order, args: ConfigArg[], promotion: Promotion): void | Promise<void>; } /** * @description * Represents a PromotionAction which applies to individual {@link OrderLine}s. * * @example * ```ts * // Applies a percentage discount to each OrderLine * const itemPercentageDiscount = new PromotionItemAction({ * code: 'item_percentage_discount', * args: { discount: 'percentage' }, * execute(ctx, orderLine, args) { * return -orderLine.unitPrice * (args.discount / 100); * }, * description: 'Discount every item by { discount }%', * }); * ``` * * @docsCategory promotions * @docsPage promotion-action * @docsWeight 1 */ export declare class PromotionItemAction<T extends ConfigArgs = ConfigArgs, U extends Array<PromotionCondition<any>> = []> extends PromotionAction<T, U> { private readonly executeFn; constructor(config: PromotionItemActionConfig<T, U>); /** @internal */ execute(ctx: RequestContext, orderLine: OrderLine, args: ConfigArg[], state: PromotionState, promotion: Promotion): number | Promise<number>; } /** * @description * Represents a PromotionAction which applies to individual {@link OrderLine}s. * The difference from PromotionItemAction is that it applies regardless of the Quantity of the OrderLine. * * @example * ```ts * // Applies a percentage discount to each OrderLine * const linePercentageDiscount = new PromotionLineAction({ * code: 'line_percentage_discount', * args: { discount: 'percentage' }, * execute(ctx, orderLine, args) { * return -orderLine.linePrice * (args.discount / 100); * }, * description: 'Discount every line by { discount }%', * }); * ``` * * @docsCategory promotions * @docsPage promotion-action */ export declare class PromotionLineAction<T extends ConfigArgs = ConfigArgs, U extends Array<PromotionCondition<any>> = []> extends PromotionAction<T, U> { private readonly executeFn; constructor(config: PromotionLineActionConfig<T, U>); /** @internal */ execute(ctx: RequestContext, orderLine: OrderLine, args: ConfigArg[], state: PromotionState, promotion: Promotion): number | Promise<number>; } /** * @description * Represents a PromotionAction which applies to the {@link Order} as a whole. * * @example * ```ts * // Applies a percentage discount to the entire Order * const orderPercentageDiscount = new PromotionOrderAction({ * code: 'order_percentage_discount', * args: { discount: 'percentage' }, * execute(ctx, order, args) { * return -order.subTotal * (args.discount / 100); * }, * description: 'Discount order by { discount }%', * }); * ``` * * @docsCategory promotions * @docsPage promotion-action * @docsWeight 2 */ export declare class PromotionOrderAction<T extends ConfigArgs = ConfigArgs, U extends PromotionCondition[] = []> extends PromotionAction<T, U> { private readonly executeFn; constructor(config: PromotionOrderActionConfig<T, U>); /** @internal */ execute(ctx: RequestContext, order: Order, args: ConfigArg[], state: PromotionState, promotion: Promotion): number | Promise<number>; } /** * @description * Represents a PromotionAction which applies to the shipping cost of an Order. * * @docsCategory promotions * @docsPage promotion-action * @docsWeight 3 */ export declare class PromotionShippingAction<T extends ConfigArgs = ConfigArgs, U extends PromotionCondition[] = []> extends PromotionAction<T, U> { private readonly executeFn; constructor(config: PromotionShippingActionConfig<T, U>); /** @internal */ execute(ctx: RequestContext, shippingLine: ShippingLine, order: Order, args: ConfigArg[], state: PromotionState, promotion: Promotion): number | Promise<number>; } export {};