From ccb50bb3da8b3ce4b42ecb143d921bd156de7ac3 Mon Sep 17 00:00:00 2001 From: Stevche Radevski Date: Thu, 18 Apr 2024 10:30:45 +0200 Subject: [PATCH] fix: Switch to zod for customer endpoints, fix inconsistencies (#7094) --- .../admin/batch-add-customers.ts | 6 +- .../admin/batch-remove-customers.ts | 6 +- .../admin/list-customer-group-customers.ts | 4 +- .../admin/create-customer-addresses.ts | 18 +- .../admin/update-customer-address.spec.ts | 16 +- packages/customer/src/joiner-config.ts | 10 +- .../customer/src/services/customer-module.ts | 13 +- .../[id]/customers/batch/add/route.ts | 48 ---- .../[id]/customers/batch/remove/route.ts | 48 ---- .../[id]/customers/batch/route.ts | 66 +++++ .../customer-groups/[id]/customers/route.ts | 32 --- .../admin/customer-groups/[id]/route.ts | 30 +-- .../api-v2/admin/customer-groups/helpers.ts | 23 ++ .../admin/customer-groups/middlewares.ts | 89 +++---- .../admin/customer-groups/query-config.ts | 7 +- .../src/api-v2/admin/customer-groups/route.ts | 47 ++-- .../admin/customer-groups/validators.ts | 240 +++++------------- .../[id]/addresses/[address_id]/route.ts | 46 ++-- .../admin/customers/[id]/addresses/route.ts | 46 ++-- .../src/api-v2/admin/customers/[id]/route.ts | 49 ++-- .../src/api-v2/admin/customers/helpers.ts | 23 ++ .../src/api-v2/admin/customers/middlewares.ts | 34 ++- .../api-v2/admin/customers/query-config.ts | 13 +- .../src/api-v2/admin/customers/route.ts | 26 +- .../src/api-v2/admin/customers/validators.ts | 13 +- 25 files changed, 432 insertions(+), 521 deletions(-) delete mode 100644 packages/medusa/src/api-v2/admin/customer-groups/[id]/customers/batch/add/route.ts delete mode 100644 packages/medusa/src/api-v2/admin/customer-groups/[id]/customers/batch/remove/route.ts create mode 100644 packages/medusa/src/api-v2/admin/customer-groups/[id]/customers/batch/route.ts delete mode 100644 packages/medusa/src/api-v2/admin/customer-groups/[id]/customers/route.ts create mode 100644 packages/medusa/src/api-v2/admin/customer-groups/helpers.ts create mode 100644 packages/medusa/src/api-v2/admin/customers/helpers.ts diff --git a/integration-tests/modules/__tests__/customer-group/admin/batch-add-customers.ts b/integration-tests/modules/__tests__/customer-group/admin/batch-add-customers.ts index a1cc138e84..054bb6cf7b 100644 --- a/integration-tests/modules/__tests__/customer-group/admin/batch-add-customers.ts +++ b/integration-tests/modules/__tests__/customer-group/admin/batch-add-customers.ts @@ -13,7 +13,7 @@ const adminHeaders = { medusaIntegrationTestRunner({ env, testSuite: ({ dbConnection, getContainer, api }) => { - describe("POST /admin/customer-groups/:id/customers/batch/add", () => { + describe("POST /admin/customer-groups/:id/customers/batch", () => { let appContainer let customerModuleService: ICustomerModuleService @@ -48,9 +48,9 @@ medusaIntegrationTestRunner({ ]) const response = await api.post( - `/admin/customer-groups/${group.id}/customers/batch/add`, + `/admin/customer-groups/${group.id}/customers/batch`, { - customer_ids: customers.map((c) => ({ id: c.id })), + create: customers.map((c) => c.id), }, adminHeaders ) diff --git a/integration-tests/modules/__tests__/customer-group/admin/batch-remove-customers.ts b/integration-tests/modules/__tests__/customer-group/admin/batch-remove-customers.ts index 86627978d2..33a905151e 100644 --- a/integration-tests/modules/__tests__/customer-group/admin/batch-remove-customers.ts +++ b/integration-tests/modules/__tests__/customer-group/admin/batch-remove-customers.ts @@ -13,7 +13,7 @@ const adminHeaders = { medusaIntegrationTestRunner({ env, testSuite: ({ dbConnection, getContainer, api }) => { - describe("POST /admin/customer-groups/:id/customers/batch/remove", () => { + describe("POST /admin/customer-groups/:id/customers/batch", () => { let appContainer let customerModuleService: ICustomerModuleService @@ -55,9 +55,9 @@ medusaIntegrationTestRunner({ ) const response = await api.post( - `/admin/customer-groups/${group.id}/customers/batch/remove`, + `/admin/customer-groups/${group.id}/customers/batch`, { - customer_ids: customers.map((c) => ({ id: c.id })), + delete: customers.map((c) => c.id), }, adminHeaders ) diff --git a/integration-tests/modules/__tests__/customer-group/admin/list-customer-group-customers.ts b/integration-tests/modules/__tests__/customer-group/admin/list-customer-group-customers.ts index 87a953dd40..62913b9c27 100644 --- a/integration-tests/modules/__tests__/customer-group/admin/list-customer-group-customers.ts +++ b/integration-tests/modules/__tests__/customer-group/admin/list-customer-group-customers.ts @@ -13,7 +13,7 @@ const adminHeaders = { medusaIntegrationTestRunner({ env, testSuite: ({ dbConnection, getContainer, api }) => { - describe("GET /admin/customer-groups/:id/customers", () => { + describe("GET customer group customers", () => { let appContainer let customerModuleService: ICustomerModuleService @@ -54,7 +54,7 @@ medusaIntegrationTestRunner({ ) const response = await api.get( - `/admin/customer-groups/${group.id}/customers`, + `/admin/customers?groups[]=${group.id}`, adminHeaders ) diff --git a/integration-tests/modules/__tests__/customer/admin/create-customer-addresses.ts b/integration-tests/modules/__tests__/customer/admin/create-customer-addresses.ts index e8f5609908..591ab3647a 100644 --- a/integration-tests/modules/__tests__/customer/admin/create-customer-addresses.ts +++ b/integration-tests/modules/__tests__/customer/admin/create-customer-addresses.ts @@ -35,7 +35,7 @@ medusaIntegrationTestRunner({ }) const response = await api.post( - `/admin/customers/${customer.id}/addresses`, + `/admin/customers/${customer.id}/addresses?fields=*addresses`, { first_name: "John", last_name: "Doe", @@ -45,13 +45,15 @@ medusaIntegrationTestRunner({ ) expect(response.status).toEqual(200) - expect(response.data.address).toEqual( - expect.objectContaining({ - id: expect.any(String), - first_name: "John", - last_name: "Doe", - address_1: "Test street 1", - }) + expect(response.data.customer.addresses).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: expect.any(String), + first_name: "John", + last_name: "Doe", + address_1: "Test street 1", + }), + ]) ) const customerWithAddresses = await customerModuleService.retrieve( diff --git a/integration-tests/modules/__tests__/customer/admin/update-customer-address.spec.ts b/integration-tests/modules/__tests__/customer/admin/update-customer-address.spec.ts index 817b0d06be..db47eac959 100644 --- a/integration-tests/modules/__tests__/customer/admin/update-customer-address.spec.ts +++ b/integration-tests/modules/__tests__/customer/admin/update-customer-address.spec.ts @@ -42,7 +42,7 @@ medusaIntegrationTestRunner({ }) const response = await api.post( - `/admin/customers/${customer.id}/addresses/${address.id}`, + `/admin/customers/${customer.id}/addresses/${address.id}?fields=*addresses`, { first_name: "Jane", }, @@ -50,12 +50,14 @@ medusaIntegrationTestRunner({ ) expect(response.status).toEqual(200) - expect(response.data.address).toEqual( - expect.objectContaining({ - id: expect.any(String), - first_name: "Jane", - last_name: "Doe", - }) + expect(response.data.customer.addresses).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: expect.any(String), + first_name: "Jane", + last_name: "Doe", + }), + ]) ) }) diff --git a/packages/customer/src/joiner-config.ts b/packages/customer/src/joiner-config.ts index 5e6df67bd9..c6c3cfb52d 100644 --- a/packages/customer/src/joiner-config.ts +++ b/packages/customer/src/joiner-config.ts @@ -1,11 +1,12 @@ import { Modules } from "@medusajs/modules-sdk" import { ModuleJoinerConfig } from "@medusajs/types" import { MapToConfig } from "@medusajs/utils" -import { Customer, CustomerGroup } from "@models" +import { Address, Customer, CustomerGroup } from "@models" export const LinkableKeys = { customer_id: Customer.name, customer_group_id: CustomerGroup.name, + customer_address_id: Address.name, } const entityLinkableKeysMap: MapToConfig = {} @@ -37,5 +38,12 @@ export const joinerConfig: ModuleJoinerConfig = { methodSuffix: "CustomerGroups", }, }, + { + name: ["customer_address", "customer_addresses"], + args: { + entity: Address.name, + methodSuffix: "Addresses", + }, + }, ], } diff --git a/packages/customer/src/services/customer-module.ts b/packages/customer/src/services/customer-module.ts index 523d63e4f3..90d4d01ab7 100644 --- a/packages/customer/src/services/customer-module.ts +++ b/packages/customer/src/services/customer-module.ts @@ -12,10 +12,8 @@ import { import { InjectManager, InjectTransactionManager, - isDuplicateError, isString, MedusaContext, - MedusaError, ModulesSdkUtils, } from "@medusajs/utils" import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config" @@ -26,10 +24,6 @@ import { CustomerGroupCustomer, } from "@models" import { EntityManager } from "@mikro-orm/core" -import { - UNIQUE_CUSTOMER_BILLING_ADDRESS, - UNIQUE_CUSTOMER_SHIPPING_ADDRESS, -} from "../models/address" type InjectedDependencies = { baseRepository: DAL.RepositoryService @@ -39,7 +33,11 @@ type InjectedDependencies = { customerGroupCustomerService: ModulesSdkTypes.InternalModuleService } -const generateMethodForModels = [Address, CustomerGroup, CustomerGroupCustomer] +const generateMethodForModels = [ + { model: Address, singular: "Address", plural: "Addresses" }, + CustomerGroup, + CustomerGroupCustomer, +] export default class CustomerModuleService< TAddress extends Address = Address, @@ -47,7 +45,6 @@ export default class CustomerModuleService< TCustomerGroup extends CustomerGroup = CustomerGroup, TCustomerGroupCustomer extends CustomerGroupCustomer = CustomerGroupCustomer > - // TODO seb I let you manage that when you are moving forward extends ModulesSdkUtils.abstractModuleServiceFactory< InjectedDependencies, CustomerDTO, diff --git a/packages/medusa/src/api-v2/admin/customer-groups/[id]/customers/batch/add/route.ts b/packages/medusa/src/api-v2/admin/customer-groups/[id]/customers/batch/add/route.ts deleted file mode 100644 index 8f85a35c41..0000000000 --- a/packages/medusa/src/api-v2/admin/customer-groups/[id]/customers/batch/add/route.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { createCustomerGroupCustomersWorkflow } from "@medusajs/core-flows" -import { AdminCustomerGroupResponse } from "@medusajs/types" -import { - ContainerRegistrationKeys, - remoteQueryObjectFromString, -} from "@medusajs/utils" -import { - AuthenticatedMedusaRequest, - MedusaResponse, -} from "../../../../../../../types/routing" -import { AdminPostCustomerGroupsGroupCustomersBatchReq } from "../../../../validators" - -export const POST = async ( - // eslint-disable-next-line max-len - req: AuthenticatedMedusaRequest, - res: MedusaResponse -) => { - const { id } = req.params - const { customer_ids } = req.validatedBody - - const createCustomers = createCustomerGroupCustomersWorkflow(req.scope) - - const { result, errors } = await createCustomers.run({ - input: { - groupCustomers: customer_ids.map((c) => ({ - customer_id: c.id, - customer_group_id: id, - })), - }, - throwOnError: false, - }) - - if (Array.isArray(errors) && errors[0]) { - throw errors[0].error - } - - const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) - - const queryObject = remoteQueryObjectFromString({ - entryPoint: "customer_group", - variables: { id }, - fields: req.remoteQueryConfig.fields, - }) - - const [customer_group] = await remoteQuery(queryObject) - - res.status(200).json({ customer_group }) -} diff --git a/packages/medusa/src/api-v2/admin/customer-groups/[id]/customers/batch/remove/route.ts b/packages/medusa/src/api-v2/admin/customer-groups/[id]/customers/batch/remove/route.ts deleted file mode 100644 index c2e924ca9b..0000000000 --- a/packages/medusa/src/api-v2/admin/customer-groups/[id]/customers/batch/remove/route.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { deleteCustomerGroupCustomersWorkflow } from "@medusajs/core-flows" -import { AdminCustomerGroupResponse } from "@medusajs/types" -import { - ContainerRegistrationKeys, - remoteQueryObjectFromString, -} from "@medusajs/utils" -import { - AuthenticatedMedusaRequest, - MedusaResponse, -} from "../../../../../../../types/routing" -import { AdminPostCustomerGroupsGroupCustomersBatchReq } from "../../../../validators" - -export const POST = async ( - // eslint-disable-next-line max-len - req: AuthenticatedMedusaRequest, - res: MedusaResponse -) => { - const { id } = req.params - const { customer_ids } = req.validatedBody - - const deleteCustomers = deleteCustomerGroupCustomersWorkflow(req.scope) - - const { errors } = await deleteCustomers.run({ - input: { - groupCustomers: customer_ids.map((c) => ({ - customer_id: c.id, - customer_group_id: id, - })), - }, - throwOnError: false, - }) - - if (Array.isArray(errors) && errors[0]) { - throw errors[0].error - } - - const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) - - const queryObject = remoteQueryObjectFromString({ - entryPoint: "customer_group", - variables: { id }, - fields: req.remoteQueryConfig.fields, - }) - - const [customer_group] = await remoteQuery(queryObject) - - res.status(200).json({ customer_group }) -} diff --git a/packages/medusa/src/api-v2/admin/customer-groups/[id]/customers/batch/route.ts b/packages/medusa/src/api-v2/admin/customer-groups/[id]/customers/batch/route.ts new file mode 100644 index 0000000000..412531b1f7 --- /dev/null +++ b/packages/medusa/src/api-v2/admin/customer-groups/[id]/customers/batch/route.ts @@ -0,0 +1,66 @@ +import { AdminCustomerGroupResponse, BatchMethodRequest } from "@medusajs/types" +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../../types/routing" +import { AdminSetCustomersCustomerGroupType } from "../../../validators" +import { + createCustomerGroupCustomersWorkflow, + deleteCustomerGroupCustomersWorkflow, +} from "@medusajs/core-flows" +import { refetchCustomerGroup } from "../../../helpers" + +export const POST = async ( + req: AuthenticatedMedusaRequest< + BatchMethodRequest< + AdminSetCustomersCustomerGroupType, + AdminSetCustomersCustomerGroupType + > + >, + res: MedusaResponse +) => { + const { id } = req.params + const { create, delete: toDelete } = req.validatedBody + + if (!!create && create?.length > 0) { + const createCustomers = createCustomerGroupCustomersWorkflow(req.scope) + const { errors } = await createCustomers.run({ + input: { + groupCustomers: create.map((c) => ({ + customer_id: c, + customer_group_id: id, + })), + }, + throwOnError: false, + }) + + if (Array.isArray(errors) && errors[0]) { + throw errors[0].error + } + } + + if (!!toDelete && toDelete?.length > 0) { + const deleteCustomers = deleteCustomerGroupCustomersWorkflow(req.scope) + const { errors } = await deleteCustomers.run({ + input: { + groupCustomers: toDelete.map((c) => ({ + customer_id: c, + customer_group_id: id, + })), + }, + throwOnError: false, + }) + + if (Array.isArray(errors) && errors[0]) { + throw errors[0].error + } + } + + const customerGroup = await refetchCustomerGroup( + id, + req.scope, + req.remoteQueryConfig.fields + ) + + res.status(200).json({ customer_group: customerGroup }) +} diff --git a/packages/medusa/src/api-v2/admin/customer-groups/[id]/customers/route.ts b/packages/medusa/src/api-v2/admin/customer-groups/[id]/customers/route.ts deleted file mode 100644 index a8acc23b56..0000000000 --- a/packages/medusa/src/api-v2/admin/customer-groups/[id]/customers/route.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { - AuthenticatedMedusaRequest, - MedusaResponse, -} from "../../../../../types/routing" - -import { ICustomerModuleService } from "@medusajs/types" -import { ModuleRegistrationName } from "@medusajs/modules-sdk" - -export const GET = async ( - req: AuthenticatedMedusaRequest, - res: MedusaResponse -) => { - const { id } = req.params - - const service = req.scope.resolve( - ModuleRegistrationName.CUSTOMER - ) - - const [customers, count] = await service.listAndCount( - { ...req.filterableFields, groups: id }, - req.listConfig - ) - - const { offset, limit } = req.validatedQuery - - res.json({ - count, - customers, - offset, - limit, - }) -} diff --git a/packages/medusa/src/api-v2/admin/customer-groups/[id]/route.ts b/packages/medusa/src/api-v2/admin/customer-groups/[id]/route.ts index 8d49c21168..41bf74cf94 100644 --- a/packages/medusa/src/api-v2/admin/customer-groups/[id]/route.ts +++ b/packages/medusa/src/api-v2/admin/customer-groups/[id]/route.ts @@ -2,38 +2,29 @@ import { AuthenticatedMedusaRequest, MedusaResponse, } from "../../../../types/routing" -import { - CustomerGroupUpdatableFields, - ICustomerModuleService, -} from "@medusajs/types" import { deleteCustomerGroupsWorkflow, updateCustomerGroupsWorkflow, } from "@medusajs/core-flows" -import { ModuleRegistrationName } from "@medusajs/modules-sdk" +import { refetchCustomerGroup } from "../helpers" +import { AdminUpdateCustomerGroupType } from "../validators" export const GET = async ( req: AuthenticatedMedusaRequest, res: MedusaResponse ) => { - const customerModuleService = req.scope.resolve( - ModuleRegistrationName.CUSTOMER - ) - - const group = await customerModuleService.retrieveCustomerGroup( + const customerGroup = await refetchCustomerGroup( req.params.id, - { - select: req.retrieveConfig.select, - relations: req.retrieveConfig.relations, - } + req.scope, + req.remoteQueryConfig.fields ) - res.status(200).json({ customer_group: group }) + res.status(200).json({ customer_group: customerGroup }) } export const POST = async ( - req: AuthenticatedMedusaRequest, + req: AuthenticatedMedusaRequest, res: MedusaResponse ) => { const updateGroups = updateCustomerGroupsWorkflow(req.scope) @@ -49,7 +40,12 @@ export const POST = async ( throw errors[0].error } - res.status(200).json({ customer_group: result[0] }) + const customerGroup = await refetchCustomerGroup( + req.params.id, + req.scope, + req.remoteQueryConfig.fields + ) + res.status(200).json({ customer_group: customerGroup }) } export const DELETE = async ( diff --git a/packages/medusa/src/api-v2/admin/customer-groups/helpers.ts b/packages/medusa/src/api-v2/admin/customer-groups/helpers.ts new file mode 100644 index 0000000000..c54fd1d343 --- /dev/null +++ b/packages/medusa/src/api-v2/admin/customer-groups/helpers.ts @@ -0,0 +1,23 @@ +import { MedusaContainer } from "@medusajs/types" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" + +export const refetchCustomerGroup = async ( + customerGroupId: string, + scope: MedusaContainer, + fields: string[] +) => { + const remoteQuery = scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + const queryObject = remoteQueryObjectFromString({ + entryPoint: "customer_group", + variables: { + filters: { id: customerGroupId }, + }, + fields: fields, + }) + + const customerGroups = await remoteQuery(queryObject) + return customerGroups[0] +} diff --git a/packages/medusa/src/api-v2/admin/customer-groups/middlewares.ts b/packages/medusa/src/api-v2/admin/customer-groups/middlewares.ts index 9540ed8ad2..41dd01732f 100644 --- a/packages/medusa/src/api-v2/admin/customer-groups/middlewares.ts +++ b/packages/medusa/src/api-v2/admin/customer-groups/middlewares.ts @@ -1,42 +1,39 @@ import * as QueryConfig from "./query-config" - -import { transformBody, transformQuery } from "../../../api/middlewares" -import { - AdminDeleteCustomerGroupsGroupCustomersBatchReq, - AdminGetCustomerGroupsGroupCustomersParams, - AdminGetCustomerGroupsGroupParams, - AdminGetCustomerGroupsParams, - AdminPostCustomerGroupsGroupCustomersBatchReq, - AdminPostCustomerGroupsGroupReq, - AdminPostCustomerGroupsReq, -} from "./validators" - import { MiddlewareRoute } from "../../../loaders/helpers/routing/types" import { authenticate } from "../../../utils/authenticate-middleware" -import { listTransformQueryConfig as customersListTransformQueryConfig } from "../customers/query-config" +import { validateAndTransformQuery } from "../../utils/validate-query" +import { + AdminCreateCustomerGroup, + AdminGetCustomerGroupParams, + AdminGetCustomerGroupsParams, + AdminSetCustomersCustomerGroup, + AdminUpdateCustomerGroup, +} from "./validators" +import { validateAndTransformBody } from "../../utils/validate-body" +import { createBatchBody } from "../../utils/validators" export const adminCustomerGroupRoutesMiddlewares: MiddlewareRoute[] = [ + { + method: ["ALL"], + matcher: "/admin/customer-groups*", + middlewares: [authenticate("admin", ["bearer", "session", "api-key"])], + }, { method: ["GET"], matcher: "/admin/customer-groups", middlewares: [ - transformQuery( + validateAndTransformQuery( AdminGetCustomerGroupsParams, QueryConfig.listTransformQueryConfig ), ], }, - { - method: ["ALL"], - matcher: "/admin/customer-groups*", - middlewares: [authenticate("admin", ["bearer", "session"])], - }, { method: ["GET"], matcher: "/admin/customer-groups/:id", middlewares: [ - transformQuery( - AdminGetCustomerGroupsGroupParams, + validateAndTransformQuery( + AdminGetCustomerGroupParams, QueryConfig.retrieveTransformQueryConfig ), ], @@ -44,41 +41,37 @@ export const adminCustomerGroupRoutesMiddlewares: MiddlewareRoute[] = [ { method: ["POST"], matcher: "/admin/customer-groups", - middlewares: [transformBody(AdminPostCustomerGroupsReq)], - }, - { - method: ["POST"], - matcher: "/admin/customer-groups/:id", - middlewares: [transformBody(AdminPostCustomerGroupsGroupReq)], - }, - { - method: ["GET"], - matcher: "/admin/customer-groups/:id/customers", middlewares: [ - transformQuery( - AdminGetCustomerGroupsGroupCustomersParams, - customersListTransformQueryConfig - ), - ], - }, - { - method: ["POST"], - matcher: "/admin/customer-groups/:id/customers/batch/add", - middlewares: [ - transformBody(AdminPostCustomerGroupsGroupCustomersBatchReq), - transformQuery( - AdminGetCustomerGroupsGroupParams, + validateAndTransformBody(AdminCreateCustomerGroup), + validateAndTransformQuery( + AdminGetCustomerGroupParams, QueryConfig.retrieveTransformQueryConfig ), ], }, { method: ["POST"], - matcher: "/admin/customer-groups/:id/customers/batch/remove", + matcher: "/admin/customer-groups/:id", middlewares: [ - transformBody(AdminDeleteCustomerGroupsGroupCustomersBatchReq), - transformQuery( - AdminGetCustomerGroupsGroupParams, + validateAndTransformBody(AdminUpdateCustomerGroup), + validateAndTransformQuery( + AdminGetCustomerGroupParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["POST"], + matcher: "/admin/customer-groups/:id/customers/batch", + middlewares: [ + validateAndTransformBody( + createBatchBody( + AdminSetCustomersCustomerGroup, + AdminSetCustomersCustomerGroup + ) + ), + validateAndTransformQuery( + AdminGetCustomerGroupParams, QueryConfig.retrieveTransformQueryConfig ), ], diff --git a/packages/medusa/src/api-v2/admin/customer-groups/query-config.ts b/packages/medusa/src/api-v2/admin/customer-groups/query-config.ts index db9aac9698..dc78491cc9 100644 --- a/packages/medusa/src/api-v2/admin/customer-groups/query-config.ts +++ b/packages/medusa/src/api-v2/admin/customer-groups/query-config.ts @@ -1,17 +1,14 @@ -export const defaultAdminCustomerGroupRelations = [] -export const allowedAdminCustomerGroupRelations = ["customers"] export const defaultAdminCustomerGroupFields = [ "id", "name", + "created_by", "created_at", "updated_at", "deleted_at", ] export const retrieveTransformQueryConfig = { - defaultFields: defaultAdminCustomerGroupFields, - defaultRelations: defaultAdminCustomerGroupRelations, - allowedRelations: allowedAdminCustomerGroupRelations, + defaults: defaultAdminCustomerGroupFields, isList: false, } diff --git a/packages/medusa/src/api-v2/admin/customer-groups/route.ts b/packages/medusa/src/api-v2/admin/customer-groups/route.ts index c290e34d60..72f8e6cd87 100644 --- a/packages/medusa/src/api-v2/admin/customer-groups/route.ts +++ b/packages/medusa/src/api-v2/admin/customer-groups/route.ts @@ -1,39 +1,42 @@ import { AuthenticatedMedusaRequest, - MedusaRequest, MedusaResponse, } from "../../../types/routing" -import { CreateCustomerGroupDTO, ICustomerModuleService } from "@medusajs/types" - -import { ModuleRegistrationName } from "@medusajs/modules-sdk" import { createCustomerGroupsWorkflow } from "@medusajs/core-flows" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" +import { AdminCreateCustomerGroupType } from "./validators" +import { refetchCustomerGroup } from "./helpers" export const GET = async ( req: AuthenticatedMedusaRequest, res: MedusaResponse ) => { - const customerModuleService = req.scope.resolve( - ModuleRegistrationName.CUSTOMER - ) + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) - const [groups, count] = - await customerModuleService.listAndCountCustomerGroups( - req.filterableFields, - req.listConfig - ) + const query = remoteQueryObjectFromString({ + entryPoint: "customer_group", + variables: { + filters: req.filterableFields, + ...req.remoteQueryConfig.pagination, + }, + fields: req.remoteQueryConfig.fields, + }) - const { offset, limit } = req.validatedQuery + const { rows: customer_groups, metadata } = await remoteQuery(query) res.json({ - count, - customer_groups: groups, - offset, - limit, + customer_groups, + count: metadata.count, + offset: metadata.skip, + limit: metadata.take, }) } export const POST = async ( - req: AuthenticatedMedusaRequest, + req: AuthenticatedMedusaRequest, res: MedusaResponse ) => { const createGroups = createCustomerGroupsWorkflow(req.scope) @@ -53,5 +56,11 @@ export const POST = async ( throw errors[0].error } - res.status(200).json({ customer_group: result[0] }) + const customerGroup = await refetchCustomerGroup( + result[0].id, + req.scope, + req.remoteQueryConfig.fields + ) + + res.status(200).json({ customer_group: customerGroup }) } diff --git a/packages/medusa/src/api-v2/admin/customer-groups/validators.ts b/packages/medusa/src/api-v2/admin/customer-groups/validators.ts index 52eab3587d..c97ca9e34d 100644 --- a/packages/medusa/src/api-v2/admin/customer-groups/validators.ts +++ b/packages/medusa/src/api-v2/admin/customer-groups/validators.ts @@ -1,183 +1,73 @@ -import { FindParams, extendedFindParamsMixin } from "../../../types/common" import { - IsNotEmpty, - IsOptional, - IsString, - ValidateNested, -} from "class-validator" -import { Transform, Type } from "class-transformer" + createFindParams, + createOperatorMap, + createSelectParams, +} from "../../utils/validators" +import { z } from "zod" -import { IsType } from "../../../utils" -import { OperatorMap } from "@medusajs/types" -import { OperatorMapValidator } from "../../../types/validators/operator-map" +export type AdminGetCustomerGroupParamsType = z.infer< + typeof AdminGetCustomerGroupParams +> +export const AdminGetCustomerGroupParams = createSelectParams() -export class AdminGetCustomerGroupsGroupParams extends FindParams {} +export const AdminCustomerInGroupFilters = z.object({ + id: z.union([z.string(), z.array(z.string())]).optional(), + email: z + .union([z.string(), z.array(z.string()), createOperatorMap()]) + .optional(), + default_billing_address_id: z + .union([z.string(), z.array(z.string())]) + .optional(), + default_shipping_address_id: z + .union([z.string(), z.array(z.string())]) + .optional(), + company_name: z.union([z.string(), z.array(z.string())]).optional(), + first_name: z.union([z.string(), z.array(z.string())]).optional(), + last_name: z.union([z.string(), z.array(z.string())]).optional(), + created_by: z.union([z.string(), z.array(z.string())]).optional(), + created_at: createOperatorMap().optional(), + updated_at: createOperatorMap().optional(), + deleted_at: createOperatorMap().optional(), +}) -class FilterableCustomerPropsValidator { - @IsOptional() - @IsString({ each: true }) - id?: string | string[] - - @IsOptional() - @ValidateNested({ each: true }) - @Type(() => OperatorMapValidator) - email?: string | string[] | OperatorMap - - @IsOptional() - @IsString({ each: true }) - default_billing_address_id?: string | string[] | null - - @IsOptional() - @IsString({ each: true }) - default_shipping_address_id?: string | string[] | null - - @IsOptional() - @IsString({ each: true }) - company_name?: string | string[] | OperatorMap | null - - @IsOptional() - @IsString({ each: true }) - first_name?: string | string[] | OperatorMap | null - - @IsOptional() - @IsString({ each: true }) - last_name?: string | string[] | OperatorMap | null - - @IsOptional() - @IsString({ each: true }) - created_by?: string | string[] | null - - @IsOptional() - @ValidateNested() - @Type(() => OperatorMapValidator) - created_at?: OperatorMap - - @IsOptional() - @ValidateNested() - @Type(() => OperatorMapValidator) - updated_at?: OperatorMap -} - -export class AdminGetCustomerGroupsParams extends extendedFindParamsMixin({ - limit: 100, +export type AdminGetCustomerGroupsParamsType = z.infer< + typeof AdminGetCustomerGroupsParams +> +export const AdminGetCustomerGroupsParams = createFindParams({ + limit: 50, offset: 0, -}) { - @IsOptional() - @IsString() - q?: string +}).merge( + z.object({ + q: z.string().optional(), + id: z.union([z.string(), z.array(z.string())]).optional(), + name: z.union([z.string(), z.array(z.string())]).optional(), + customers: z + .union([z.string(), z.array(z.string()), AdminCustomerInGroupFilters]) + .optional(), + created_by: z.union([z.string(), z.array(z.string())]).optional(), + created_at: createOperatorMap().optional(), + updated_at: createOperatorMap().optional(), + deleted_at: createOperatorMap().optional(), + $and: z.lazy(() => AdminGetCustomerGroupsParams.array()).optional(), + $or: z.lazy(() => AdminGetCustomerGroupsParams.array()).optional(), + }) +) - @IsOptional() - @IsString({ each: true }) - id?: string | string[] +export type AdminCreateCustomerGroupType = z.infer< + typeof AdminCreateCustomerGroup +> +export const AdminCreateCustomerGroup = z.object({ + name: z.string(), +}) - @IsOptional() - @ValidateNested({ each: true }) - @Type(() => OperatorMapValidator) - name?: string | OperatorMap +export type AdminUpdateCustomerGroupType = z.infer< + typeof AdminUpdateCustomerGroup +> +export const AdminUpdateCustomerGroup = z.object({ + name: z.string(), +}) - @IsOptional() - @ValidateNested() - @Type(() => FilterableCustomerPropsValidator) - customers?: FilterableCustomerPropsValidator | string | string[] - - @IsOptional() - @IsString({ each: true }) - created_by?: string | string[] | null - - @IsOptional() - @ValidateNested() - @Type(() => OperatorMapValidator) - created_at?: OperatorMap - - @IsOptional() - @ValidateNested() - @Type(() => OperatorMapValidator) - updated_at?: OperatorMap - - // Additional filters from BaseFilterable - @IsOptional() - @ValidateNested({ each: true }) - @Type(() => AdminGetCustomerGroupsParams) - $and?: AdminGetCustomerGroupsParams[] - - @IsOptional() - @ValidateNested({ each: true }) - @Type(() => AdminGetCustomerGroupsParams) - $or?: AdminGetCustomerGroupsParams[] -} - -export class AdminPostCustomerGroupsReq { - @IsNotEmpty() - @IsString() - name: string -} - -export class AdminPostCustomerGroupsGroupReq { - @IsNotEmpty() - @IsString() - @IsOptional() - name?: string -} - -export class AdminGetCustomerGroupsGroupCustomersParams extends extendedFindParamsMixin( - { - limit: 100, - offset: 0, - } -) { - @IsOptional() - @IsString() - q?: string - - @IsOptional() - @IsString({ each: true }) - id?: string | string[] - - @IsOptional() - @IsType([String, [String], OperatorMapValidator]) - email?: string | string[] | OperatorMap - - @IsOptional() - @IsString({ each: true }) - company_name?: string | string[] | OperatorMap | null - - @IsOptional() - @IsString({ each: true }) - first_name?: string | string[] | OperatorMap | null - - @IsOptional() - @IsType([String, [String], OperatorMapValidator]) - @Transform(({ value }) => (value === "null" ? null : value)) - last_name?: string | string[] | OperatorMap | null - - @IsOptional() - @IsString({ each: true }) - created_by?: string | string[] | null - - @IsOptional() - @ValidateNested() - @Type(() => OperatorMapValidator) - created_at?: OperatorMap - - @IsOptional() - @ValidateNested() - @Type(() => OperatorMapValidator) - updated_at?: OperatorMap -} - -class CustomerGroupsBatchCustomer { - @IsString() - id: string -} - -export class AdminDeleteCustomerGroupsGroupCustomersBatchReq { - @ValidateNested({ each: true }) - @Type(() => CustomerGroupsBatchCustomer) - customer_ids: CustomerGroupsBatchCustomer[] -} - -export class AdminPostCustomerGroupsGroupCustomersBatchReq { - @ValidateNested({ each: true }) - @Type(() => CustomerGroupsBatchCustomer) - customer_ids: CustomerGroupsBatchCustomer[] -} +export type AdminSetCustomersCustomerGroupType = z.infer< + typeof AdminSetCustomersCustomerGroup +> +export const AdminSetCustomersCustomerGroup = z.string() diff --git a/packages/medusa/src/api-v2/admin/customers/[id]/addresses/[address_id]/route.ts b/packages/medusa/src/api-v2/admin/customers/[id]/addresses/[address_id]/route.ts index 636b8ba09b..c011a5540f 100644 --- a/packages/medusa/src/api-v2/admin/customers/[id]/addresses/[address_id]/route.ts +++ b/packages/medusa/src/api-v2/admin/customers/[id]/addresses/[address_id]/route.ts @@ -2,35 +2,38 @@ import { AuthenticatedMedusaRequest, MedusaResponse, } from "../../../../../../types/routing" -import { CustomerAddressDTO, ICustomerModuleService } from "@medusajs/types" import { deleteCustomerAddressesWorkflow, updateCustomerAddressesWorkflow, } from "@medusajs/core-flows" -import { ModuleRegistrationName } from "@medusajs/modules-sdk" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" +import { AdminCreateCustomerAddressType } from "../../../validators" +import { refetchCustomer } from "../../../helpers" export const GET = async ( req: AuthenticatedMedusaRequest, res: MedusaResponse ) => { - const customerModuleService = req.scope.resolve( - ModuleRegistrationName.CUSTOMER - ) + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + const queryObject = remoteQueryObjectFromString({ + entryPoint: "customer_address", + variables: { + filters: { id: req.params.address_id, customer_id: req.params.id }, + }, + fields: req.remoteQueryConfig.fields, + }) - const [address] = await customerModuleService.listAddresses( - { id: req.params.address_id, customer_id: req.params.id }, - { - select: req.retrieveConfig.select, - relations: req.retrieveConfig.relations, - } - ) + const [address] = await remoteQuery(queryObject) res.status(200).json({ address }) } export const POST = async ( - req: AuthenticatedMedusaRequest>, + req: AuthenticatedMedusaRequest, res: MedusaResponse ) => { const updateAddresses = updateCustomerAddressesWorkflow(req.scope) @@ -46,7 +49,13 @@ export const POST = async ( throw errors[0].error } - res.status(200).json({ address: result[0] }) + const customer = await refetchCustomer( + req.params.id, + req.scope, + req.remoteQueryConfig.fields + ) + + res.status(200).json({ customer }) } export const DELETE = async ( @@ -65,9 +74,16 @@ export const DELETE = async ( throw errors[0].error } + const customer = await refetchCustomer( + req.params.id, + req.scope, + req.remoteQueryConfig.fields + ) + res.status(200).json({ id, - object: "address", + object: "customer_address", deleted: true, + parent: customer, }) } diff --git a/packages/medusa/src/api-v2/admin/customers/[id]/addresses/route.ts b/packages/medusa/src/api-v2/admin/customers/[id]/addresses/route.ts index 634ffb3219..52b92c2f24 100644 --- a/packages/medusa/src/api-v2/admin/customers/[id]/addresses/route.ts +++ b/packages/medusa/src/api-v2/admin/customers/[id]/addresses/route.ts @@ -1,41 +1,43 @@ import { createCustomerAddressesWorkflow } from "@medusajs/core-flows" -import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { - CreateCustomerAddressDTO, - ICustomerModuleService, -} from "@medusajs/types" import { AuthenticatedMedusaRequest, MedusaResponse, } from "../../../../../types/routing" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" +import { AdminCreateCustomerAddressType } from "../../validators" +import { refetchCustomer } from "../../helpers" export const GET = async ( req: AuthenticatedMedusaRequest, res: MedusaResponse ) => { const customerId = req.params.id + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) - const customerModuleService = req.scope.resolve( - ModuleRegistrationName.CUSTOMER - ) + const query = remoteQueryObjectFromString({ + entryPoint: "customer_address", + variables: { + filters: { ...req.filterableFields, customer_id: customerId }, + ...req.remoteQueryConfig.pagination, + }, + fields: req.remoteQueryConfig.fields, + }) - const [addresses, count] = await customerModuleService.listAndCountAddresses( - { ...req.filterableFields, customer_id: customerId }, - req.listConfig - ) - - const { offset, limit } = req.validatedQuery + const { rows: addresses, metadata } = await remoteQuery(query) res.json({ - count, addresses, - offset, - limit, + count: metadata.count, + offset: metadata.skip, + limit: metadata.take, }) } export const POST = async ( - req: AuthenticatedMedusaRequest, + req: AuthenticatedMedusaRequest, res: MedusaResponse ) => { const customerId = req.params.id @@ -56,5 +58,11 @@ export const POST = async ( throw errors[0].error } - res.status(200).json({ address: result[0] }) + const customer = await refetchCustomer( + customerId, + req.scope, + req.remoteQueryConfig.fields + ) + + res.status(200).json({ customer }) } diff --git a/packages/medusa/src/api-v2/admin/customers/[id]/route.ts b/packages/medusa/src/api-v2/admin/customers/[id]/route.ts index 2054610cc6..0b4aaf92f8 100644 --- a/packages/medusa/src/api-v2/admin/customers/[id]/route.ts +++ b/packages/medusa/src/api-v2/admin/customers/[id]/route.ts @@ -2,37 +2,37 @@ import { deleteCustomersWorkflow, updateCustomersWorkflow, } from "@medusajs/core-flows" -import { AdminCustomerResponse, CustomerUpdatableFields } from "@medusajs/types" -import { - ContainerRegistrationKeys, - remoteQueryObjectFromString, -} from "@medusajs/utils" +import { AdminCustomerResponse } from "@medusajs/types" +import { MedusaError } from "@medusajs/utils" import { AuthenticatedMedusaRequest, MedusaResponse, } from "../../../../types/routing" +import { refetchCustomer } from "../helpers" +import { AdminUpdateCustomerType } from "../validators" export const GET = async ( req: AuthenticatedMedusaRequest, res: MedusaResponse ) => { - const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + const customer = await refetchCustomer( + req.params.id, + req.scope, + req.remoteQueryConfig.fields + ) - const variables = { id: req.params.id } - - const queryObject = remoteQueryObjectFromString({ - entryPoint: "customer", - variables, - fields: req.remoteQueryConfig.fields, - }) - - const [customer] = await remoteQuery(queryObject) + if (!customer) { + throw new MedusaError( + MedusaError.Types.NOT_FOUND, + `Customer with id: ${req.params.id} not found` + ) + } res.status(200).json({ customer }) } export const POST = async ( - req: AuthenticatedMedusaRequest, + req: AuthenticatedMedusaRequest, res: MedusaResponse ) => { const { errors } = await updateCustomersWorkflow(req.scope).run({ @@ -47,18 +47,11 @@ export const POST = async ( throw errors[0].error } - const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) - - const queryObject = remoteQueryObjectFromString({ - entryPoint: "customer", - variables: { - filters: { id: req.params.id }, - }, - fields: req.remoteQueryConfig.fields, - }) - - const [customer] = await remoteQuery(queryObject) - + const customer = await refetchCustomer( + req.params.id, + req.scope, + req.remoteQueryConfig.fields + ) res.status(200).json({ customer }) } diff --git a/packages/medusa/src/api-v2/admin/customers/helpers.ts b/packages/medusa/src/api-v2/admin/customers/helpers.ts new file mode 100644 index 0000000000..5aee77c888 --- /dev/null +++ b/packages/medusa/src/api-v2/admin/customers/helpers.ts @@ -0,0 +1,23 @@ +import { MedusaContainer } from "@medusajs/types" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" + +export const refetchCustomer = async ( + customerId: string, + scope: MedusaContainer, + fields: string[] +) => { + const remoteQuery = scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) + const queryObject = remoteQueryObjectFromString({ + entryPoint: "customer", + variables: { + filters: { id: customerId }, + }, + fields: fields, + }) + + const customers = await remoteQuery(queryObject) + return customers[0] +} diff --git a/packages/medusa/src/api-v2/admin/customers/middlewares.ts b/packages/medusa/src/api-v2/admin/customers/middlewares.ts index 4001202fe7..9819920cc0 100644 --- a/packages/medusa/src/api-v2/admin/customers/middlewares.ts +++ b/packages/medusa/src/api-v2/admin/customers/middlewares.ts @@ -19,7 +19,7 @@ export const adminCustomerRoutesMiddlewares: MiddlewareRoute[] = [ { method: ["ALL"], matcher: "/admin/customers*", - middlewares: [authenticate("admin", ["bearer", "session"])], + middlewares: [authenticate("admin", ["bearer", "session", "api-key"])], }, { method: ["GET"], @@ -38,7 +38,7 @@ export const adminCustomerRoutesMiddlewares: MiddlewareRoute[] = [ validateAndTransformBody(AdminCreateCustomer), validateAndTransformQuery( AdminCustomerParams, - QueryConfig.listTransformQueryConfig + QueryConfig.retrieveTransformQueryConfig ), ], }, @@ -48,7 +48,7 @@ export const adminCustomerRoutesMiddlewares: MiddlewareRoute[] = [ middlewares: [ validateAndTransformQuery( AdminCustomerParams, - QueryConfig.listTransformQueryConfig + QueryConfig.retrieveTransformQueryConfig ), ], }, @@ -59,19 +59,41 @@ export const adminCustomerRoutesMiddlewares: MiddlewareRoute[] = [ validateAndTransformBody(AdminUpdateCustomer), validateAndTransformQuery( AdminCustomerParams, - QueryConfig.listTransformQueryConfig + QueryConfig.retrieveTransformQueryConfig ), ], }, { method: ["POST"], matcher: "/admin/customers/:id/addresses", - middlewares: [validateAndTransformBody(AdminCreateCustomerAddress)], + middlewares: [ + validateAndTransformBody(AdminCreateCustomerAddress), + validateAndTransformQuery( + AdminCustomerParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], }, { method: ["POST"], matcher: "/admin/customers/:id/addresses/:address_id", - middlewares: [validateAndTransformBody(AdminUpdateCustomerAddress)], + middlewares: [ + validateAndTransformBody(AdminUpdateCustomerAddress), + validateAndTransformQuery( + AdminCustomerParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], + }, + { + method: ["DELETE"], + matcher: "/admin/customers/:id/addresses/:address_id", + middlewares: [ + validateAndTransformQuery( + AdminCustomerParams, + QueryConfig.retrieveTransformQueryConfig + ), + ], }, { method: ["GET"], diff --git a/packages/medusa/src/api-v2/admin/customers/query-config.ts b/packages/medusa/src/api-v2/admin/customers/query-config.ts index 48960739a7..dfe365feaa 100644 --- a/packages/medusa/src/api-v2/admin/customers/query-config.ts +++ b/packages/medusa/src/api-v2/admin/customers/query-config.ts @@ -1,5 +1,3 @@ -export const defaultAdminCustomerRelations = [] -export const allowedAdminCustomerRelations = ["groups", "addresses"] export const defaultAdminCustomerFields = [ "id", "company_name", @@ -7,15 +5,14 @@ export const defaultAdminCustomerFields = [ "last_name", "email", "phone", + "created_by", "created_at", "updated_at", "deleted_at", ] export const retrieveTransformQueryConfig = { - defaultFields: defaultAdminCustomerFields, - defaultRelations: defaultAdminCustomerRelations, - allowedRelations: allowedAdminCustomerRelations, + defaults: defaultAdminCustomerFields, isList: false, } @@ -24,8 +21,6 @@ export const listTransformQueryConfig = { isList: true, } -export const defaultAdminCustomerAddressRelations = [] -export const allowedAdminCustomerAddressRelations = ["customer"] export const defaultAdminCustomerAddressFields = [ "id", "company", @@ -45,9 +40,7 @@ export const defaultAdminCustomerAddressFields = [ ] export const retrieveAddressTransformQueryConfig = { - defaultFields: defaultAdminCustomerAddressFields, - defaultRelations: defaultAdminCustomerAddressRelations, - allowedRelations: allowedAdminCustomerAddressRelations, + defaults: defaultAdminCustomerAddressFields, isList: false, } diff --git a/packages/medusa/src/api-v2/admin/customers/route.ts b/packages/medusa/src/api-v2/admin/customers/route.ts index fd522eafbc..ee9bbbfbcc 100644 --- a/packages/medusa/src/api-v2/admin/customers/route.ts +++ b/packages/medusa/src/api-v2/admin/customers/route.ts @@ -3,27 +3,29 @@ import { AdminCustomerListResponse, AdminCustomerResponse, } from "@medusajs/types" -import { remoteQueryObjectFromString } from "@medusajs/utils" +import { + ContainerRegistrationKeys, + remoteQueryObjectFromString, +} from "@medusajs/utils" import { AuthenticatedMedusaRequest, MedusaResponse, } from "../../../types/routing" import { AdminCreateCustomerType } from "./validators" +import { refetchCustomer } from "./helpers" export const GET = async ( req: AuthenticatedMedusaRequest, res: MedusaResponse ) => { - const remoteQuery = req.scope.resolve("remoteQuery") - - const variables = { - filters: req.filterableFields, - ...req.remoteQueryConfig.pagination, - } + const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY) const query = remoteQueryObjectFromString({ entryPoint: "customers", - variables, + variables: { + filters: req.filterableFields, + ...req.remoteQueryConfig.pagination, + }, fields: req.remoteQueryConfig.fields, }) @@ -59,5 +61,11 @@ export const POST = async ( throw errors[0].error } - res.status(200).json({ customer: result[0] as AdminCustomerResponse["customer"] }) + const customer = await refetchCustomer( + result[0].id, + req.scope, + req.remoteQueryConfig.fields + ) + + res.status(200).json({ customer }) } diff --git a/packages/medusa/src/api-v2/admin/customers/validators.ts b/packages/medusa/src/api-v2/admin/customers/validators.ts index a540bad30c..300a2baffd 100644 --- a/packages/medusa/src/api-v2/admin/customers/validators.ts +++ b/packages/medusa/src/api-v2/admin/customers/validators.ts @@ -6,7 +6,6 @@ import { } from "../../utils/validators" export const AdminCustomerParams = createSelectParams() -export const AdminCustomerGroupParams = createSelectParams() export const AdminCustomerGroupInCustomerParams = z.object({ id: z.union([z.string(), z.array(z.string())]).optional(), @@ -35,9 +34,9 @@ export const AdminCustomersParams = createFindParams({ first_name: z.union([z.string(), z.array(z.string())]).optional(), last_name: z.union([z.string(), z.array(z.string())]).optional(), created_by: z.union([z.string(), z.array(z.string())]).optional(), - created_at: createOperatorMap().optional().optional(), - updated_at: createOperatorMap().optional().optional(), - deleted_at: createOperatorMap().optional().optional(), + created_at: createOperatorMap().optional(), + updated_at: createOperatorMap().optional(), + deleted_at: createOperatorMap().optional(), $and: z.lazy(() => AdminCustomersParams.array()).optional(), $or: z.lazy(() => AdminCustomersParams.array()).optional(), }) @@ -101,12 +100,6 @@ export const AdminCustomerAdressesParams = createFindParams({ ) export type AdminCustomerParamsType = z.infer -export type AdminCustomerGroupParamsType = z.infer< - typeof AdminCustomerGroupParams -> -export type AdminCustomerGroupInCustomerParamsType = z.infer< - typeof AdminCustomerGroupInCustomerParams -> export type AdminCustomersParamsType = z.infer export type AdminCreateCustomerType = z.infer export type AdminUpdateCustomerType = z.infer