@reactionary/core 0.0.48 → 0.0.51

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/package.json +2 -2
  2. package/providers/checkout.provider.js +6 -0
  3. package/providers/index.js +2 -1
  4. package/providers/order.provider.js +15 -0
  5. package/schemas/capabilities.schema.js +2 -1
  6. package/schemas/models/cart.model.js +3 -24
  7. package/schemas/models/checkout.model.js +44 -0
  8. package/schemas/models/cost.model.js +20 -0
  9. package/schemas/models/identifiers.model.js +12 -0
  10. package/schemas/models/identity.model.js +6 -3
  11. package/schemas/models/index.js +4 -0
  12. package/schemas/models/order.model.js +37 -0
  13. package/schemas/models/payment.model.js +1 -10
  14. package/schemas/models/product.model.js +5 -2
  15. package/schemas/models/shipping-method.model.js +24 -2
  16. package/schemas/mutations/checkout.mutation.js +36 -0
  17. package/schemas/mutations/index.js +1 -1
  18. package/schemas/queries/checkout.query.js +16 -0
  19. package/schemas/queries/index.js +2 -1
  20. package/schemas/queries/order.query.js +8 -0
  21. package/schemas/queries/product.query.js +5 -0
  22. package/src/client/client.d.ts +2 -2
  23. package/src/providers/checkout.provider.d.ts +135 -0
  24. package/src/providers/index.d.ts +2 -1
  25. package/src/providers/order.provider.d.ts +16 -0
  26. package/src/providers/product.provider.d.ts +2 -1
  27. package/src/schemas/capabilities.schema.d.ts +2 -1
  28. package/src/schemas/models/cart.model.d.ts +0 -2106
  29. package/src/schemas/models/checkout.model.d.ts +2930 -0
  30. package/src/schemas/models/cost.model.d.ts +1867 -0
  31. package/src/schemas/models/identifiers.model.d.ts +13 -1
  32. package/src/schemas/models/identity.model.d.ts +12 -6
  33. package/src/schemas/models/index.d.ts +4 -0
  34. package/src/schemas/models/order.model.d.ts +3144 -0
  35. package/src/schemas/models/payment.model.d.ts +1 -438
  36. package/src/schemas/models/product.model.d.ts +2 -2
  37. package/src/schemas/models/shipping-method.model.d.ts +50 -0
  38. package/src/schemas/mutations/{cart-payment.mutation.d.ts → checkout.mutation.d.ts} +75 -7
  39. package/src/schemas/mutations/index.d.ts +1 -1
  40. package/src/schemas/queries/checkout.query.d.ts +19 -0
  41. package/src/schemas/queries/index.d.ts +2 -1
  42. package/src/schemas/queries/order.query.d.ts +7 -0
  43. package/src/schemas/queries/product.query.d.ts +6 -0
  44. package/src/schemas/session.schema.d.ts +6 -3
  45. package/providers/cart-payment.provider.js +0 -9
  46. package/schemas/mutations/cart-payment.mutation.js +0 -15
  47. package/schemas/queries/cart-payment.query.js +0 -11
  48. package/src/providers/cart-payment.provider.d.ts +0 -42
  49. package/src/schemas/queries/cart-payment.query.d.ts +0 -16
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@reactionary/core",
3
- "version": "0.0.48",
3
+ "version": "0.0.51",
4
4
  "main": "index.js",
5
5
  "types": "src/index.d.ts",
6
6
  "dependencies": {
7
7
  "zod": "4.1.9",
8
8
  "@upstash/redis": "^1.34.9",
9
- "@reactionary/otel": "0.0.48",
9
+ "@reactionary/otel": "0.0.51",
10
10
  "node-object-hash": "^3.1.1"
11
11
  }
12
12
  }
@@ -0,0 +1,6 @@
1
+ import { BaseProvider } from "./base.provider";
2
+ class CheckoutProvider extends BaseProvider {
3
+ }
4
+ export {
5
+ CheckoutProvider
6
+ };
@@ -1,8 +1,8 @@
1
1
  export * from "./analytics.provider";
2
2
  export * from "./base.provider";
3
- export * from "./cart-payment.provider";
4
3
  export * from "./cart.provider";
5
4
  export * from "./category.provider";
5
+ export * from "./checkout.provider";
6
6
  export * from "./identity.provider";
7
7
  export * from "./inventory.provider";
8
8
  export * from "./price.provider";
@@ -10,3 +10,4 @@ export * from "./product.provider";
10
10
  export * from "./profile.provider";
11
11
  export * from "./search.provider";
12
12
  export * from "./store.provider";
