From 2446151420747794711ba9d7149f2a55269b4bd9 Mon Sep 17 00:00:00 2001 From: Riqwan Thamir Date: Tue, 23 Apr 2024 13:31:52 +0200 Subject: [PATCH] feat(medusa): migrate store cart endpoints to zod (#7130) --- .changeset/three-mangos-judge.md | 5 + .../carts/[id]/line-items/[line_id]/route.ts | 43 ++--- .../[id]/line-items/[line_id]/validators.ts | 9 - .../store/carts/[id]/line-items/route.ts | 36 ++-- .../store/carts/[id]/line-items/validators.ts | 12 -- .../carts/[id]/payment-collections/route.ts | 39 ++-- .../store/carts/[id]/promotions/route.ts | 51 ++--- .../src/api-v2/store/carts/[id]/route.ts | 33 ++-- .../api-v2/store/carts/[id]/taxes/route.ts | 28 +-- .../medusa/src/api-v2/store/carts/helpers.ts | 22 +++ .../src/api-v2/store/carts/middlewares.ts | 99 ++++++++-- .../medusa/src/api-v2/store/carts/route.ts | 16 +- .../src/api-v2/store/carts/validators.ts | 174 +++++++----------- 13 files changed, 275 insertions(+), 292 deletions(-) create mode 100644 .changeset/three-mangos-judge.md delete mode 100644 packages/medusa/src/api-v2/store/carts/[id]/line-items/[line_id]/validators.ts delete mode 100644 packages/medusa/src/api-v2/store/carts/[id]/line-items/validators.ts create mode 100644 packages/medusa/src/api-v2/store/carts/helpers.ts diff --git a/.changeset/three-mangos-judge.md b/.changeset/three-mangos-judge.md new file mode 100644 index 0000000000..d5b4863d1b --- /dev/null +++ b/.changeset/three-mangos-judge.md @@ -0,0 +1,5 @@ +--- +"@medusajs/medusa": patch +--- + +feat(medusa): migrate store cart endpoints to zod diff --git a/packages/medusa/src/api-v2/store/carts/[id]/line-items/[line_id]/route.ts b/packages/medusa/src/api-v2/store/carts/[id]/line-items/[line_id]/route.ts index 8389f115be..03468672d9 100644 --- a/packages/medusa/src/api-v2/store/carts/[id]/line-items/[line_id]/route.ts +++ b/packages/medusa/src/api-v2/store/carts/[id]/line-items/[line_id]/route.ts @@ -4,12 +4,15 @@ import { } from "@medusajs/core-flows" import { ModuleRegistrationName } from "@medusajs/modules-sdk" import { ICartModuleService } from "@medusajs/types" -import { MedusaError, remoteQueryObjectFromString } from "@medusajs/utils" +import { MedusaError } from "@medusajs/utils" import { MedusaRequest, MedusaResponse } from "../../../../../../types/routing" -import { defaultStoreCartFields } from "../../../query-config" -import { StorePostCartsCartLineItemsItemReq } from "./validators" +import { refetchCart } from "../../../helpers" +import { StoreUpdateCartLineItemType } from "../../../validators" -export const POST = async (req: MedusaRequest, res: MedusaResponse) => { +export const POST = async ( + req: MedusaRequest, + res: MedusaResponse +) => { const cartModuleService = req.scope.resolve( ModuleRegistrationName.CART ) @@ -31,7 +34,7 @@ export const POST = async (req: MedusaRequest, res: MedusaResponse) => { const input = { cart, item, - update: req.validatedBody as StorePostCartsCartLineItemsItemReq, + update: req.validatedBody, } const { errors } = await updateLineItemInCartWorkflow(req.scope).run({ @@ -43,16 +46,11 @@ export const POST = async (req: MedusaRequest, res: MedusaResponse) => { throw errors[0].error } - const remoteQuery = req.scope.resolve("remoteQuery") - - const query = remoteQueryObjectFromString({ - entryPoint: "cart", - fields: defaultStoreCartFields, - }) - - const [updatedCart] = await remoteQuery(query, { - cart: { id: req.params.id }, - }) + const updatedCart = await refetchCart( + req.params.id, + req.scope, + req.remoteQueryConfig.fields + ) res.status(200).json({ cart: updatedCart }) } @@ -69,16 +67,11 @@ export const DELETE = async (req: MedusaRequest, res: MedusaResponse) => { throw errors[0].error } - const remoteQuery = req.scope.resolve("remoteQuery") - - const query = remoteQueryObjectFromString({ - entryPoint: "cart", - fields: defaultStoreCartFields, - }) - - const [cart] = await remoteQuery(query, { - cart: { id: req.params.id }, - }) + const cart = await refetchCart( + req.params.id, + req.scope, + req.remoteQueryConfig.fields + ) res.status(200).json({ cart }) } diff --git a/packages/medusa/src/api-v2/store/carts/[id]/line-items/[line_id]/validators.ts b/packages/medusa/src/api-v2/store/carts/[id]/line-items/[line_id]/validators.ts deleted file mode 100644 index 2ea37e5dcf..0000000000 --- a/packages/medusa/src/api-v2/store/carts/[id]/line-items/[line_id]/validators.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { IsInt, IsOptional } from "class-validator" - -export class StorePostCartsCartLineItemsItemReq { - @IsInt() - quantity: number - - @IsOptional() - metadata?: Record | undefined -} diff --git a/packages/medusa/src/api-v2/store/carts/[id]/line-items/route.ts b/packages/medusa/src/api-v2/store/carts/[id]/line-items/route.ts index 9b4cc9664d..694137c2a0 100644 --- a/packages/medusa/src/api-v2/store/carts/[id]/line-items/route.ts +++ b/packages/medusa/src/api-v2/store/carts/[id]/line-items/route.ts @@ -1,24 +1,20 @@ import { addToCartWorkflow } from "@medusajs/core-flows" -import { LinkModuleUtils, Modules } from "@medusajs/modules-sdk" -import { remoteQueryObjectFromString } from "@medusajs/utils" import { MedusaRequest, MedusaResponse } from "../../../../../types/routing" -import { defaultStoreCartFields } from "../../query-config" -import { StorePostCartsCartLineItemsReq } from "./validators" +import { refetchCart } from "../../helpers" +import { StoreAddCartLineItemType } from "../../validators" -export const POST = async (req: MedusaRequest, res: MedusaResponse) => { - const remoteQuery = req.scope.resolve(LinkModuleUtils.REMOTE_QUERY) - - const query = remoteQueryObjectFromString({ - entryPoint: Modules.CART, - fields: defaultStoreCartFields, - }) - - const [cart] = await remoteQuery(query, { - cart: { id: req.params.id }, - }) +export const POST = async ( + req: MedusaRequest, + res: MedusaResponse +) => { + const cart = await refetchCart( + req.params.id, + req.scope, + req.remoteQueryConfig.fields + ) const workflowInput = { - items: [req.validatedBody as StorePostCartsCartLineItemsReq], + items: [req.validatedBody], cart, } @@ -31,9 +27,11 @@ export const POST = async (req: MedusaRequest, res: MedusaResponse) => { throw errors[0].error } - const [updatedCart] = await remoteQuery(query, { - cart: { id: req.params.id }, - }) + const updatedCart = await refetchCart( + req.params.id, + req.scope, + req.remoteQueryConfig.fields + ) res.status(200).json({ cart: updatedCart }) } diff --git a/packages/medusa/src/api-v2/store/carts/[id]/line-items/validators.ts b/packages/medusa/src/api-v2/store/carts/[id]/line-items/validators.ts deleted file mode 100644 index d382565776..0000000000 --- a/packages/medusa/src/api-v2/store/carts/[id]/line-items/validators.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { IsInt, IsOptional, IsString } from "class-validator" - -export class StorePostCartsCartLineItemsReq { - @IsString() - variant_id: string - - @IsInt() - quantity: number - - @IsOptional() - metadata?: Record | undefined -} diff --git a/packages/medusa/src/api-v2/store/carts/[id]/payment-collections/route.ts b/packages/medusa/src/api-v2/store/carts/[id]/payment-collections/route.ts index 9139444588..fd5ad696e4 100644 --- a/packages/medusa/src/api-v2/store/carts/[id]/payment-collections/route.ts +++ b/packages/medusa/src/api-v2/store/carts/[id]/payment-collections/route.ts @@ -1,28 +1,19 @@ import { createPaymentCollectionForCartWorkflow } from "@medusajs/core-flows" -import { UpdateCartDataDTO } from "@medusajs/types" -import { remoteQueryObjectFromString } from "@medusajs/utils" - import { MedusaRequest, MedusaResponse } from "../../../../../types/routing" -import { defaultStoreCartFields } from "../../query-config" +import { refetchCart } from "../../helpers" +import { StoreUpdateCartType } from "../../validators" export const POST = async ( - req: MedusaRequest, + req: MedusaRequest, res: MedusaResponse ) => { const workflow = createPaymentCollectionForCartWorkflow(req.scope) - - const remoteQuery = req.scope.resolve("remoteQuery") - - let [cart] = await remoteQuery( - { - cart: { - fields: ["id", "currency_code", "region_id", "total"], - }, - }, - { - cart: { id: req.params.id }, - } - ) + let cart = await refetchCart(req.params.id, req.scope, [ + "id", + "currency_code", + "region_id", + "total", + ]) const { errors } = await workflow.run({ input: { @@ -38,13 +29,11 @@ export const POST = async ( throw errors[0].error } - const query = remoteQueryObjectFromString({ - entryPoint: "cart", - variables: { id: req.params.id }, - fields: defaultStoreCartFields, - }) - - ;[cart] = await remoteQuery(query) + cart = await refetchCart( + req.params.id, + req.scope, + req.remoteQueryConfig.fields + ) res.status(200).json({ cart }) } diff --git a/packages/medusa/src/api-v2/store/carts/[id]/promotions/route.ts b/packages/medusa/src/api-v2/store/carts/[id]/promotions/route.ts index 3758965d9f..4b79c4295f 100644 --- a/packages/medusa/src/api-v2/store/carts/[id]/promotions/route.ts +++ b/packages/medusa/src/api-v2/store/carts/[id]/promotions/route.ts @@ -1,13 +1,18 @@ import { updateCartPromotionsWorkflow } from "@medusajs/core-flows" -import { PromotionActions, remoteQueryObjectFromString } from "@medusajs/utils" +import { PromotionActions } from "@medusajs/utils" import { MedusaRequest, MedusaResponse } from "../../../../../types/routing" -import { defaultStoreCartFields } from "../../query-config" -import { StorePostCartsCartPromotionsReq } from "../../validators" +import { refetchCart } from "../../helpers" +import { + StoreAddCartPromotionsType, + StoreRemoveCartPromotionsType, +} from "../../validators" -export const POST = async (req: MedusaRequest, res: MedusaResponse) => { - const remoteQuery = req.scope.resolve("remoteQuery") +export const POST = async ( + req: MedusaRequest, + res: MedusaResponse +) => { const workflow = updateCartPromotionsWorkflow(req.scope) - const payload = req.validatedBody as StorePostCartsCartPromotionsReq + const payload = req.validatedBody const { errors } = await workflow.run({ input: { @@ -22,22 +27,21 @@ export const POST = async (req: MedusaRequest, res: MedusaResponse) => { throw errors[0].error } - const query = remoteQueryObjectFromString({ - entryPoint: "cart", - fields: defaultStoreCartFields, - }) - - const [cart] = await remoteQuery(query, { - cart: { id: req.params.id }, - }) + const cart = await refetchCart( + req.params.id, + req.scope, + req.remoteQueryConfig.fields + ) res.status(200).json({ cart }) } -export const DELETE = async (req: MedusaRequest, res: MedusaResponse) => { - const remoteQuery = req.scope.resolve("remoteQuery") +export const DELETE = async ( + req: MedusaRequest, + res: MedusaResponse +) => { const workflow = updateCartPromotionsWorkflow(req.scope) - const payload = req.validatedBody as StorePostCartsCartPromotionsReq + const payload = req.validatedBody const { errors } = await workflow.run({ input: { @@ -52,14 +56,11 @@ export const DELETE = async (req: MedusaRequest, res: MedusaResponse) => { throw errors[0].error } - const query = remoteQueryObjectFromString({ - entryPoint: "cart", - fields: defaultStoreCartFields, - }) - - const [cart] = await remoteQuery(query, { - cart: { id: req.params.id }, - }) + const cart = await refetchCart( + req.params.id, + req.scope, + req.remoteQueryConfig.fields + ) res.status(200).json({ cart }) } diff --git a/packages/medusa/src/api-v2/store/carts/[id]/route.ts b/packages/medusa/src/api-v2/store/carts/[id]/route.ts index 853ff965d9..bbd49bef27 100644 --- a/packages/medusa/src/api-v2/store/carts/[id]/route.ts +++ b/packages/medusa/src/api-v2/store/carts/[id]/route.ts @@ -1,21 +1,15 @@ import { updateCartWorkflow } from "@medusajs/core-flows" -import { LinkModuleUtils, Modules } from "@medusajs/modules-sdk" import { UpdateCartDataDTO } from "@medusajs/types" -import { remoteQueryObjectFromString } from "@medusajs/utils" import { MedusaRequest, MedusaResponse } from "../../../../types/routing" -import { defaultStoreCartFields } from "../query-config" +import { refetchCart } from "../helpers" export const GET = async (req: MedusaRequest, res: MedusaResponse) => { - const remoteQuery = req.scope.resolve(LinkModuleUtils.REMOTE_QUERY) - const variables = { id: req.params.id } - - const query = remoteQueryObjectFromString({ - entryPoint: Modules.CART, - fields: req.remoteQueryConfig.fields, - }) - - const [cart] = await remoteQuery(query, { cart: variables }) + const cart = await refetchCart( + req.params.id, + req.scope, + req.remoteQueryConfig.fields + ) res.json({ cart }) } @@ -38,16 +32,11 @@ export const POST = async ( throw errors[0].error } - const remoteQuery = req.scope.resolve(LinkModuleUtils.REMOTE_QUERY) - - const query = remoteQueryObjectFromString({ - entryPoint: Modules.CART, - fields: defaultStoreCartFields, - }) - - const [cart] = await remoteQuery(query, { - cart: { id: req.params.id }, - }) + const cart = await refetchCart( + req.params.id, + req.scope, + req.remoteQueryConfig.fields + ) res.status(200).json({ cart }) } diff --git a/packages/medusa/src/api-v2/store/carts/[id]/taxes/route.ts b/packages/medusa/src/api-v2/store/carts/[id]/taxes/route.ts index 4a8cf8e376..75565db903 100644 --- a/packages/medusa/src/api-v2/store/carts/[id]/taxes/route.ts +++ b/packages/medusa/src/api-v2/store/carts/[id]/taxes/route.ts @@ -1,15 +1,10 @@ import { updateTaxLinesWorkflow } from "@medusajs/core-flows" -import { Modules } from "@medusajs/modules-sdk" -import { - ContainerRegistrationKeys, - remoteQueryObjectFromString, -} from "@medusajs/utils" import { MedusaRequest, MedusaResponse } from "../../../../../types/routing" -import { defaultStoreCartFields } from "../../query-config" -import { StorePostCartsCartTaxesReq } from "../../validators" +import { refetchCart } from "../../helpers" +import { StoreCalculateCartTaxesType } from "../../validators" export const POST = async ( - req: MedusaRequest, + req: MedusaRequest, res: MedusaResponse ) => { const workflow = updateTaxLinesWorkflow(req.scope) @@ -26,18 +21,11 @@ export const POST = async ( throw errors[0].error } - const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) - - const query = remoteQueryObjectFromString({ - entryPoint: Modules.CART, - fields: defaultStoreCartFields, - }) - - const [cart] = await remoteQuery(query, { - cart: { id: req.params.id }, - }) - - // TODO: wrap result with totals when totals calculation is ready + const cart = await refetchCart( + req.params.id, + req.scope, + req.remoteQueryConfig.fields + ) res.status(200).json({ cart }) } diff --git a/packages/medusa/src/api-v2/store/carts/helpers.ts b/packages/medusa/src/api-v2/store/carts/helpers.ts new file mode 100644 index 0000000000..87fb9be088 --- /dev/null +++ b/packages/medusa/src/api-v2/store/carts/helpers.ts @@ -0,0 +1,22 @@ +import { MedusaContainer } from "@medusajs/types" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" + +export const refetchCart = async ( + id: string, + scope: MedusaContainer, + fields: string[] +) => { + const remoteQuery = scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + const queryObject = remoteQueryObjectFromString({ + entryPoint: "cart", + variables: { filters: { id } }, + fields, + }) + + const [cart] = await remoteQuery(queryObject) + + return cart +} diff --git a/packages/medusa/src/api-v2/store/carts/middlewares.ts b/packages/medusa/src/api-v2/store/carts/middlewares.ts index 51f1407e09..5e9fd36c34 100644 --- a/packages/medusa/src/api-v2/store/carts/middlewares.ts +++ b/packages/medusa/src/api-v2/store/carts/middlewares.ts @@ -1,15 +1,17 @@ -import { transformBody, transformQuery } from "../../../api/middlewares" import { MiddlewareRoute } from "../../../loaders/helpers/routing/types" import { authenticate } from "../../../utils/authenticate-middleware" -import { StorePostCartsCartLineItemsItemReq } from "./[id]/line-items/[line_id]/validators" -import { StorePostCartsCartLineItemsReq } from "./[id]/line-items/validators" +import { validateAndTransformBody } from "../../utils/validate-body" +import { validateAndTransformQuery } from "../../utils/validate-query" import * as QueryConfig from "./query-config" import { - StoreDeleteCartsCartPromotionsReq, - StoreGetCartsCartParams, - StorePostCartReq, - StorePostCartsCartPromotionsReq, - StorePostCartsCartReq, + StoreAddCartLineItem, + StoreAddCartPromotions, + StoreCalculateCartTaxes, + StoreCreateCart, + StoreGetCartsCart, + StoreRemoveCartPromotions, + StoreUpdateCart, + StoreUpdateCartLineItem, } from "./validators" export const storeCartRoutesMiddlewares: MiddlewareRoute[] = [ @@ -26,8 +28,8 @@ export const storeCartRoutesMiddlewares: MiddlewareRoute[] = [ method: ["GET"], matcher: "/store/carts/:id", middlewares: [ - transformQuery( - StoreGetCartsCartParams, + validateAndTransformQuery( + StoreGetCartsCart, QueryConfig.retrieveTransformQueryConfig ), ], @@ -35,34 +37,99 @@ export const storeCartRoutesMiddlewares: MiddlewareRoute[] = [ { method: ["POST"], matcher: "/store/carts", - middlewares: [transformBody(StorePostCartReq)], + middlewares: [ + validateAndTransformBody(StoreCreateCart), + validateAndTransformQuery( + StoreGetCartsCart, + QueryConfig.retrieveTransformQueryConfig + ), + ], }, { method: ["POST"], matcher: "/store/carts/:id", - middlewares: [transformBody(StorePostCartsCartReq)], + middlewares: [ + validateAndTransformBody(StoreUpdateCart), + validateAndTransformQuery( + StoreGetCartsCart, + QueryConfig.retrieveTransformQueryConfig + ), + ], }, { method: ["POST"], matcher: "/store/carts/:id/line-items", - middlewares: [transformBody(StorePostCartsCartLineItemsReq)], + middlewares: [ + validateAndTransformBody(StoreAddCartLineItem), + validateAndTransformQuery( + StoreGetCartsCart, + QueryConfig.retrieveTransformQueryConfig + ), + ], }, { method: ["POST"], matcher: "/store/carts/:id/line-items/:line_id", - middlewares: [transformBody(StorePostCartsCartLineItemsItemReq)], + middlewares: [ + validateAndTransformBody(StoreUpdateCartLineItem), + validateAndTransformQuery( + StoreGetCartsCart, + QueryConfig.retrieveTransformQueryConfig + ), + ], }, { method: ["DELETE"], matcher: "/store/carts/:id/line-items/:line_id", + middlewares: [ + validateAndTransformQuery( + StoreGetCartsCart, + QueryConfig.retrieveTransformQueryConfig + ), + ], }, { + method: ["POST"], matcher: "/store/carts/:id/promotions", - middlewares: [transformBody(StorePostCartsCartPromotionsReq)], + middlewares: [ + validateAndTransformBody(StoreAddCartPromotions), + validateAndTransformQuery( + StoreGetCartsCart, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["POST"], + matcher: "/store/carts/:id/taxes", + middlewares: [ + validateAndTransformBody(StoreCalculateCartTaxes), + validateAndTransformQuery( + StoreGetCartsCart, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["POST"], + matcher: "/store/carts/:id/payment-collections", + middlewares: [ + validateAndTransformBody(StoreUpdateCart), + validateAndTransformQuery( + StoreGetCartsCart, + QueryConfig.retrieveTransformQueryConfig + ), + ], }, { method: ["DELETE"], matcher: "/store/carts/:id/promotions", - middlewares: [transformBody(StoreDeleteCartsCartPromotionsReq)], + middlewares: [ + validateAndTransformBody(StoreRemoveCartPromotions), + validateAndTransformQuery( + StoreGetCartsCart, + QueryConfig.retrieveTransformQueryConfig + ), + ], }, ] diff --git a/packages/medusa/src/api-v2/store/carts/route.ts b/packages/medusa/src/api-v2/store/carts/route.ts index faeb52a5d6..6a54471e1a 100644 --- a/packages/medusa/src/api-v2/store/carts/route.ts +++ b/packages/medusa/src/api-v2/store/carts/route.ts @@ -1,12 +1,10 @@ import { createCartWorkflow } from "@medusajs/core-flows" -import { LinkModuleUtils, Modules } from "@medusajs/modules-sdk" import { CreateCartWorkflowInputDTO } from "@medusajs/types" -import { remoteQueryObjectFromString } from "@medusajs/utils" import { AuthenticatedMedusaRequest, MedusaResponse, } from "../../../types/routing" -import { defaultStoreCartFields } from "../carts/query-config" +import { refetchCart } from "./helpers" export const POST = async ( req: AuthenticatedMedusaRequest, @@ -26,13 +24,11 @@ export const POST = async ( throw errors[0].error } - const remoteQuery = req.scope.resolve(LinkModuleUtils.REMOTE_QUERY) - const query = remoteQueryObjectFromString({ - entryPoint: Modules.CART, - fields: defaultStoreCartFields, - }) - - const [cart] = await remoteQuery(query, { cart: { id: result.id } }) + const cart = await refetchCart( + result.id, + req.scope, + req.remoteQueryConfig.fields + ) res.status(200).json({ cart }) } diff --git a/packages/medusa/src/api-v2/store/carts/validators.ts b/packages/medusa/src/api-v2/store/carts/validators.ts index 2cdfc9def5..9d273a7d29 100644 --- a/packages/medusa/src/api-v2/store/carts/validators.ts +++ b/packages/medusa/src/api-v2/store/carts/validators.ts @@ -1,118 +1,74 @@ -import { Type } from "class-transformer" -import { - IsArray, - IsEmail, - IsInt, - IsNotEmpty, - IsObject, - IsOptional, - IsString, - ValidateNested, -} from "class-validator" -import { AddressPayload, FindParams } from "../../../types/common" -import { IsType } from "../../../utils" +import { z } from "zod" +import { AddressPayload } from "../../utils/common-validators" +import { createSelectParams } from "../../utils/validators" -export class StoreGetCartsCartParams extends FindParams {} +export type StoreGetPromotionType = z.infer +export const StoreGetCartsCart = createSelectParams() -export class Item { - @IsNotEmpty() - @IsString() - variant_id: string +const ItemSchema = z.object({ + variant_id: z.string(), + quantity: z.number(), +}) - @IsNotEmpty() - @IsInt() - quantity: number -} +export type StoreCreateCartType = z.infer +export const StoreCreateCart = z + .object({ + region_id: z.string().optional().nullable(), + shipping_address: z.union([AddressPayload, z.string()]).optional(), + billing_address: z.union([AddressPayload, z.string()]).optional(), + email: z.string().email().optional().nullable(), + currency_code: z.string().optional(), + items: z.array(ItemSchema).optional(), + sales_channel_id: z.string().optional().nullable(), + metadata: z.record(z.unknown()).optional().nullable(), + }) + .strict() -export class StorePostCartReq { - @IsOptional() - @IsString() - region_id?: string +export type StoreAddCartPromotionsType = z.infer +export const StoreAddCartPromotions = z + .object({ + promo_codes: z.array(z.string()), + }) + .strict() - @IsOptional() - @IsType([AddressPayload, String]) - shipping_address?: AddressPayload | string +export type StoreRemoveCartPromotionsType = z.infer< + typeof StoreRemoveCartPromotions +> +export const StoreRemoveCartPromotions = z + .object({ + promo_codes: z.array(z.string()), + }) + .strict() - @IsOptional() - @IsType([AddressPayload, String]) - billing_address?: AddressPayload | string +export type StoreUpdateCartType = z.infer +export const StoreUpdateCart = z + .object({ + region_id: z.string().optional().nullable(), + email: z.string().email().optional().nullable(), + billing_address: z.union([AddressPayload, z.string()]).optional(), + shipping_address: z.union([AddressPayload, z.string()]).optional(), + sales_channel_id: z.string().optional().nullable(), + metadata: z.record(z.unknown()).optional().nullable(), + promo_codes: z.array(z.string()).optional(), + }) + .strict() - @IsOptional() - @IsString() - email?: string +export type StoreCalculateCartTaxesType = z.infer< + typeof StoreCalculateCartTaxes +> +export const StoreCalculateCartTaxes = createSelectParams() - @IsOptional() - @IsString() - currency_code?: string +export type StoreAddCartLineItemType = z.infer +export const StoreAddCartLineItem = z.object({ + variant_id: z.string(), + quantity: z.number(), + metadata: z.record(z.unknown()).optional(), +}) - @IsOptional() - @IsArray() - @ValidateNested({ each: true }) - @Type(() => Item) - items?: Item[] - - @IsString() - @IsOptional() - sales_channel_id?: string - - @IsObject() - @IsOptional() - metadata?: Record -} - -export class StorePostCartsCartPromotionsReq { - @IsArray() - @Type(() => String) - promo_codes: string[] -} - -export class StoreDeleteCartsCartPromotionsReq { - @IsArray() - @Type(() => String) - promo_codes: string[] -} - -export class StorePostCartsCartReq { - @IsOptional() - @IsString() - region_id?: string - - @IsEmail() - @IsOptional() - email?: string - - @IsOptional() - @IsType([AddressPayload, String]) - billing_address?: AddressPayload | string - - @IsOptional() - @IsType([AddressPayload, String]) - shipping_address?: AddressPayload | string - - @IsOptional() - @IsString() - sales_channel_id?: string - - @IsObject() - @IsOptional() - metadata?: Record - - @IsOptional() - @IsArray() - @Type(() => String) - promo_codes?: string[] - - // @IsOptional() - // @IsArray() - // @ValidateNested({ each: true }) - // @Type(() => GiftCard) - // gift_cards?: GiftCard[] - - // @IsOptional() - // @IsArray() - // @ValidateNested({ each: true }) - // @Type(() => Discount) - // discounts?: Discount[] -} - -export class StorePostCartsCartTaxesReq {} +export type StoreUpdateCartLineItemType = z.infer< + typeof StoreUpdateCartLineItem +> +export const StoreUpdateCartLineItem = z.object({ + quantity: z.number(), + metadata: z.record(z.unknown()).optional(), +})