@reactionary/source 0.0.41 → 0.0.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/.env-template +8 -5
  2. package/README.md +41 -0
  3. package/core/src/client/client.ts +2 -0
  4. package/core/src/index.ts +3 -28
  5. package/core/src/providers/cart-payment.provider.ts +56 -0
  6. package/core/src/providers/cart.provider.ts +125 -1
  7. package/core/src/providers/index.ts +10 -0
  8. package/core/src/providers/price.provider.ts +1 -1
  9. package/core/src/providers/product.provider.ts +13 -1
  10. package/core/src/schemas/capabilities.schema.ts +1 -0
  11. package/core/src/schemas/models/cart.model.ts +16 -3
  12. package/core/src/schemas/models/identifiers.model.ts +43 -3
  13. package/core/src/schemas/models/identity.model.ts +22 -2
  14. package/core/src/schemas/models/index.ts +14 -0
  15. package/core/src/schemas/models/payment.model.ts +41 -0
  16. package/core/src/schemas/models/profile.model.ts +34 -0
  17. package/core/src/schemas/models/shipping-method.model.ts +14 -0
  18. package/core/src/schemas/mutations/cart-payment.mutation.ts +21 -0
  19. package/core/src/schemas/mutations/cart.mutation.ts +62 -3
  20. package/core/src/schemas/mutations/identity.mutation.ts +2 -1
  21. package/core/src/schemas/mutations/index.ts +9 -0
  22. package/core/src/schemas/queries/cart-payment.query.ts +12 -0
  23. package/core/src/schemas/queries/index.ts +1 -0
  24. package/examples/node/src/test-utils.ts +10 -3
  25. package/package.json +1 -1
  26. package/providers/algolia/src/test/test-utils.ts +8 -3
  27. package/providers/commercetools/README.md +16 -0
  28. package/providers/commercetools/src/core/client.ts +25 -34
  29. package/providers/commercetools/src/core/initialize.ts +17 -10
  30. package/providers/commercetools/src/providers/cart-payment.provider.ts +192 -0
  31. package/providers/commercetools/src/providers/cart.provider.ts +409 -104
  32. package/providers/commercetools/src/providers/category.provider.ts +5 -2
  33. package/providers/commercetools/src/providers/identity.provider.ts +12 -4
  34. package/providers/commercetools/src/providers/inventory.provider.ts +10 -0
  35. package/providers/commercetools/src/providers/price.provider.ts +10 -4
  36. package/providers/commercetools/src/providers/product.provider.ts +23 -14
  37. package/providers/commercetools/src/providers/search.provider.ts +10 -3
  38. package/providers/commercetools/src/schema/capabilities.schema.ts +1 -0
  39. package/providers/commercetools/src/schema/commercetools.schema.ts +18 -0
  40. package/providers/commercetools/src/schema/configuration.schema.ts +2 -1
  41. package/providers/commercetools/src/test/cart-payment.provider.spec.ts +149 -0
  42. package/providers/commercetools/src/test/cart.provider.spec.ts +69 -10
  43. package/providers/commercetools/src/test/product.provider.spec.ts +27 -0
  44. package/providers/commercetools/src/test/test-utils.ts +22 -7
  45. package/providers/fake/src/providers/cart.provider.ts +47 -3
  46. package/providers/fake/src/providers/price.provider.ts +1 -1
  47. package/providers/fake/src/providers/product.provider.ts +3 -0
  48. package/providers/fake/src/test/test-utils.ts +7 -2
  49. package/trpc/src/test-utils.ts +8 -3
package/.env-template CHANGED
@@ -1,8 +1,11 @@
1
- COMMERCETOOLS_API_URL=https://api.europe-west1.gcp.commercetools.com
2
- COMMERCETOOLS_AUTH_URL=https://auth.europe-west1.gcp.commercetools.com
3
- COMMERCETOOLS_CLIENT_ID=
4
- COMMERCETOOLS_CLIENT_SECRET=
5
- COMMERCETOOLS_PROJECT_KEY=
1
+ CTP_PROJECT_KEY=
2
+ CTP_CLIENT_SECRET=
3
+ CTP_CLIENT_ID=
4
+ CTP_AUTH_URL=https://auth.europe-west1.gcp.commercetools.com
5
+ CTP_API_URL=https://api.europe-west1.gcp.commercetools.com
6
+ CTP_SCOPES=
7
+
8
+
6
9
 
7
10
  OTEL_SERVICE_NAME=reactionary