13
+ export * from "./order.provider";
@@ -0,0 +1,15 @@
1
+ import { BaseProvider } from "./base.provider";
2
+ class OrderProvider extends BaseProvider {
3
+ createEmptyOrder() {
4
+ const order = this.newModel();
5
+ order.meta = { placeholder: true, cache: { hit: true, key: "empty-order" } };
6
+ order.identifier = { key: "" };
7
+ return order;
8
+ }
9
+ getResourceName() {
10
+ return "order";
11
+ }
12
+ }
13
+ export {
14
+ OrderProvider
15
+ };
@@ -5,7 +5,8 @@ const CapabilitiesSchema = z.looseObject({
5
5
  analytics: z.boolean(),
6
6
  identity: z.boolean(),
7
7
  cart: z.boolean(),
8
- cartPayment: z.boolean(),
8
+ checkout: z.boolean(),
9
+ order: z.boolean(),
9
10
  inventory: z.boolean(),
10
11
  price: z.boolean(),
11
12
  category: z.boolean(),
@@ -1,23 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { CartIdentifierSchema, CartItemIdentifierSchema, IdentityIdentifierSchema, ProductIdentifierSchema, SKUIdentifierSchema } from "../models/identifiers.model";
3
3
  import { BaseModelSchema } from "./base.model";
4
- import { MonetaryAmountSchema } from "./price.model";
5
- import { AddressSchema } from "./profile.model";
6
- import { ShippingMethodSchema } from "./shipping-method.model";
7
- const CostBreakDownSchema = z.looseObject({
8
- totalTax: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The amount of tax paid on the cart. This may include VAT, GST, sales tax, etc."),
9
- totalDiscount: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The amount of discount applied to the cart."),
10
- totalSurcharge: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The amount of surcharge applied to the cart."),
11
- totalShipping: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The amount of shipping fees for the cart."),
12
- totalProductPrice: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The total price of products in the cart."),
13
- grandTotal: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The total price for the cart including all taxes, discounts, and shipping.")
14
- });
15
- const ItemCostBreakdownSchema = z.looseObject({
16
- unitPrice: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The price per single unit of the item."),
17
- unitDiscount: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The discount applied per single unit of the item."),
18
- totalPrice: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The total price for all units of the item."),
19
- totalDiscount: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The total discount applied to all units of the item.")
20
- });
4
+ import { CostBreakDownSchema, ItemCostBreakdownSchema } from "./cost.model";
21
5
  const CartItemSchema = z.looseObject({
22
6
  identifier: CartItemIdentifierSchema.default(() => CartItemIdentifierSchema.parse({})),
23
7
  product: ProductIdentifierSchema.default(() => ProductIdentifierSchema.parse({})),
@@ -31,14 +15,9 @@ const CartSchema = BaseModelSchema.extend({
31
15
  items: z.array(CartItemSchema).default(() => []),
32
16
  price: CostBreakDownSchema.default(() => CostBreakDownSchema.parse({})),
33
17
  name: z.string().default(""),
34
- description: z.string().default(""),
35
- shippingAddress: AddressSchema.optional(),
36
- billingAddress: AddressSchema.optional(),
37
- shippingMethod: ShippingMethodSchema.optional()
18
+ description: z.string().default("")
38
19
  });
39
20
  export {
40
21
  CartItemSchema,
41
- CartSchema,
42
- CostBreakDownSchema,
43
- ItemCostBreakdownSchema
22
+ CartSchema
44
23
  };
@@ -0,0 +1,44 @@
1
+ import { z } from "zod";
2
+ import { BaseModelSchema } from "./base.model";
3
+ import { CartIdentifierSchema, CheckoutIdentifierSchema, CheckoutItemIdentifierSchema, OrderIdentifierSchema, SKUIdentifierSchema } from "./identifiers.model";
4
+ import { CostBreakDownSchema, ItemCostBreakdownSchema } from "./cost.model";
5
+ import { AddressSchema } from "./profile.model";
6
+ import { ShippingInstructionSchema } from "./shipping-method.model";
7
+ import { PaymentInstructionSchema } from "./payment.model";
8
+ const CheckoutItemSchema = z.looseObject({
9
+ identifier: CheckoutItemIdentifierSchema.default(() => CheckoutItemIdentifierSchema.parse({})),
10
+ sku: SKUIdentifierSchema.default(() => SKUIdentifierSchema.parse({})),
11
+ quantity: z.number().default(0),
12
+ price: ItemCostBreakdownSchema.default(() => ItemCostBreakdownSchema.parse({}))
13
+ });
14
+ const CheckoutSchema = BaseModelSchema.extend({
15
+ identifier: CheckoutIdentifierSchema.default(() => CheckoutIdentifierSchema.parse({})),
16
+ /**
17
+ * Do we need this?
18
+ */
19
+ originalCartReference: CartIdentifierSchema.default(() => CartIdentifierSchema.parse({})),
20
+ /**
21
+ * If the checkout has been completed, this will point to the resulting order.
22
+ */
23
+ resultingOrder: OrderIdentifierSchema.optional(),
24
+ items: z.array(CheckoutItemSchema).default(() => []),
25
+ price: CostBreakDownSchema.default(() => CostBreakDownSchema.parse({})),
26
+ name: z.string().default(""),
27
+ description: z.string().default(""),
28
+ billingAddress: AddressSchema.optional(),
29
+ /**
30
+ * Shipping and billing details can be changed on the checkout, but not items or quantities.
31
+ */
32
+ shippingAddress: AddressSchema.optional(),
33
+ shippingInstruction: ShippingInstructionSchema.optional(),
34
+ paymentInstructions: z.array(PaymentInstructionSchema).default(() => []),
35
+ /**
36
+ * Indicates if the checkout has all the required information to be finalized into an order.
37
+ * This does not mean it will succeed, as there may be issues with payment or shipping, but all required information is present.
38
+ */
39
+ readyForFinalization: z.boolean().default(false).describe("Indicates if the checkout has all the required information to be finalized into an order. This does not mean it will succeed, as there may be issues with payment or shipping, but all required information is present.")
40
+ });
41
+ export {
42
+ CheckoutItemSchema,
43
+ CheckoutSchema
44
+ };
@@ -0,0 +1,20 @@
1
+ import z from "zod";
2
+ import { MonetaryAmountSchema } from "./price.model";
3
+ const CostBreakDownSchema = z.looseObject({
4
+ totalTax: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The amount of tax paid on the cart. This may include VAT, GST, sales tax, etc."),
5
+ totalDiscount: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The amount of discount applied to the cart."),
6
+ totalSurcharge: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The amount of surcharge applied to the cart."),
7
+ totalShipping: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The amount of shipping fees for the cart."),
8
+ totalProductPrice: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The total price of products in the cart."),
9
+ grandTotal: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The total price for the cart including all taxes, discounts, and shipping.")
10
+ });
11
+ const ItemCostBreakdownSchema = z.looseObject({
12
+ unitPrice: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The price per single unit of the item."),
13
+ unitDiscount: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The discount applied per single unit of the item."),
14
+ totalPrice: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The total price for all units of the item."),
15
+ totalDiscount: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The total discount applied to all units of the item.")
16
+ });
17
+ export {
18
+ CostBreakDownSchema,
19
+ ItemCostBreakdownSchema
20
+ };
@@ -39,6 +39,12 @@ const OrderIdentifierSchema = z.looseObject({
39
39
  const OrderItemIdentifierSchema = z.looseObject({
40
40
  key: z.string().default("").nonoptional()
41
41
  });
42
+ const CheckoutIdentifierSchema = z.looseObject({
43
+ key: z.string().default("").nonoptional()
44
+ });
45
+ const CheckoutItemIdentifierSchema = z.looseObject({
46
+ key: z.string().default("").nonoptional()
47
+ });
42
48
  const WebStoreIdentifierSchema = z.looseObject({
43
49
  key: z.string().default("").nonoptional()
44
50
  });
@@ -68,11 +74,16 @@ const AddressIdentifierSchema = z.looseObject({
68
74
  const PaymentInstructionIdentifierSchema = z.looseObject({
69
75
  key: z.string().default("").nonoptional()
70
76
  });
77
+ const PickupPointIdentifierSchema = z.looseObject({
78
+ key: z.string().default("").nonoptional()
79
+ });
71
80
  export {
72
81
  AddressIdentifierSchema,
73
82
  CartIdentifierSchema,
74
83
  CartItemIdentifierSchema,
75
84
  CategoryIdentifierSchema,
85
+ CheckoutIdentifierSchema,
86
+ CheckoutItemIdentifierSchema,
76
87
  FacetIdentifierSchema,
77
88
  FacetValueIdentifierSchema,
78
89
  FulfillmentCenterIdentifierSchema,
@@ -82,6 +93,7 @@ export {
82
93
  OrderItemIdentifierSchema,
83
94
  PaymentInstructionIdentifierSchema,
84
95
  PaymentMethodIdentifierSchema,
96
+ PickupPointIdentifierSchema,
85
97
  PriceIdentifierSchema,
86
98
  ProductIdentifierSchema,
87
99
  SKUIdentifierSchema,
@@ -2,18 +2,21 @@ import { z } from "zod";
2
2
  import { BaseModelSchema } from "./base.model";
3
3
  import { IdentityIdentifierSchema } from "./identifiers.model";
4
4
  const AnonymousIdentitySchema = BaseModelSchema.extend({
5
- type: z.literal("Anonymous")
5
+ type: z.literal("Anonymous").default("Anonymous"),
6
+ token: z.string().optional(),
7
+ refresh_token: z.string().optional(),
8
+ expiry: z.coerce.date().default(/* @__PURE__ */ new Date())
6
9
  });
7
10
  const GuestIdentitySchema = BaseModelSchema.extend({
8
11
  id: IdentityIdentifierSchema.default(() => IdentityIdentifierSchema.parse({})),
9
- type: z.literal("Guest"),
12
+ type: z.literal("Guest").default("Guest"),
10
13
  token: z.string().optional(),
11
14
  refresh_token: z.string().optional(),
12
15
  expiry: z.coerce.date().default(/* @__PURE__ */ new Date())
13
16
  });
14
17
  const RegisteredIdentitySchema = BaseModelSchema.extend({
15
18
  id: IdentityIdentifierSchema.default(() => IdentityIdentifierSchema.parse({})),
16
- type: z.literal("Registered"),
19
+ type: z.literal("Registered").default("Registered"),
17
20
  logonId: z.string().default(""),
18
21
  token: z.string().optional(),
19
22
  refresh_token: z.string().optional(),
@@ -13,3 +13,7 @@ export * from "./profile.model";
13
13
  export * from "./search.model";
14
14
  export * from "./shipping-method.model";
15
15
  export * from "./store.model";
16
+ export * from "./order.model";
17
+ export * from "./cost.model";
18
+ export * from "./checkout.model";
19
+ export * from "./payment.model";
@@ -0,0 +1,37 @@
1
+ import { z } from "zod";
2
+ import { CartIdentifierSchema, CartItemIdentifierSchema, IdentityIdentifierSchema, SKUIdentifierSchema } from "../models/identifiers.model";
3
+ import { BaseModelSchema } from "./base.model";
4
+ import { AddressSchema } from "./profile.model";
5
+ import { ShippingMethodSchema } from "./shipping-method.model";
6
+ import { CostBreakDownSchema, ItemCostBreakdownSchema } from "./cost.model";
7
+ import { PaymentInstructionSchema } from "./payment.model";
8
+ const OrderStatusSchema = z.enum(["AwaitingPayment", "ReleasedToFulfillment", "Shipped", "Cancelled"]).default("AwaitingPayment").describe("The current status of the order.");
9
+ const OrderInventoryStatusSchema = z.enum(["NotAllocated", "Allocated", "Backordered", "Preordered"]).default("Allocated").describe("The inventory release status of the order.");
10
+ const OrderItemSchema = z.looseObject({
11
+ identifier: CartItemIdentifierSchema.default(() => CartItemIdentifierSchema.parse({})),
12
+ sku: SKUIdentifierSchema.default(() => SKUIdentifierSchema.parse({})),
13
+ quantity: z.number().default(0),
14
+ price: ItemCostBreakdownSchema.default(() => ItemCostBreakdownSchema.parse({})),
15
+ inventoryStatus: OrderInventoryStatusSchema.default("Allocated").describe("The inventory release status of the order item.")
16
+ });
17
+ const OrderSchema = BaseModelSchema.extend({
18
+ identifier: CartIdentifierSchema.default(() => CartIdentifierSchema.parse({})),
19
+ userId: IdentityIdentifierSchema.default(() => IdentityIdentifierSchema.parse({})),
20
+ items: z.array(OrderItemSchema).default(() => []),
21
+ price: CostBreakDownSchema.default(() => CostBreakDownSchema.parse({})),
22
+ name: z.string().default(""),
23
+ description: z.string().default(""),
24
+ shippingAddress: AddressSchema.optional(),
25
+ billingAddress: AddressSchema.optional(),
26
+ shippingMethod: ShippingMethodSchema.optional(),
27
+ orderStatus: OrderStatusSchema.default("AwaitingPayment"),
28
+ inventoryStatus: OrderInventoryStatusSchema.default("Allocated"),
29
+ paymentInstructions: z.array(PaymentInstructionSchema).default(() => []),
30
+ cartReference: CartIdentifierSchema.optional().describe("Reference to the cart from which this order was created.")
31
+ });
32
+ export {
33
+ OrderInventoryStatusSchema,
34
+ OrderItemSchema,
35
+ OrderSchema,
36
+ OrderStatusSchema
37
+ };
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { BaseModelSchema, ImageSchema } from "./base.model";
3
- import { CartIdentifierSchema, PaymentInstructionIdentifierSchema, PaymentMethodIdentifierSchema } from "./identifiers.model";
3
+ import { PaymentInstructionIdentifierSchema, PaymentMethodIdentifierSchema } from "./identifiers.model";
4
4
  import { MonetaryAmountSchema } from "./price.model";
5
5
  const PaymentStatusSchema = z.enum(["pending", "authorized", "canceled", "capture", "partial_capture", "refunded", "partial_refund"]);
6
6
  const PaymentProtocolDataSchema = z.looseObject({
@@ -20,16 +20,7 @@ const PaymentInstructionSchema = BaseModelSchema.extend({
20
20
  protocolData: z.array(PaymentProtocolDataSchema).default(() => []).describe("Additional protocol-specific data for processing the payment."),
21
21
  status: PaymentStatusSchema.default("pending")
22
22
  });
23
- const CartPaymentInstructionSchema = PaymentInstructionSchema.extend({
24
- cart: CartIdentifierSchema.default(() => CartIdentifierSchema.parse({}))
25
- });
26
- const OrderPaymentInstructionSchema = PaymentInstructionSchema.extend({
27
- order: z.string().default("")
28
- // OrderIdentifierSchema
29
- });
30
23
  export {
31
- CartPaymentInstructionSchema,
32
- OrderPaymentInstructionSchema,
33
24
  PaymentInstructionSchema,
34
25
  PaymentMethodSchema,
35
26
  PaymentProtocolDataSchema,
@@ -1,8 +1,11 @@
1
1
  import { z } from "zod";
2
- import { ProductIdentifierSchema } from "./identifiers.model";
2
+ import { ProductIdentifierSchema, SKUIdentifierSchema } from "./identifiers.model";
3
3
  import { BaseModelSchema } from "./base.model";
4
4
  const SKUSchema = z.looseObject({
5
- identifier: ProductIdentifierSchema.default(() => ProductIdentifierSchema.parse({}))
5
+ identifier: SKUIdentifierSchema.default(() => SKUIdentifierSchema.parse({}))
6
+ /* name: z.string().default(''),
7
+ slug: z.string().default(''),
8
+ image: ImageSchema.default(() => ImageSchema.parse({})), */
6
9
  });
7
10
  const ProductAttributeSchema = z.looseObject({
8
11
  id: z.string(),
@@ -1,15 +1,37 @@
1
1
  import z from "zod";
2
2
  import { ShippingMethodIdentifierSchema } from "./identifiers.model";
3
3
  import { MonetaryAmountSchema } from "./price.model";
4
- import { ImageSchema } from "./base.model";
4
+ import { BaseModelSchema, ImageSchema } from "./base.model";
5
+ import { AddressSchema } from "./profile.model";
6
+ const PickupPointSchema = z.looseObject({
7
+ identifier: z.object({
8
+ key: z.string().default("").nonoptional()
9
+ }).default(() => ({ key: "" })),
10
+ name: z.string().default(""),
11
+ description: z.string().default(""),
12
+ address: AddressSchema.default(() => AddressSchema.parse({})),
13
+ openingHours: z.string().default("").optional().describe('The opening hours of the pickup point, if applicable. This could be a string like "Mon-Fri 9am-5pm".'),
14
+ contactPhone: z.string().default("").optional().describe("The contact phone number for the pickup point, if applicable."),
15
+ contactEmail: z.string().default("").optional().describe("The contact email for the pickup point, if applicable."),
16
+ instructions: z.string().default("").optional().describe("Any special instructions for picking up from this point.")
17
+ });
5
18
  const ShippingMethodSchema = z.looseObject({
6
19
  identifier: ShippingMethodIdentifierSchema.default(() => ShippingMethodIdentifierSchema.parse({})),
7
20
  name: z.string().default(""),
8
21
  description: z.string().default(""),
9
22
  logo: ImageSchema.optional(),
10
23
  price: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})),
11
- deliveryTime: z.string().default("")
24
+ deliveryTime: z.string().default(""),
25
+ carrier: z.string().default("").optional()
26
+ });
27
+ const ShippingInstructionSchema = BaseModelSchema.extend({
28
+ shippingMethod: ShippingMethodIdentifierSchema.default(() => ShippingMethodIdentifierSchema.parse({})),
29
+ pickupPoint: z.string().default("").describe("An optional pickup point for the shipping method. This could be a physical store, a locker, or similar. If not set, it means home delivery to the shipping address."),
30
+ instructions: z.string().default("").describe("Optional instructions for the shipping. This could be delivery instructions, or similar."),
31
+ consentForUnattendedDelivery: z.boolean().default(false).describe("Indicates if the customer has given consent for unattended delivery, if applicable.")
12
32
  });
13
33
  export {
34
+ PickupPointSchema,
35
+ ShippingInstructionSchema,
14
36
  ShippingMethodSchema
15
37
  };
@@ -0,0 +1,36 @@
1
+ import z from "zod";
2
+ import { CartIdentifierSchema, AddressSchema, PaymentInstructionIdentifierSchema, PaymentInstructionSchema, ShippingInstructionSchema } from "../models";
3
+ import { BaseMutationSchema } from "./base.mutation";
4
+ const CheckoutMutationInitiateCheckoutSchema = BaseMutationSchema.extend({
5
+ cart: CartIdentifierSchema.required(),
6
+ billingAddress: AddressSchema.omit({ identifier: true }).optional(),
7
+ notificationEmail: z.string().optional(),
8
+ notificationPhone: z.string().optional()
9
+ });
10
+ const CheckoutMutationSetShippingAddressSchema = BaseMutationSchema.extend({
11
+ checkout: CartIdentifierSchema.required(),
12
+ shippingAddress: AddressSchema.omit({ identifier: true }).required()
13
+ });
14
+ const CheckoutMutationFinalizeCheckoutSchema = BaseMutationSchema.extend({
15
+ checkout: CartIdentifierSchema.required()
16
+ });
17
+ const CheckoutMutationAddPaymentInstruction = BaseMutationSchema.extend({
18
+ paymentInstruction: PaymentInstructionSchema.omit({ meta: true, status: true, identifier: true }).required(),
19
+ checkout: CartIdentifierSchema.required()
20
+ });
21
+ const CheckoutMutationRemovePaymentInstruction = BaseMutationSchema.extend({
22
+ paymentInstruction: PaymentInstructionIdentifierSchema.required(),
23
+ checkout: CartIdentifierSchema.required()
24
+ });
25
+ const CheckoutMutationSetShippingInstruction = BaseMutationSchema.extend({
26
+ shippingInstruction: ShippingInstructionSchema.omit({ meta: true, status: true, identifier: true }).required(),
27
+ checkout: CartIdentifierSchema.required()
28
+ });
29
+ export {
30
+ CheckoutMutationAddPaymentInstruction,
31
+ CheckoutMutationFinalizeCheckoutSchema,
32
+ CheckoutMutationInitiateCheckoutSchema,
33
+ CheckoutMutationRemovePaymentInstruction,
34
+ CheckoutMutationSetShippingAddressSchema,
35
+ CheckoutMutationSetShippingInstruction
36
+ };
@@ -1,6 +1,5 @@
1
1
  export * from "./analytics.mutation";
2
2
  export * from "./base.mutation";
3
- export * from "./cart-payment.mutation";
4
3
  export * from "./cart.mutation";
5
4
  export * from "./identity.mutation";
6
5
  export * from "./inventory.mutation";
@@ -8,3 +7,4 @@ export * from "./price.mutation";
8
7
  export * from "./product.mutation";
9
8
  export * from "./profile.mutation";
10
9
  export * from "./search.mutation";
10
+ export * from "./checkout.mutation";
@@ -0,0 +1,16 @@
1
+ import { BaseQuerySchema } from "./base.query";
2
+ import { CheckoutIdentifierSchema } from "../models/identifiers.model";
3
+ const CheckoutQueryByIdSchema = BaseQuerySchema.extend({
4
+ identifier: CheckoutIdentifierSchema.required()
5
+ });
6
+ const CheckoutQueryForAvailableShippingMethodsSchema = BaseQuerySchema.extend({
7
+ checkout: CheckoutIdentifierSchema.required()
8
+ });
9
+ const CheckoutQueryForAvailablePaymentMethodsSchema = BaseQuerySchema.extend({
10
+ checkout: CheckoutIdentifierSchema.required()
11
+ });
12
+ export {
13
+ CheckoutQueryByIdSchema,
14
+ CheckoutQueryForAvailablePaymentMethodsSchema,
15
+ CheckoutQueryForAvailableShippingMethodsSchema
16
+ };
@@ -1,6 +1,5 @@
1
1
  export * from "./analytics.query";
2
2
  export * from "./base.query";
3
- export * from "./cart-payment.query";
4
3
  export * from "./cart.query";
5
4
  export * from "./category.query";
6
5
  export * from "./identity.query";
@@ -10,3 +9,5 @@ export * from "./product.query";
10
9
  export * from "./profile.query";
11
10
  export * from "./search.query";
12
11
  export * from "./store.query";
12
+ export * from "./order.query";
13
+ export * from "./checkout.query";
@@ -0,0 +1,8 @@
1
+ import { BaseQuerySchema } from "./base.query";
2
+ import { OrderIdentifierSchema } from "../models/identifiers.model";
3
+ const OrderQueryByIdSchema = BaseQuerySchema.extend({
4
+ order: OrderIdentifierSchema.required()
5
+ });
6
+ export {
7
+ OrderQueryByIdSchema
8
+ };
@@ -1,12 +1,17 @@
1
1
  import { z } from "zod";
2
2
  import { BaseQuerySchema } from "./base.query";
3
+ import { SKUIdentifierSchema } from "../models";
3
4
  const ProductQueryBySlugSchema = BaseQuerySchema.extend({
4
5
  slug: z.string()
5
6
  });
6
7
  const ProductQueryByIdSchema = BaseQuerySchema.extend({
7
8
  id: z.string()
8
9
  });
10
+ const ProductQueryBySKUSchema = BaseQuerySchema.extend({
11
+ sku: SKUIdentifierSchema.default(() => SKUIdentifierSchema.parse({}))
12
+ });
9
13
  export {
10
14
  ProductQueryByIdSchema,
15
+ ProductQueryBySKUSchema,
11
16
  ProductQueryBySlugSchema
12
17
  };
@@ -7,14 +7,14 @@ import type { PriceProvider } from "../providers/price.provider";
7
7
  import type { InventoryProvider } from "../providers/inventory.provider";
8
8
  import type { Cache } from "../cache/cache.interface";
9
9
  import type { CategoryProvider } from "../providers/category.provider";
10
- import type { CartPaymentProvider } from "../providers";
10
+ import type { CheckoutProvider } from "../providers";
11
11
  export interface Client {
12
12
  product: ProductProvider;
13
13
  search: SearchProvider;
14
14
  identity: IdentityProvider;
15
15
  cache: Cache;
16
16
  cart: CartProvider;
17
- cartPayment: CartPaymentProvider;
17
+ checkout: CheckoutProvider;
18
18
  analytics: Array<AnalyticsProvider>;
19
19
  price: PriceProvider;
20
20
  inventory: InventoryProvider;
@@ -0,0 +1,135 @@
1
+ import type { Checkout, PaymentMethod, ShippingMethod } from "../schemas/models";
2
+ import type { RequestContext } from "../schemas/session.schema";
3
+ import { BaseProvider } from "./base.provider";
4
+ import type { CheckoutMutationFinalizeCheckout, CheckoutMutationInitiateCheckout, CheckoutMutationSetShippingAddress, CheckoutMutationAddPaymentInstruction, CheckoutMutationRemovePaymentInstruction, CheckoutMutationSetShippingInstruction } from "../schemas/mutations/checkout.mutation";
5
+ import type { CheckoutQueryById, CheckoutQueryForAvailablePaymentMethods, CheckoutQueryForAvailableShippingMethods } from "../schemas/queries";
6
+ export declare abstract class CheckoutProvider<T extends Checkout = Checkout> extends BaseProvider<T> {
7
+ /**
8
+ * This starts a new checkout session for the given cart. The checkout might duplicate the cart, or just reference it, depending on implementation, but changes to the cart,
9
+ * is not reflected in the checkout, and vice versa. The checkout is a snapshot of the cart at the time of initiation.
10
+ * The checkout will typically copy over addresses from the user profile, if available, or from the anonymous profile in the session.
11
+ *
12
+ * Usecase: User has filled out cart, and is ready to checkout. You call this to create a checkout object, that you can then use to set shipping method, payment method etc.
13
+ * @param cartId The cart you are trying to checkout
14
+ * @param billingAddress the billing/shipping address to start with. This affects available shipping methods, and may be required by some payment providers.
15
+ * @param reqCtx
16
+ */
17
+ abstract initiateCheckoutForCart(payload: CheckoutMutationInitiateCheckout, reqCtx: RequestContext): Promise<T>;
18
+ /**
19
+ * Fetches an existing checkout by its identifier.
20
+ *
21
+ * Usecase: User has navigated to the checkout page, or reloaded on it , or has been redirected back from the payment provider.
22
+ * @param payload
23
+ * @param reqCtx
24
+ */
25
+ abstract getById(payload: CheckoutQueryById, reqCtx: RequestContext): Promise<T | null>;
26
+ /**
27
+ * Updates the shipping address for the checkout and recalculates the shipping methods and totals.
28
+ *
29
+ * Usecase: User has chosen home delivery and you have allowed them to change the address on the checkout page.
30
+ *
31
+ * NOTE: Unsure this is really needed.
32
+ * @param shippingAddress The updated shipping address. Note: This may also be the billing address, if your store does not differentiate.
33
+ */
34
+ abstract setShippingAddress(payload: CheckoutMutationSetShippingAddress, reqCtx: RequestContext): Promise<T>;
35
+ /**
36
+ * Returns all available shipping methods for the given checkout. This will typically depend on the shipping address, and possibly also the items in the checkout.
37
+ *
38
+ * Usecase: User has filled out shipping address, and you need to show available shipping methods.
39
+ *
40
+ * @param checkoutId The checkout you want to get shipping methods for.
41
+ * @param reqCtx
42
+ */
43
+ abstract getAvailableShippingMethods(payload: CheckoutQueryForAvailableShippingMethods, reqCtx: RequestContext): Promise<ShippingMethod[]>;
44
+ /**
45
+ * Returns all available payment methods for the given checkout. This will typically depend mostly on the billing address and jurisdiction.
46
+ *
47
+ * Usecase: User has chosen shipping method, and you need to show available payment methods.
48
+ *
49
+ * @param checkoutId The checkout you want to get payment methods for.
50
+ * @param reqCtx
51
+ */
52
+ abstract getAvailablePaymentMethods(payload: CheckoutQueryForAvailablePaymentMethods, reqCtx: RequestContext): Promise<PaymentMethod[]>;
53
+ /**
54
+ * Adds a payment instruction to the checkout. This will typically create a payment intent in the payment provider, and return whatever is needed to continue the payment process, e.g. a client secret for Stripe, or a redirect URL for PayPal.
55
+ *
56
+ * Usecase: User has chosen a payment method, and you need to start the payment process.
57
+ */
58
+ abstract addPaymentInstruction(payload: CheckoutMutationAddPaymentInstruction, reqCtx: RequestContext): Promise<T>;
59
+ /**
60
+ * Removes a payment instruction from the checkout. This will typically void the payment intent in the payment provider, and remove the payment instruction from the checkout.
61
+ *
62
+ * Usecase: User has decided to change payment method, or has cancelled the payment process.
63
+ * @param paymentInstructionId
64
+ */
65
+ abstract removePaymentInstruction(payload: CheckoutMutationRemovePaymentInstruction, reqCtx: RequestContext): Promise<T>;
66
+ /**
67
+ * Sets the shipping method and optional pickup point for the checkout. The pickup point can be a physical store, a locker, or similar.
68
+ * If it is unset, it means home delivery to the shipping address.
69
+ *
70
+ *
71
+ * Usecase: record all the users shipping choices, and any special instructions they may have added.
72
+ *
73
+ * @param shippingMethodId
74
+ * @param pickupPoint
75
+ */
76
+ abstract setShippingInstruction(payload: CheckoutMutationSetShippingInstruction, reqCtx: RequestContext): Promise<T>;
77
+ /**
78
+ * Finalizes the checkout process. This typically involves creating an order from the checkout and processing payment.
79
+ *
80
+ * Usecase: User has completed all necessary steps in the checkout process and is ready to place the order.
81
+ *
82
+ * @param payload
83
+ * @param reqCtx
84
+ */
85
+ abstract finalizeCheckout(payload: CheckoutMutationFinalizeCheckout, reqCtx: RequestContext): Promise<T>;
86
+ }
87
+ /**
88
+ *
89
+ *
90
+ * How would this be used?
91
+ * // navigated to /payment
92
+ *
93
+ * const cart = await cartProvider.getById({id: 'cart-123'}, reqCtx);
94
+ *
95
+ * let address = null;
96
+ * if (reqCtx.identity.isAuthenticated) {
97
+ * const profile = await profileProvider.getByUserId({userId: reqCtx.identity.userId}, reqCtx);
98
+ * address = profile?.addresses?.[0];
99
+ * }
100
+ * if (!address) {
101
+ * address = reqCtx.session.anonymousProfile?.addresses?.[0];
102
+ * }
103
+ *
104
+ * // ok we are ready for checkout...
105
+ * const checkout = await checkoutProvider.initiateCheckoutForCart(cart.identifier, address, reqCtx);
106
+ *
107
+ * const paymentMethods = await paymentProvider.getAvailablePaymentMethods(checkout, reqCtx);
108
+ * const shippingMethods = await shippingProvider.getAvailableShippingMethods(checkout, reqCtx);
109
+ *
110
+ *
111
+ * onShippingSelected = async (shippingMethodId, pickupPoint) => {
112
+ * const checkout = await checkoutProvider.setShippingMethod(checkout.identifier, shippingMethodId, pickupPoint);
113
+ * return checkout;
114
+ * }
115
+ *
116
+ * onPaymentSelected = async (paymentMethodId) => {
117
+ * const checkout = await checkoutProvider.addPaymentInstruction(checkout.identifier, paymentMethodId);
118
+ * return checkout;
119
+ * }
120
+ *
121
+ * if (checkout.paymentInstructions.length === 0) {
122
+ * // show payment method selection
123
+ * return <PaymentMethodSelection methods={paymentMethods} onSelect={onPaymentSelected} />
124
+ *
125
+ * } else {
126
+ * if (checkout.paymentInstructions[0].status !== 'Authorized') {
127
+ * const pi = checkout.paymentInstructions[0];
128
+ * if (pi.provider === 'stripe') {
129
+ * return new StripeForm(pi.protocolData.find(x => x.key === 'clientSecret').value, onPaymentAuthorized);
130
+ * } else if (pi.provider === 'adyen') {
131
+ * return new RedirectTo(pi.protocolData.find(x => x.key === 'punchoutUrl').value);
132
+ * }
133
+ * }
134
+ * })
135
+ */
@@ -1,8 +1,8 @@
1
1
  export * from './analytics.provider';
2
2
  export * from './base.provider';
3
- export * from './cart-payment.provider';
4
3
  export * from './cart.provider';
5
4
  export * from './category.provider';
5
+ export * from './checkout.provider';
6
6
  export * from './identity.provider';
7
7
  export * from './inventory.provider';
8
8
  export * from './price.provider';
@@ -10,3 +10,4 @@ export * from './product.provider';
10
10
  export * from './profile.provider';
11
11
  export * from './search.provider';
12
12
  export * from './store.provider';
13
+ export * from './order.provider';