Skip to content

Commit

Permalink
feat(cart): create injection tokens with factory (#3235)
Browse files Browse the repository at this point in the history
  • Loading branch information
griest024 authored Oct 14, 2024
1 parent 8f078f5 commit e536798
Show file tree
Hide file tree
Showing 37 changed files with 358 additions and 350 deletions.
Original file line number Diff line number Diff line change
@@ -1,29 +1,32 @@
import { InjectionToken } from '@angular/core';
import { RequestInfo } from 'angular-in-memory-web-api';

import { DaffCart } from '@daffodil/cart';
import { createSingleInjectionToken } from '@daffodil/core';

export type DaffCartInMemoryExtraAttributesHook = (reqInfo: RequestInfo, cart: DaffCart) => Record<string, any>;

/**
* Allows an app dev to generate extra fields in the in-memory backend.
* This enables the in-memory drivers to return responses similar to what the
* frontend would expect from the production platform.
*
* The value returned by the hook function will be set to the returned cart's `extra_attributes` field
* for driver calls that return a cart.
*
* The following example demonstrates adding the `numberOfCartItems` field to `extra_attributes`:
* ```ts
* (reqInfo: RequestInfo, cart: DaffCart) => ({
* numberOfCartItems: cart.items.length
* })
* ```
*
* Note that this and any `extra_attributes` features are for advanced users
* and should be used with care.
*/
export const DAFF_CART_IN_MEMORY_EXTRA_ATTRIBUTES_HOOK =
new InjectionToken<DaffCartInMemoryExtraAttributesHook>('DAFF_CART_IN_MEMORY_EXTRA_ATTRIBUTES_HOOK', {
factory: () => (reqInfo, cart) => ({}),
});
export const {
/**
* Allows an app dev to generate extra fields in the in-memory backend.
* This enables the in-memory drivers to return responses similar to what the
* frontend would expect from the production platform.
*
* The value returned by the hook function will be set to the returned cart's `extra_attributes` field
* for driver calls that return a cart.
*
* The following example demonstrates adding the `numberOfCartItems` field to `extra_attributes`:
* ```ts
* (reqInfo: RequestInfo, cart: DaffCart) => ({
* numberOfCartItems: cart.items.length
* })
* ```
*
* Note that this and any `extra_attributes` features are for advanced users
* and should be used with care.
*/
token: DAFF_CART_IN_MEMORY_EXTRA_ATTRIBUTES_HOOK,
provider: daffProvideCartInMemoryExtraAttributesHook,
} = createSingleInjectionToken<DaffCartInMemoryExtraAttributesHook>(
'DAFF_CART_IN_MEMORY_EXTRA_ATTRIBUTES_HOOK',
{ factory: () => (reqInfo, cart) => ({}) },
);
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import {
inject,
InjectionToken,
} from '@angular/core';
import { inject } from '@angular/core';
import { Apollo } from 'apollo-angular';

import { createSingleInjectionToken } from '@daffodil/core';
import { DaffQueuedApollo } from '@daffodil/core/graphql';

export const DAFF_MAGENTO_CART_MUTATION_QUEUE = new InjectionToken<DaffQueuedApollo>('DAFF_MAGENTO_CART_MUTATION_QUEUE', {
providedIn: 'root',
factory: () => new DaffQueuedApollo(inject(Apollo)),
});
export const {
token: DAFF_MAGENTO_CART_MUTATION_QUEUE,
provider: daffProvideCartMagentoMutationQueue,
} = createSingleInjectionToken<DaffQueuedApollo>(
'DAFF_MAGENTO_CART_MUTATION_QUEUE', {
providedIn: 'root',
factory: () => new DaffQueuedApollo(inject(Apollo)),
},
);
35 changes: 18 additions & 17 deletions libs/cart/driver/magento/src/injection-tokens/fragments/cart.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import { InjectionToken } from '@angular/core';
import { DocumentNode } from 'graphql';

/**
* An multi-provider injection token for providing extra GraphQL fragments that will be spread into cart queries.
* This can be used to retrieve additional data that is not covered by the standard Daffodil interfaces.
* The data will appear in DaffCart#extra_attributes.
*
* Fragment structure is platform-specific and this feature should be used with care.
*
* This can increase query complexity above the Magento default of 300.
* Daffodil only guarantees that stock queries don't exceed the limit of 300.
* Apps using this token should therefore increase the query complexity limit
* to accommodate the extra complexity contributed by the provided fragments.
*/
export const DAFF_CART_MAGENTO_EXTRA_CART_FRAGMENTS = new InjectionToken<DocumentNode[]>(
'DAFF_CART_MAGENTO_EXTRA_CART_FRAGMENTS',
{ factory: () => []},
);
import { createMultiInjectionToken } from '@daffodil/core';

export const {
/**
* An multi-provider injection token for providing extra GraphQL fragments that will be spread into cart queries.
* This can be used to retrieve additional data that is not covered by the standard Daffodil interfaces.
* The data will appear in DaffCart#extra_attributes.
*
* Fragment structure is platform-specific and this feature should be used with care.
*
* This can increase query complexity above the Magento default of 300.
* Daffodil only guarantees that stock queries don't exceed the limit of 300.
* Apps using this token should therefore increase the query complexity limit
* to accommodate the extra complexity contributed by the provided fragments.
*/
token: DAFF_CART_MAGENTO_EXTRA_CART_FRAGMENTS,
provider: daffProvideCartMagentoExtraCartFragments,
} = createMultiInjectionToken<DocumentNode>('DAFF_CART_MAGENTO_EXTRA_CART_FRAGMENTS');
Original file line number Diff line number Diff line change
@@ -1,39 +1,28 @@
import {
InjectionToken,
Provider,
} from '@angular/core';

// workaround https://github.com/graycoreio/daffodil/issues/1667
import { DaffCartItem } from '@daffodil/cart';
import { createMultiInjectionToken } from '@daffodil/core';

import { DaffCartMagentoCartItemTransform } from '../../../interfaces/public_api';

/**
* A multi-provider injection token for providing cart item transform logic in the Magento driver.
* It is run after the standard transforms and passed both the current transformed Daffodil cart item and the Magento cart item.
*/
export const DAFF_CART_MAGENTO_CART_ITEM_TRANSFORMS = new InjectionToken<DaffCartMagentoCartItemTransform[]>(
'DAFF_CART_MAGENTO_CART_ITEM_TRANSFORMS',
{ factory: () => []},
);
export const {
/**
* A multi-provider injection token for providing cart item transform logic in the Magento driver.
* It is run after the standard transforms and passed both the current transformed Daffodil cart item and the Magento cart item.
*/
token: DAFF_CART_MAGENTO_CART_ITEM_TRANSFORMS,

/**
* Provides cart item transforms for the Magento cart driver.
*
* See {@link DAFF_CART_MAGENTO_CART_ITEM_TRANSFORMS}.
*
* ```ts
* providers: [
* ...daffProvideCartMagentoCartItemTransforms(
* myCartItemTransform
* )
* ]
* ```
*/
export function daffProvideCartMagentoCartItemTransforms(...transforms: DaffCartMagentoCartItemTransform[]): Provider[] {
return transforms.map(transform => ({
provide: DAFF_CART_MAGENTO_CART_ITEM_TRANSFORMS,
useValue: transform,
multi: true,
}));
}
/**
* Provides cart item transforms for the Magento cart driver.
*
* See {@link DAFF_CART_MAGENTO_CART_ITEM_TRANSFORMS}.
*
* ```ts
* providers: [
* ...daffProvideCartMagentoCartItemTransforms(
* myCartItemTransform
* )
* ]
* ```
*/
provider: daffProvideCartMagentoCartItemTransforms,
} = createMultiInjectionToken<DaffCartMagentoCartItemTransform>('DAFF_CART_MAGENTO_CART_ITEM_TRANSFORMS');
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,28 @@ import {

// workaround https://github.com/graycoreio/daffodil/issues/1667
import { DaffCart } from '@daffodil/cart';
import { createMultiInjectionToken } from '@daffodil/core';

import { DaffCartMagentoCartTransform } from '../../../interfaces/public_api';

/**
* A multi-provider injection token for providing cart transform logic in the Magento driver.
* It is run after the standard transforms and passed both the current transformed Daffodil cart and the Magento cart.
*/
export const DAFF_CART_MAGENTO_CART_TRANSFORMS = new InjectionToken<DaffCartMagentoCartTransform[]>(
'DAFF_CART_MAGENTO_CART_TRANSFORMS',
{ factory: () => []},
);

/**
* Provides cart transforms for the Magento cart driver.
*
* See {@link DAFF_CART_MAGENTO_CART_TRANSFORMS}.
*
* ```ts
* providers: [
* ...daffProvideCartMagentoCartTransforms(
* myCartTransform
* )
* ]
* ```
*/
export function daffProvideCartMagentoCartTransforms(...transforms: DaffCartMagentoCartTransform[]): Provider[] {
return transforms.map(transform => ({
provide: DAFF_CART_MAGENTO_CART_TRANSFORMS,
useValue: transform,
multi: true,
}));
}
export const {
/**
* A multi-provider injection token for providing cart transform logic in the Magento driver.
* It is run after the standard transforms and passed both the current transformed Daffodil cart and the Magento cart.
*/
token: DAFF_CART_MAGENTO_CART_TRANSFORMS,
/**
* Provides cart transforms for the Magento cart driver.
*
* See {@link DAFF_CART_MAGENTO_CART_TRANSFORMS}.
*
* ```ts
* providers: [
* ...daffProvideCartMagentoCartTransforms(
* myCartTransform
* )
* ]
* ```
*/
provider: daffProvideCartMagentoCartTransforms,
} = createMultiInjectionToken<DaffCartMagentoCartTransform>('DAFF_CART_MAGENTO_CART_TRANSFORMS');
37 changes: 14 additions & 23 deletions libs/cart/driver/src/injection-tokens/free-payment-method.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,17 @@
import {
InjectionToken,
ValueProvider,
} from '@angular/core';

import { DaffCartPaymentMethod } from '@daffodil/cart';
import { createSingleInjectionToken } from '@daffodil/core';

/**
* The payment method payload that correspondes to the free payment method.
* This will be different per-platform and can be passed into the update driver call.
*/
export const DAFF_CART_DRIVER_FREE_PAYMENT_METHOD = new InjectionToken<Partial<DaffCartPaymentMethod>>(
export const {
/**
* The payment method payload that correspondes to the free payment method.
* This will be different per-platform and can be passed into the update driver call.
*/
token: DAFF_CART_DRIVER_FREE_PAYMENT_METHOD,
/**
* Provides the {@link DAFF_CART_DRIVER_FREE_PAYMENT_METHOD} injection token.
*/
provider: daffCartDriverProvideFreePaymentMethod,
} = createSingleInjectionToken<Partial<DaffCartPaymentMethod>>(
'DAFF_CART_DRIVER_FREE_PAYMENT_METHOD',
{
factory: () => ({}),
});

/**
* Provides the {@link DAFF_CART_DRIVER_FREE_PAYMENT_METHOD} injection token.
*/
export function daffCartDriverProvideFreePaymentMethod(method: Partial<DaffCartPaymentMethod>): ValueProvider {
return {
provide: DAFF_CART_DRIVER_FREE_PAYMENT_METHOD,
useValue: method,
};
}
{ factory: () => ({}) },
);
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { InjectionToken } from '@angular/core';
import { Observable } from 'rxjs';

import { DaffCart } from '@daffodil/cart';
import {
DaffCartAddress,
DaffCart,
} from '@daffodil/cart';
import { createSingleInjectionToken } from '@daffodil/core';

/**
* The interface responsible for managing the address of a cart.
Expand All @@ -13,6 +16,7 @@ export interface DaffCartAddressServiceInterface<T extends DaffCart = DaffCart>
update(cartId: T['id'], address: Partial<T['shipping_address'] | T['billing_address']>): Observable<Partial<T>>;
}

export const DaffCartAddressDriver = new InjectionToken<
DaffCartAddressServiceInterface
>('DaffCartAddressDriver');
export const {
token: DaffCartAddressDriver,
provider: daffProvideCartAddressDriver,
} = createSingleInjectionToken<DaffCartAddressServiceInterface>('DaffCartAddressDriver');
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { InjectionToken } from '@angular/core';
import { Observable } from 'rxjs';

import { DaffCart } from '@daffodil/cart';
import {
DaffCartAddress,
DaffCart,
} from '@daffodil/cart';
import { createSingleInjectionToken } from '@daffodil/core';

/**
* The interface responsible for managing the billing address of a cart.
Expand All @@ -18,6 +21,7 @@ export interface DaffCartBillingAddressServiceInterface<T extends DaffCart = Daf
update(cartId: T['id'], address: Partial<T['billing_address']>): Observable<Partial<T>>;
}

export const DaffCartBillingAddressDriver = new InjectionToken<
DaffCartBillingAddressServiceInterface
>('DaffCartBillingAddressDriver');
export const {
token: DaffCartBillingAddressDriver,
provider: daffProvideCartBillingAddressDriver,
} = createSingleInjectionToken<DaffCartBillingAddressServiceInterface>('DaffCartBillingAddressDriver');
14 changes: 9 additions & 5 deletions libs/cart/driver/src/interfaces/cart-coupon-service.interface.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { InjectionToken } from '@angular/core';
import { Observable } from 'rxjs';

import { DaffCart } from '@daffodil/cart';
import {
DaffCart,
DaffCartCoupon,
} from '@daffodil/cart';
import { createSingleInjectionToken } from '@daffodil/core';

/**
* The interface responsible for applying a coupon to a cart.
Expand All @@ -28,6 +31,7 @@ export interface DaffCartCouponServiceInterface<T extends DaffCart = DaffCart> {
removeAll(cartId: T['id']): Observable<Partial<T>>;
}

export const DaffCartCouponDriver = new InjectionToken<DaffCartCouponServiceInterface>(
'DaffCartCouponDriver',
);
export const {
token: DaffCartCouponDriver,
provider: daffProvideCartCouponDriver,
} = createSingleInjectionToken<DaffCartCouponServiceInterface>('DaffCartCouponDriver');
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { InjectionToken } from '@angular/core';
import { Observable } from 'rxjs';

import {
DaffCartItem,
DaffCartItemInput,
DaffCart,
} from '@daffodil/cart';
import { createSingleInjectionToken } from '@daffodil/core';

/**
* The interface responsible for managing the items of a cart.
Expand Down Expand Up @@ -44,6 +44,7 @@ export interface DaffCartItemServiceInterface<
delete(cartId: T['id'], itemId: T['items'][number]['id']): Observable<Partial<T>>;
}

export const DaffCartItemDriver = new InjectionToken<
DaffCartItemServiceInterface
>('DaffCartItemDriver');
export const {
token: DaffCartItemDriver,
provider: daffProvideCartItemDriver,
} = createSingleInjectionToken<DaffCartItemServiceInterface>('DaffCartItemDriver');
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { InjectionToken } from '@angular/core';
import { Observable } from 'rxjs';

import {
DaffCart,
DaffCartOrderResult,
} from '@daffodil/cart';
import { createSingleInjectionToken } from '@daffodil/core';

/**
* The interface responsible for placing an order for the customer's cart.
Expand All @@ -19,6 +19,7 @@ export interface DaffCartOrderServiceInterface<
placeOrder(id: T['id'], payment?: T['payment']): Observable<R>;
}

export const DaffCartOrderDriver = new InjectionToken<DaffCartOrderServiceInterface>(
'DaffCartOrderDriver',
);
export const {
token: DaffCartOrderDriver,
provider: daffProvideCartOrderDriver,
} = createSingleInjectionToken<DaffCartOrderServiceInterface>('DaffCartOrderDriver');
Loading

0 comments on commit e536798

Please sign in to comment.