diff --git a/integration-tests/plugins/__tests__/cart/store/get-cart.ts b/integration-tests/plugins/__tests__/cart/store/get-cart.ts new file mode 100644 index 0000000000..0ce5e7870e --- /dev/null +++ b/integration-tests/plugins/__tests__/cart/store/get-cart.ts @@ -0,0 +1,71 @@ +import { ModuleRegistrationName } from "@medusajs/modules-sdk" +import { ICartModuleService } from "@medusajs/types" +import path from "path" +import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app" +import { useApi } from "../../../../environment-helpers/use-api" +import { getContainer } from "../../../../environment-helpers/use-container" +import { initDb, useDb } from "../../../../environment-helpers/use-db" +import adminSeeder from "../../../../helpers/admin-seeder" + +const env = { MEDUSA_FF_MEDUSA_V2: true } + +describe("GET /store/:id", () => { + let dbConnection + let appContainer + let shutdownServer + let cartModuleService: ICartModuleService + + beforeAll(async () => { + const cwd = path.resolve(path.join(__dirname, "..", "..", "..")) + dbConnection = await initDb({ cwd, env } as any) + shutdownServer = await startBootstrapApp({ cwd, env }) + appContainer = getContainer() + cartModuleService = appContainer.resolve(ModuleRegistrationName.CART) + }) + + afterAll(async () => { + const db = useDb() + await db.shutdown() + await shutdownServer() + }) + + beforeEach(async () => { + await adminSeeder(dbConnection) + }) + + afterEach(async () => { + const db = useDb() + await db.teardown() + }) + + it("should get cart", async () => { + const cart = await cartModuleService.create({ + currency_code: "usd", + items: [ + { + unit_price: 1000, + quantity: 1, + title: "Test item", + }, + ], + }) + + const api = useApi() as any + const response = await api.get(`/store/carts/${cart.id}`) + + expect(response.status).toEqual(200) + expect(response.data.cart).toEqual( + expect.objectContaining({ + id: cart.id, + currency_code: "usd", + items: expect.arrayContaining([ + expect.objectContaining({ + unit_price: 1000, + quantity: 1, + title: "Test item", + }), + ]), + }) + ) + }) +}) diff --git a/integration-tests/plugins/medusa-config.js b/integration-tests/plugins/medusa-config.js index 2088ea4544..41dffcbef9 100644 --- a/integration-tests/plugins/medusa-config.js +++ b/integration-tests/plugins/medusa-config.js @@ -81,5 +81,10 @@ module.exports = { resources: "shared", resolve: "@medusajs/sales-channel", }, + [Modules.CART]: { + scope: "internal", + resources: "shared", + resolve: "@medusajs/cart", + }, }, } diff --git a/packages/cart/src/migrations/CartModuleSetup20240122122952.ts b/packages/cart/src/migrations/CartModuleSetup20240122122952.ts index a81894789b..cea797ef68 100644 --- a/packages/cart/src/migrations/CartModuleSetup20240122122952.ts +++ b/packages/cart/src/migrations/CartModuleSetup20240122122952.ts @@ -21,6 +21,8 @@ export class CartModuleSetup20240122122952 extends Migration { ); ALTER TABLE "cart" ADD COLUMN IF NOT EXISTS "currency_code" TEXT NOT NULL; + ALTER TABLE "cart" ALTER COLUMN "region_id" DROP NOT NULL; + ALTER TABLE "cart" ALTER COLUMN "email" DROP NOT NULL; ALTER TABLE "cart" DROP CONSTRAINT IF EXISTS "FK_242205c81c1152fab1b6e848470"; ALTER TABLE "cart" DROP CONSTRAINT IF EXISTS "FK_484c329f4783be4e18e5e2ff090"; diff --git a/packages/medusa/src/api-v2/middlewares.ts b/packages/medusa/src/api-v2/middlewares.ts index 59b5884fed..34fabd658f 100644 --- a/packages/medusa/src/api-v2/middlewares.ts +++ b/packages/medusa/src/api-v2/middlewares.ts @@ -1,8 +1,9 @@ import { MiddlewaresConfig } from "../loaders/helpers/routing/types" import { adminCampaignRoutesMiddlewares } from "./admin/campaigns/middlewares" -import { adminPromotionRoutesMiddlewares } from "./admin/promotions/middlewares" -import { adminCustomerRoutesMiddlewares } from "./admin/customers/middlewares" import { adminCustomerGroupRoutesMiddlewares } from "./admin/customer-groups/middlewares" +import { adminCustomerRoutesMiddlewares } from "./admin/customers/middlewares" +import { adminPromotionRoutesMiddlewares } from "./admin/promotions/middlewares" +import { storeCartRoutesMiddlewares } from "./store/carts/middlewares" export const config: MiddlewaresConfig = { routes: [ @@ -10,5 +11,6 @@ export const config: MiddlewaresConfig = { ...adminCustomerRoutesMiddlewares, ...adminPromotionRoutesMiddlewares, ...adminCampaignRoutesMiddlewares, + ...storeCartRoutesMiddlewares, ], } diff --git a/packages/medusa/src/api-v2/store/carts/[id]/route.ts b/packages/medusa/src/api-v2/store/carts/[id]/route.ts new file mode 100644 index 0000000000..e0bbedacf8 --- /dev/null +++ b/packages/medusa/src/api-v2/store/carts/[id]/route.ts @@ -0,0 +1,30 @@ +import { ModuleRegistrationName } from "@medusajs/modules-sdk" +import { ICartModuleService } from "@medusajs/types" +import { MedusaRequest, MedusaResponse } from "../../../../types/routing" + +export const GET = async (req: MedusaRequest, res: MedusaResponse) => { + const cartModuleService: ICartModuleService = req.scope.resolve( + ModuleRegistrationName.CART + ) + + // TODO: Replace with remoteQuery + const cart = await cartModuleService.retrieve(req.params.id, { + select: req.retrieveConfig.select, + relations: req.retrieveConfig.relations, + }) + + // const remoteQuery = req.scope.resolve("remoteQuery") + + // const variables = { id: req.params.id } + + // const query = { + // cart: { + // __args: variables, + // ...defaultStoreCartRemoteQueryObject, + // }, + // } + + // const [cart] = await remoteQuery(query) + + res.json({ cart }) +} diff --git a/packages/medusa/src/api-v2/store/carts/middlewares.ts b/packages/medusa/src/api-v2/store/carts/middlewares.ts new file mode 100644 index 0000000000..2147701191 --- /dev/null +++ b/packages/medusa/src/api-v2/store/carts/middlewares.ts @@ -0,0 +1,17 @@ +import { transformQuery } from "../../../api/middlewares" +import { MiddlewareRoute } from "../../../loaders/helpers/routing/types" +import * as QueryConfig from "./query-config" +import { StoreGetCartsCartParams } from "./validators" + +export const storeCartRoutesMiddlewares: MiddlewareRoute[] = [ + { + method: ["GET"], + matcher: "/store/carts/:id", + middlewares: [ + transformQuery( + StoreGetCartsCartParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, +] diff --git a/packages/medusa/src/api-v2/store/carts/query-config.ts b/packages/medusa/src/api-v2/store/carts/query-config.ts new file mode 100644 index 0000000000..a77526002a --- /dev/null +++ b/packages/medusa/src/api-v2/store/carts/query-config.ts @@ -0,0 +1,64 @@ +export const defaultStoreCartFields = [ + "id", + "currency_code", + "email", + "created_at", + "updated_at", + "deleted_at", +] + +export const defaultStoreCartRelations = [ + "items", + "shipping_address", + "billing_address", + "shipping_methods", +] + +export const retrieveTransformQueryConfig = { + defaultFields: defaultStoreCartFields, + defaultRelations: defaultStoreCartRelations, + isList: false, +} + +export const defaultStoreCartRemoteQueryObject = { + fields: defaultStoreCartFields, + line_items: { + fields: [ + "id", + "created_at", + "updated_at", + "deleted_at", + "title", + "quantity", + "unit_price", + ], + }, + shipping_address: { + fields: [ + "id", + "first_name", + "last_name", + "address_1", + "address_2", + "city", + "postal_code", + "country_code", + "region_code", + "phone", + ], + }, + billing_address: { + fields: [ + "id", + "first_name", + "last_name", + "address_1", + "address_2", + "city", + "postal_code", + "country_code", + "region_code", + "phone", + ], + }, +} diff --git a/packages/medusa/src/api-v2/store/carts/validators.ts b/packages/medusa/src/api-v2/store/carts/validators.ts new file mode 100644 index 0000000000..3dff03e7e8 --- /dev/null +++ b/packages/medusa/src/api-v2/store/carts/validators.ts @@ -0,0 +1,3 @@ +import { FindParams } from "../../../types/common" + +export class StoreGetCartsCartParams extends FindParams {} diff --git a/packages/medusa/src/joiner-configs/cart-service.ts b/packages/medusa/src/joiner-configs/cart-service.ts index 878cfe2cdd..f236208ebf 100644 --- a/packages/medusa/src/joiner-configs/cart-service.ts +++ b/packages/medusa/src/joiner-configs/cart-service.ts @@ -4,7 +4,7 @@ import { ModuleJoinerConfig } from "@medusajs/types" import { Cart } from "../models" export default { - serviceName: Modules.CART, + serviceName: "cartService", primaryKeys: ["id"], linkableKeys: { cart_id: "Cart" }, alias: { diff --git a/packages/medusa/src/joiner-configs/index.ts b/packages/medusa/src/joiner-configs/index.ts index fb21643b5d..4fccd04161 100644 --- a/packages/medusa/src/joiner-configs/index.ts +++ b/packages/medusa/src/joiner-configs/index.ts @@ -1,5 +1,6 @@ export * as cart from "./cart-service" export * as customer from "./customer-service" +export * as publishableApiKey from "./publishable-api-key-service" export * as region from "./region-service" export * as shippingProfile from "./shipping-profile-service" -export * as publishableApiKey from "./publishable-api-key-service" +