8
11
  OTEL_LOG_LEVEL=info
package/README.md CHANGED
@@ -37,3 +37,44 @@ The following is a short list of commonly used terms and phrases, to keep guessi
37
37
  - *Fake:* an implementation that provides a functional response, but with in a limited capacity. A fake provider may, for example, provide *Cart* functionality, but only store it in-memory and throw it away on a whim. As such it can be used for prototyping, but never for a production scenario.
38
38
  - *Product Analytics:* structured analytics that relate to how the the product is being used.
39
39
  - *Microsite:* an application of a limited scope. It may focus solely on this limited functionality, making it ideal for demonstration purposes.
40
+
41
+
42
+
43
+ ## TODO:
44
+
45
+
46
+
47
+ ### Core
48
+ - [ ] Figure a way to get a correlation id from the caller
49
+ - [ ] Maybe rework session so its not languageContext but requestContext, and this could have the correlation id in it?
50
+
51
+
52
+ ### Search
53
+ - [ ] Add support for filters, not just facets
54
+
55
+ ### Marketing
56
+ - [ ] Add marketing provider (input: (name, url, user, segments, productid, categoryid) => output { Array<Product | Category | Image | Text>}
57
+
58
+
59
+ ### Inventory
60
+ - [ ] Invent and document some notational standard for cannel-key to purpose.
61
+ - [ ] Be traced and cached
62
+
63
+ ### Profile
64
+ - [ ] Be able to register new account
65
+ - [ ] Create profile provider
66
+
67
+
68
+ ### Organization
69
+ - [ ] Create organization provider
70
+ - [ ] Create business user provider
71
+ - [ ] Create role provider
72
+
73
+ ### Cart
74
+ - [ ] Add B2B/organization identifier
75
+
76
+ ### Price
77
+ - [ ] Add list price
78
+
79
+ ### Order
80
+ - [ ] Add Order
@@ -8,6 +8,7 @@ import { InventoryProvider } from "../providers/inventory.provider";
8
8
  import { Cache } from "../cache/cache.interface";
9
9
  import { RedisCache } from "../cache/redis-cache";
10
10
  import { CategoryProvider } from "../providers/category.provider";
11
+ import { CartPaymentProvider } from "../providers";
11
12
 
12
13
  export interface Client {
13
14
  product: ProductProvider,
@@ -15,6 +16,7 @@ export interface Client {
15
16
  identity: IdentityProvider,
16
17
  cache: Cache,
17
18
  cart: CartProvider,
19
+ cartPayment: CartPaymentProvider,
18
20
  analytics: Array<AnalyticsProvider>,
19
21
  price: PriceProvider,
20
22
  inventory: InventoryProvider,
package/core/src/index.ts CHANGED
@@ -8,36 +8,11 @@ export * from './client/client-builder';
8
8
 
9
9
  export * from './decorators/reactionary.decorator';
10
10
 
11
- export * from './providers/analytics.provider';
12
- export * from './providers/base.provider';
13
- export * from './providers/cart.provider';
14
- export * from './providers/identity.provider';
15
- export * from './providers/inventory.provider';
16
- export * from './providers/price.provider';
17
- export * from './providers/product.provider';
18
- export * from './providers/search.provider';
19
- export * from './providers/category.provider';
11
+ export * from './providers/'
20
12
 
21
13
  export * from './schemas/capabilities.schema';
22
14
  export * from './schemas/session.schema';
23
15
 
24
- export * from './schemas/models/base.model';
25
- export * from './schemas/models/cart.model';
26
- export * from './schemas/models/currency.model';
27
- export * from './schemas/models/identifiers.model';
28
- export * from './schemas/models/identity.model';
29
- export * from './schemas/models/inventory.model';
30
- export * from './schemas/models/price.model';
31
- export * from './schemas/models/product.model';
32
- export * from './schemas/models/search.model';
33
- export * from './schemas/models/category.model';
34
-
35
- export * from './schemas/mutations/base.mutation';
36
- export * from './schemas/mutations/cart.mutation';
37
- export * from './schemas/mutations/identity.mutation';
38
- export * from './schemas/mutations/inventory.mutation';
39
- export * from './schemas/mutations/price.mutation';
40
- export * from './schemas/mutations/product.mutation';
41
- export * from './schemas/mutations/search.mutation';
42
-
16
+ export * from './schemas/models/';
17
+ export * from './schemas/mutations/';
43
18
  export * from './schemas/queries';
@@ -0,0 +1,56 @@
1
+ import { CartPaymentInstruction } from '../schemas/models/payment.model';
2
+ import { CartPaymentMutationAddPayment, CartPaymentMutationCancelPayment } from '../schemas/mutations/cart-payment.mutation';
3
+ import { CartPaymentQueryByCart } from '../schemas/queries/cart-payment.query';
4
+ import { Session } from '../schemas/session.schema';
5
+ import { BaseProvider } from './base.provider';
6
+
7
+ export abstract class CartPaymentProvider<
8
+ T extends CartPaymentInstruction = CartPaymentInstruction
9
+ > extends BaseProvider<T> {
10
+
11
+
12
+
13
+ /**
14
+ * Returns all payment instructions associated with a given cart, optionally filtered by status
15
+ *
16
+ * Usecase: Fetch all registered payment instructions to show on checkout page, in case you support multiple payments in your storefront,
17
+ * and need to show how far the user has come in the payment process. Also useful if user reloads page, or goes back to site or otherwise breaks the flow.
18
+ *
19
+ * Only returns payment instructions in status 'pending' or 'authorized'
20
+ * @param cartIdentifier
21
+ * @param session
22
+ */
23
+ public abstract getByCartIdentifier(payload: CartPaymentQueryByCart, session: Session): Promise<T[]>;
24
+
25
+
26
+ /**
27
+ * Calls payment provider to set up a new payment intent. Returns whatever is needed to continue the payment process, e.g. a client secret for Stripe, or a redirect URL for PayPal.
28
+ *
29
+ * Usecase: User has filled out checkout form, and is ready to pay. You call this to get the payment process started.
30
+ *
31
+ * Note: The payment provider MAY change the cart during the payment process, so be sure to reload the cart object after this call.
32
+ *
33
+ * @param payload
34
+ * @param session
35
+ */
36
+ public abstract initiatePaymentForCart(payload: CartPaymentMutationAddPayment, session: Session): Promise<T>;
37
+
38
+
39
+
40
+ /**
41
+ * Cancel a payment instruction. This will typically void the payment intent in the payment provider, and set the status of the payment instruction to 'canceled'.
42
+ *
43
+ * Usecase: User has decided to cancel the payment, e.g. by going back in the checkout process, or by closing the browser window. You call this to clean up the payment instruction.
44
+ *
45
+ * Note: The payment provider MAY change the cart during the cancellation process, so be sure to reload the cart object after this call.
46
+ *
47
+ * @param payload
48
+ * @param session
49
+ * @returns
50
+ */
51
+ public abstract cancelPaymentInstruction(payload: CartPaymentMutationCancelPayment, session: Session): Promise<T>;
52
+
53
+ protected override getResourceName(): string {
54
+ return 'cart-payment-instruction';
55
+ }
56
+ }
@@ -2,17 +2,141 @@ import { BaseProvider } from "./base.provider";
2
2
  import { Cart } from "../schemas/models/cart.model";
3
3
  import { CartQueryById } from "../schemas/queries/cart.query";
4
4
  import { Session } from "../schemas/session.schema";
5
- import { CartMutationItemAdd, CartMutationItemQuantityChange, CartMutationItemRemove } from "../schemas/mutations/cart.mutation";
5
+ import { CartMutationAddPaymentMethod, CartMutationApplyCoupon, CartMutationChangeCurrency, CartMutationCheckout, CartMutationDeleteCart, CartMutationItemAdd, CartMutationItemQuantityChange, CartMutationItemRemove, CartMutationRemoveCoupon, CartMutationRemovePaymentMethod, CartMutationSetBillingAddress, CartMutationSetShippingInfo } from "../schemas/mutations/cart.mutation";
6
+ import { CartIdentifier, OrderIdentifier } from "../schemas/models/identifiers.model";
7
+ import { CartPaymentProvider } from "./cart-payment.provider";
6
8
 
7
9
  export abstract class CartProvider<
8
10
  T extends Cart = Cart
9
11
  > extends BaseProvider<T> {
12
+
13
+ /**
14
+ * Get cart by ID.
15
+ *
16
+ * Usecase: Unclear, until we support multiple carts per user.
17
+ * @param payload
18
+ * @param session
19
+ */
10
20
  public abstract getById(payload: CartQueryById, session: Session): Promise<T>;
21
+
22
+
23
+ /**
24
+ * Get the active cart id for the user.
25
+ *
26
+ * Usecase: Most common usecase during site load, or after login. You want to get the active cart for the user, so you can display it in the minicart.
27
+ * @param session
28
+ */
29
+ public abstract getActiveCartId(session: Session): Promise<CartIdentifier>;
30
+
31
+
32
+ /**
33
+ * Add item to cart. If no cart exists, create a new one. Returns the updated and recalculated cart.
34
+ * Does not automatically consolidate items, so if you want to have second add of same item to increase quantity,
35
+ * you need to handle that in your logic or on the server.
36
+ *
37
+ * Usecase: Add item to cart, create cart if none exists.
38
+ * @param payload
39
+ * @param session
40
+ */
11
41
  public abstract add(payload: CartMutationItemAdd, session: Session): Promise<T>;
42
+
43
+ /**
44
+ * Remove item from cart. If the cart is empty after removal, delete the cart. Returns the updated and recalculated cart.
45
+ *
46
+ * Usecase: Remove item from cart, delete cart if empty.
47
+ * @param payload
48
+ * @param session
49
+ */
12
50
  public abstract remove(payload: CartMutationItemRemove, session: Session): Promise<T>;
51
+
52
+ /**
53
+ * Change quantity of item in cart. If the cart is empty after change, delete the cart. Returns the updated and recalculated cart.
54
+ * Changing quantity to 0 is not allowed. Use the remove call instead. This is done to avoid accidental removal of item.
55
+ * Calls with quantity 0 will just be ignored.
56
+ *
57
+ * Usecase: Change quantity of item in cart, like in a minicart, or in the full cart view.
58
+ * @param payload
59
+ * @param session
60
+ */
13
61
  public abstract changeQuantity(payload: CartMutationItemQuantityChange, session: Session): Promise<T>;
14
62
 
15
63
 
64
+ /**
65
+ * Deletes the entire cart.
66
+ *
67
+ * Usecase: User wants to empty the cart or something is wrong with the current cart, and you want to clear it out and start fresh.
68
+ * @param payload
69
+ * @param session
70
+ */
71
+ public abstract deleteCart(payload: CartMutationDeleteCart, session: Session): Promise<T>;
72
+
73
+ /**
74
+ * Sets shipping method and address on the cart. Returns the updated and recalculated cart.
75
+ *
76
+ * Usecase: User selects shipping method during checkout.
77
+ * @param payload
78
+ * @param session
79
+ */
80
+ public abstract setShippingInfo(payload: CartMutationSetShippingInfo, session: Session): Promise<T>;
81
+
82
+ /**
83
+ * Sets billing address on the cart. Returns the updated and recalculated cart.
84
+ *
85
+ * Usecase: User enters billing address during checkout.
86
+ *
87
+ * @param payload
88
+ * @param session
89
+ */
90
+ public abstract setBillingAddress(payload: CartMutationSetBillingAddress, session: Session): Promise<T>;
91
+
92
+ /**
93
+ * Applies a coupon code to the cart. Returns the updated and recalculated cart.
94
+ *
95
+ * Usecase: User applies a coupon code during checkout.
96
+ * @param payload
97
+ * @param session
98
+ */
99
+ public abstract applyCouponCode(payload: CartMutationApplyCoupon, session: Session): Promise<T>;
100
+
101
+
102
+ /**
103
+ * Removes a coupon code from the cart. Returns the updated and recalculated cart.
104
+ *
105
+ * Usecase: User removes a coupon code during checkout.
106
+ * @param payload
107
+ * @param session
108
+ */
109
+ public abstract removeCouponCode(payload: CartMutationRemoveCoupon, session: Session): Promise<T>;
110
+
111
+
112
+ /**
113
+ * Checks out the cart. Returns the order identifier of the newly created order.
114
+ *
115
+ * Usecase: User proceeds to checkout.
116
+ *
117
+ * @param payload
118
+ * @param session
119
+ */
120
+ public abstract checkout(payload: CartMutationCheckout, session: Session): Promise<OrderIdentifier>;
121
+
122
+ /**
123
+ * Changes the currency of the cart.
124
+ *
125
+ * Usecase: User wants to change the currency for his session. This will change the currency of the cart, and recalculate prices.
126
+ * @param newCurrency
127
+ * @param session
128
+ */
129
+ public abstract changeCurrency(payload: CartMutationChangeCurrency, session: Session): Promise<T>;
130
+
131
+
132
+
133
+ protected createEmptyCart(): T {
134
+ const cart = this.newModel();
135
+ cart.meta = { placeholder: true, cache: { hit: true, key: 'empty-cart' } };
136
+ cart.identifier = { key: '' };
137
+ return cart;
138
+ }
139
+
16
140
  protected override getResourceName(): string {
17
141
  return 'cart';
18
142
  }
@@ -0,0 +1,10 @@
1
+ export * from './analytics.provider';
2
+ export * from './base.provider';
3
+ export * from './cart-payment.provider';
4
+ export * from './cart.provider';
5
+ export * from './category.provider';
6
+ export * from './identity.provider';
7
+ export * from './inventory.provider';
8
+ export * from './price.provider';
9
+ export * from './product.provider';
10
+ export * from './search.provider';
@@ -40,7 +40,7 @@ export abstract class PriceProvider<
40
40
  * @param currency
41
41
  * @returns
42
42
  */
43
- protected getEmptyPriceResult(sku: string, currency: Currency): T {
43
+ protected createEmptyPriceResult(sku: string, currency: Currency): T {
44
44
  const base = this.newModel();
45
45
  base.identifier = {
46
46
  sku: { key: sku }
@@ -7,8 +7,20 @@ export abstract class ProductProvider<
7
7
  T extends Product = Product
8
8
  > extends BaseProvider<T> {
9
9
  public abstract getById(payload: ProductQueryById, session: Session): Promise<T>;
10
- public abstract getBySlug(payload: ProductQueryBySlug, session: Session): Promise<T>;
10
+ public abstract getBySlug(payload: ProductQueryBySlug, session: Session): Promise<T | null>;
11
11
 
12
+
13
+ protected createEmptyProduct(id: string): T {
14
+ const product = this.newModel();
15
+ product.identifier = { key: id };
16
+ product.meta.placeholder = true;
17
+ return product;
18
+ }
19
+
20
+ /**
21
+ * The resource name, used for caching and logging.
22
+ * @returns
23
+ */
12
24
  protected override getResourceName(): string {
13
25
  return 'product';
14
26
  }
@@ -6,6 +6,7 @@ export const CapabilitiesSchema = z.looseObject({
6
6
  analytics: z.boolean(),
7
7
  identity: z.boolean(),
8
8
  cart: z.boolean(),
9
+ cartPayment: z.boolean(),
9
10
  inventory: z.boolean(),
10
11
  price: z.boolean(),
11
12
  category: z.boolean()
@@ -1,7 +1,9 @@
1
1
  import { z } from 'zod';
2
- import { CartIdentifierSchema, CartItemIdentifierSchema, ProductIdentifierSchema } from '../models/identifiers.model';
2
+ import { CartIdentifierSchema, CartItemIdentifierSchema, IdentityIdentifierSchema, ProductIdentifierSchema, SKUIdentifierSchema } from '../models/identifiers.model';
3
3
  import { BaseModelSchema } from './base.model';
4
4
  import { MonetaryAmountSchema } from './price.model';
5
+ import { AddressSchema } from './profile.model';
6
+ import { ShippingMethodSchema } from './shipping-method.model';
5
7
 
6
8
  export const CostBreakDownSchema = z.looseObject({
7
9
  totalTax: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe('The amount of tax paid on the cart. This may include VAT, GST, sales tax, etc.'),
@@ -11,7 +13,6 @@ export const CostBreakDownSchema = z.looseObject({
11
13
  totalProductPrice: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe('The total price of products in the cart.'),
12
14
  grandTotal: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe('The total price for the cart including all taxes, discounts, and shipping.'),
13
15
  });
14
- export type CostBreakDown = z.infer<typeof CostBreakDownSchema>;
15
16
 
16
17
  export const ItemCostBreakdownSchema = z.looseObject({
17
18
  unitPrice: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe('The price per single unit of the item.'),
@@ -20,22 +21,34 @@ export const ItemCostBreakdownSchema = z.looseObject({
20
21
  totalDiscount: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe('The total discount applied to all units of the item.'),
21
22
  });
22
23
 
23
- export type ItemCostBreakdown = z.infer<typeof ItemCostBreakdownSchema>;
24
24
 
25
25
  export const CartItemSchema = z.looseObject({
26
26
  identifier: CartItemIdentifierSchema.default(() => CartItemIdentifierSchema.parse({})),
27
27
  product: ProductIdentifierSchema.default(() => ProductIdentifierSchema.parse({})),
28
+ sku: SKUIdentifierSchema.default(() => SKUIdentifierSchema.parse({})),
28
29
  quantity: z.number().default(0),
29
30
  price: ItemCostBreakdownSchema.default(() => ItemCostBreakdownSchema.parse({})),
30
31
  });
31
32
 
32
33
  export const CartSchema = BaseModelSchema.extend({
33
34
  identifier: CartIdentifierSchema.default(() => CartIdentifierSchema.parse({})),
35
+
36
+ userId: IdentityIdentifierSchema.default(() => IdentityIdentifierSchema.parse({})),
37
+
34
38
  items: z.array(CartItemSchema).default(() => []),
35
39
  price: CostBreakDownSchema.default(() => CostBreakDownSchema.parse({})),
36
40
  name: z.string().default(''),
37
41
  description: z.string().default(''),
42
+
43
+
44
+ shippingAddress: AddressSchema.optional(),
45
+ billingAddress: AddressSchema.optional(),
46
+ shippingMethod: ShippingMethodSchema.optional(),
38
47
  });
39
48
 
49
+
50
+
51
+ export type CostBreakDown = z.infer<typeof CostBreakDownSchema>;
52
+ export type ItemCostBreakdown = z.infer<typeof ItemCostBreakdownSchema>;
40
53
  export type CartItem = z.infer<typeof CartItemSchema>;
41
54
  export type Cart = z.infer<typeof CartSchema>;
@@ -40,6 +40,15 @@ export const CategoryIdentifierSchema = z.looseObject({
40
40
  key: z.string().default('').nonoptional()
41
41
  });
42
42
 
43
+
44
+ export const OrderIdentifierSchema = z.looseObject({
45
+ key: z.string().default('').nonoptional()
46
+ });
47
+
48
+ export const OrderItemIdentifierSchema = z.looseObject({
49
+ key: z.string().default('').nonoptional()
50
+ });
51
+
43
52
  /**
44
53
  * The target store the user is interacting with. Can change over time, and is not necessarily the same as the default store.
45
54
  */
@@ -56,6 +65,27 @@ export const InventoryIdentifierSchema = z.looseObject({
56
65
  channelId: InventoryChannelIdentifierSchema.default(() => InventoryChannelIdentifierSchema.parse({})),
57
66
  });
58
67
 
68
+ export const IdentityIdentifierSchema = z.looseObject({
69
+ userId: z.string().default('').nonoptional()
70
+ });
71
+
72
+ export const ShippingMethodIdentifier = z.looseObject({
73
+ key: z.string().default('').nonoptional()
74
+ });
75
+
76
+ export const PaymentMethodIdentifierSchema = z.looseObject({
77
+ method: z.string().default('').nonoptional(),
78
+ name: z.string().default('').nonoptional(),
79
+ paymentProcessor: z.string().default('').nonoptional()
80
+ });
81
+
82
+ export const AddressIdentifierSchema = z.looseObject({
83
+ nickName: z.string().default('').nonoptional()
84
+ });
85
+
86
+ export const PaymentInstructionIdentifierSchema = z.looseObject({
87
+ key: z.string().default('').nonoptional()
88
+ });
59
89
 
60
90
  export type ProductIdentifier = z.infer<typeof ProductIdentifierSchema>;
61
91
  export type SearchIdentifier = z.infer<typeof SearchIdentifierSchema>;
@@ -68,6 +98,16 @@ export type CategoryIdentifier = z.infer<typeof CategoryIdentifierSchema>;
68
98
  export type WebStoreIdentifier = z.infer<typeof WebStoreIdentifierSchema>;
69
99
  export type InventoryIdentifier = z.infer<typeof InventoryIdentifierSchema>;
70
100
  export type InventoryChannelIdentifier = z.infer<typeof InventoryChannelIdentifierSchema>;
71
-
72
-
73
- export type IdentifierType = ProductIdentifier | SearchIdentifier | FacetIdentifier | FacetValueIdentifier | CartIdentifier | CartItemIdentifier | PriceIdentifier | CategoryIdentifier | WebStoreIdentifier | InventoryIdentifier;
101
+ export type IdentityIdentifier = z.infer<typeof IdentityIdentifierSchema>;
102
+ export type ShippingMethodIdentifier = z.infer<typeof ShippingMethodIdentifier>;
103
+ export type PaymentMethodIdentifier = z.infer<typeof PaymentMethodIdentifierSchema>;
104
+ export type AddressIdentifier = z.infer<typeof AddressIdentifierSchema>;
105
+ export type PaymentInstructionIdentifier = z.infer<typeof PaymentInstructionIdentifierSchema>;
106
+ export type OrderIdentifier = z.infer<typeof OrderIdentifierSchema>;
107
+ export type OrderItemIdentifier = z.infer<typeof OrderItemIdentifierSchema>;
108
+
109
+ export type IdentifierType = ProductIdentifier | SearchIdentifier | FacetIdentifier | FacetValueIdentifier
110
+ | CartIdentifier | CartItemIdentifier | PriceIdentifier | CategoryIdentifier
111
+ | WebStoreIdentifier | InventoryIdentifier | InventoryChannelIdentifier
112
+ | IdentityIdentifier | ShippingMethodIdentifier | PaymentMethodIdentifier | AddressIdentifier | PaymentInstructionIdentifier
113
+ | OrderIdentifier | OrderItemIdentifier;
@@ -1,15 +1,35 @@
1
1
  import { z } from 'zod';
2
2
  import { BaseModelSchema } from './base.model';
3
+ import { IdentityIdentifierSchema } from './identifiers.model';
3
4
 
4
5
  export const IdentityTypeSchema = z.enum(["Anonymous", "Guest", "Registered"]);
5
6
 
7
+
8
+ export const ServiceTokenSchema = z.object({
9
+ service: z.string().default(''),
10
+ token: z.string().default(''),
11
+ issued: z.coerce.date().default(new Date()),
12
+ expiry: z.coerce.date().default(new Date())
13
+ });
14
+
6
15
  export const IdentitySchema = BaseModelSchema.extend({
7
- id: z.string().default(''),
16
+ id: IdentityIdentifierSchema.default(() => IdentityIdentifierSchema.parse({})),
8
17
  type: IdentityTypeSchema.default("Anonymous"),
18
+
19
+ logonId: z.string().default(''),
20
+
21
+ createdAt: z.string().default(() => new Date().toISOString()),
22
+ updatedAt: z.string().default(() => new Date().toISOString()),
23
+ // Tokens for various services
24
+ keyring: z.array(ServiceTokenSchema).default(() => []),
25
+
26
+ // Deprecated - use serviceTokens map instead
27
+ currentService: z.string().optional(),
28
+
9
29
  token: z.string().optional(),
10
30
  issued: z.coerce.date().default(new Date()),
11
31
  expiry: z.coerce.date().default(new Date())
12
32
  });
13
33
 
14
34
  export type IdentityType = z.infer<typeof IdentityTypeSchema>;
15
- export type Identity = z.infer<typeof IdentitySchema>;
35
+ export type Identity = z.infer<typeof IdentitySchema>;
@@ -0,0 +1,14 @@
1
+ export * from './analytics.model';
2
+ export * from './base.model';
3
+ export * from './cart.model';
4
+ export * from './category.model';
5
+ export * from './currency.model';
6
+ export * from './identifiers.model';
7
+ export * from './identity.model';
8
+ export * from './inventory.model';
9
+ export * from './payment.model';
10
+ export * from './price.model';
11
+ export * from './product.model';
12
+ export * from './profile.model';
13
+ export * from './search.model';
14
+ export * from './shipping-method.model';
@@ -0,0 +1,41 @@
1
+ import { z } from 'zod';
2
+ import { BaseModelSchema, ImageSchema } from './base.model';
3
+ import { CartIdentifierSchema, InventoryIdentifierSchema, PaymentInstructionIdentifierSchema, PaymentMethodIdentifierSchema } from './identifiers.model';
4
+ import { MonetaryAmountSchema } from './price.model';
5
+ import { describe } from 'node:test';
6
+
7
+ export const PaymentStatusSchema = z.enum(['pending', 'authorized', 'canceled', 'capture', 'partial_capture', 'refunded', 'partial_refund']);
8
+
9
+ export const PaymentProtocolDataSchema = z.looseObject({
10
+ key: z.string().default(''),
11
+ value: z.string().default(''),
12
+ });
13
+
14
+
15
+ export const PaymentMethodSchema = BaseModelSchema.extend({
16
+ identifier: PaymentMethodIdentifierSchema.default(() => PaymentMethodIdentifierSchema.parse({})),
17
+ logo: ImageSchema.optional(),
18
+ description: z.string().default(''),
19
+ isPunchOut: z.boolean().default(true)
20
+ });
21
+
22
+ export const PaymentInstructionSchema = BaseModelSchema.extend({
23
+ identifier: PaymentInstructionIdentifierSchema.default(() => PaymentInstructionIdentifierSchema.parse({})),
24
+ amount: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})),
25
+ paymentMethod: PaymentMethodIdentifierSchema.default(() => PaymentMethodIdentifierSchema.parse({})),
26
+ protocolData: z.array(PaymentProtocolDataSchema).default(() => []).describe('Additional protocol-specific data for processing the payment.'),
27
+ status: PaymentStatusSchema.default('pending'),
28
+ });
29
+
30
+ export const CartPaymentInstructionSchema = PaymentInstructionSchema.extend({
31
+ cart: CartIdentifierSchema.default(() => CartIdentifierSchema.parse({}))
32
+ });
33
+
34
+ export const OrderPaymentInstructionSchema = PaymentInstructionSchema.extend({
35
+ order: z.string().default('') // OrderIdentifierSchema
36
+ });
37
+
38
+ export type CartPaymentInstruction = z.infer<typeof CartPaymentInstructionSchema>;
39
+ export type OrderPaymentInstruction = z.infer<typeof OrderPaymentInstructionSchema>;
40
+ export type PaymentInstruction = z.infer<typeof PaymentInstructionSchema>;
41
+ export type PaymentStatus = z.infer<typeof PaymentStatusSchema>;
@@ -0,0 +1,34 @@
1
+ import z from "zod";
2
+ import { AddressIdentifierSchema, IdentityIdentifierSchema } from "./identifiers.model";
3
+
4
+ export const AddressSchema = z.looseObject({
5
+ identifier: AddressIdentifierSchema.default(() => AddressIdentifierSchema.parse({})),
6
+ firstName: z.string().default(''),
7
+ lastName: z.string().default(''),
8
+ streetAddress: z.string().default(''),
9
+ streetNumber: z.string().default(''),
10
+ city: z.string().default(''),
11
+ region: z.string().default(''),
12
+ postalCode: z.string().default(''),
13
+ countryCode: z.string().default('US'),
14
+ });
15
+
16
+ export const ProfileSchema = z.looseObject({
17
+ identifier: IdentityIdentifierSchema.default(() => IdentityIdentifierSchema.parse({})),
18
+ email: z.string().email().default(''),
19
+ phone: z.string().default(''),
20
+
21
+ emailVerified: z.boolean().default(false),
22
+ phoneVerified: z.boolean().default(false),
23
+
24
+ createdAt: z.string().default(() => new Date().toISOString()),
25
+ updatedAt: z.string().default(() => new Date().toISOString()),
26
+
27
+ shippingAddress: AddressSchema.optional(),
28
+ billingAddress: AddressSchema.optional(),
29
+
30
+ alternateShippingAddresses: z.array(AddressSchema).default(() => []),
31
+ });
32
+
33
+ export type Address = z.infer<typeof AddressSchema>;
34
+ export type Profile = z.infer<typeof ProfileSchema>;
@@ -0,0 +1,14 @@
1
+ import z from "zod";
2
+ import { ShippingMethodIdentifier } from "./identifiers.model";
3
+ import { MonetaryAmountSchema } from "./price.model";
4
+ import { ImageSchema } from "./base.model";
5
+
6
+ export const ShippingMethodSchema = z.looseObject({
7
+ identifier: ShippingMethodIdentifier.default(() => ShippingMethodIdentifier.parse({})),
8
+ name: z.string().default(''),
9
+ description: z.string().default(''),
10
+ logo: ImageSchema.optional(),
11
+ price: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})),
12
+ deliveryTime: z.string().default(''),
13
+ });
14
+
@@ -0,0 +1,21 @@
1
+ import z from "zod";
2
+ import { CartIdentifierSchema, PaymentInstructionIdentifierSchema } from "../models/identifiers.model";
3
+ import { PaymentInstructionSchema } from "../models/payment.model";
4
+ import { BaseMutationSchema } from "./base.mutation";
5
+
6
+
7
+
8
+ export const CartPaymentMutationAddPayment = BaseMutationSchema.extend({
9
+ paymentInstruction: PaymentInstructionSchema.omit({ meta: true, status: true, identifier: true }).required(),
10
+ cart: CartIdentifierSchema.required()
11
+ });
12
+
13
+ export const CartPaymentMutationCancelPayment = BaseMutationSchema.extend({
14
+ paymentInstruction: PaymentInstructionIdentifierSchema.required(),
15
+ cart: CartIdentifierSchema.required()
16
+ });
17
+
18
+
19
+
20
+ export type CartPaymentMutationAddPayment = z.infer<typeof CartPaymentMutationAddPayment>;
21
+ export type CartPaymentMutationCancelPayment = z.infer<typeof CartPaymentMutationCancelPayment>;