From a28822e0d4ec03390af01d2d9319906667d750ba Mon Sep 17 00:00:00 2001 From: Sebastian Rindom Date: Thu, 1 Feb 2024 11:11:52 +0100 Subject: [PATCH] feat(customer): store addresses (#6283) - GET /customers/me/addresses - POST /customers/me/addresses - GET /customers/me/addresses/:address_id - POST /customers/me/addresses/:address_id - DELETE /customers/me/addresses/:address_id --- .../store/create-customer-addresses.ts | 76 ++++++ .../store/delete-customer-address.spec.ts | 93 ++++++++ .../__tests__/customer/store/get-me.spec.ts | 23 +- .../customer/store/list-customer-addresses.ts | 105 +++++++++ .../store/update-customer-address.spec.ts | 99 ++++++++ .../helpers/create-authenticated-customer.ts | 22 ++ .../me/addresses/[address_id]/route.ts | 94 ++++++++ .../store/customers/me/addresses/route.ts | 52 +++++ .../src/api-v2/store/customers/middlewares.ts | 28 ++- .../api-v2/store/customers/query-config.ts | 32 +++ .../src/api-v2/store/customers/validators.ts | 219 +++++++++++++++++- 11 files changed, 823 insertions(+), 20 deletions(-) create mode 100644 integration-tests/plugins/__tests__/customer/store/create-customer-addresses.ts create mode 100644 integration-tests/plugins/__tests__/customer/store/delete-customer-address.spec.ts create mode 100644 integration-tests/plugins/__tests__/customer/store/list-customer-addresses.ts create mode 100644 integration-tests/plugins/__tests__/customer/store/update-customer-address.spec.ts create mode 100644 integration-tests/plugins/helpers/create-authenticated-customer.ts create mode 100644 packages/medusa/src/api-v2/store/customers/me/addresses/[address_id]/route.ts create mode 100644 packages/medusa/src/api-v2/store/customers/me/addresses/route.ts diff --git a/integration-tests/plugins/__tests__/customer/store/create-customer-addresses.ts b/integration-tests/plugins/__tests__/customer/store/create-customer-addresses.ts new file mode 100644 index 0000000000..f628406a4d --- /dev/null +++ b/integration-tests/plugins/__tests__/customer/store/create-customer-addresses.ts @@ -0,0 +1,76 @@ +import { ModuleRegistrationName } from "@medusajs/modules-sdk" +import { ICustomerModuleService } 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 { createAuthenticatedCustomer } from "../../../helpers/create-authenticated-customer" + +jest.setTimeout(50000) + +const env = { MEDUSA_FF_MEDUSA_V2: true } + +describe("POST /store/customers/me/addresses", () => { + let dbConnection + let appContainer + let shutdownServer + let customerModuleService: ICustomerModuleService + + beforeAll(async () => { + const cwd = path.resolve(path.join(__dirname, "..", "..", "..")) + dbConnection = await initDb({ cwd, env } as any) + shutdownServer = await startBootstrapApp({ cwd, env }) + appContainer = getContainer() + customerModuleService = appContainer.resolve( + ModuleRegistrationName.CUSTOMER + ) + }) + + afterAll(async () => { + const db = useDb() + await db.shutdown() + await shutdownServer() + }) + + afterEach(async () => { + const db = useDb() + await db.teardown() + }) + + it("should create a customer address", async () => { + const { customer, jwt } = await createAuthenticatedCustomer( + customerModuleService, + appContainer.resolve(ModuleRegistrationName.AUTH) + ) + + const api = useApi() as any + const response = await api.post( + `/store/customers/me/addresses`, + { + first_name: "John", + last_name: "Doe", + address_1: "Test street 1", + }, + { headers: { authorization: `Bearer ${jwt}` } } + ) + + 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", + customer_id: customer.id, + }) + ) + + const customerWithAddresses = await customerModuleService.retrieve( + customer.id, + { relations: ["addresses"] } + ) + + expect(customerWithAddresses.addresses?.length).toEqual(1) + }) +}) diff --git a/integration-tests/plugins/__tests__/customer/store/delete-customer-address.spec.ts b/integration-tests/plugins/__tests__/customer/store/delete-customer-address.spec.ts new file mode 100644 index 0000000000..d2476958ab --- /dev/null +++ b/integration-tests/plugins/__tests__/customer/store/delete-customer-address.spec.ts @@ -0,0 +1,93 @@ +import { ModuleRegistrationName } from "@medusajs/modules-sdk" +import { ICustomerModuleService } 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 { createAuthenticatedCustomer } from "../../../helpers/create-authenticated-customer" + +const env = { MEDUSA_FF_MEDUSA_V2: true } + +describe("DELETE /store/customers/me/addresses/:address_id", () => { + let dbConnection + let appContainer + let shutdownServer + let customerModuleService: ICustomerModuleService + + beforeAll(async () => { + const cwd = path.resolve(path.join(__dirname, "..", "..", "..")) + dbConnection = await initDb({ cwd, env } as any) + shutdownServer = await startBootstrapApp({ cwd, env }) + appContainer = getContainer() + customerModuleService = appContainer.resolve( + ModuleRegistrationName.CUSTOMER + ) + }) + + afterAll(async () => { + const db = useDb() + await db.shutdown() + await shutdownServer() + }) + + afterEach(async () => { + const db = useDb() + await db.teardown() + }) + + it("should delete a customer address", async () => { + const { customer, jwt } = await createAuthenticatedCustomer( + customerModuleService, + appContainer.resolve(ModuleRegistrationName.AUTH) + ) + + const address = await customerModuleService.addAddresses({ + customer_id: customer.id, + first_name: "John", + last_name: "Doe", + address_1: "Test street 1", + }) + + const api = useApi() as any + const response = await api.delete( + `/store/customers/me/addresses/${address.id}`, + { headers: { authorization: `Bearer ${jwt}` } } + ) + + expect(response.status).toEqual(200) + + const updatedCustomer = await customerModuleService.retrieve(customer.id, { + relations: ["addresses"], + }) + + expect(updatedCustomer.addresses?.length).toEqual(0) + }) + + it("should fail to delete another customer's address", async () => { + const { jwt } = await createAuthenticatedCustomer( + customerModuleService, + appContainer.resolve(ModuleRegistrationName.AUTH) + ) + + const otherCustomer = await customerModuleService.create({ + first_name: "Jane", + last_name: "Doe", + }) + const address = await customerModuleService.addAddresses({ + customer_id: otherCustomer.id, + first_name: "John", + last_name: "Doe", + address_1: "Test street 1", + }) + + const api = useApi() as any + const response = await api + .delete(`/store/customers/me/addresses/${address.id}`, { + headers: { authorization: `Bearer ${jwt}` }, + }) + .catch((e) => e.response) + + expect(response.status).toEqual(404) + }) +}) diff --git a/integration-tests/plugins/__tests__/customer/store/get-me.spec.ts b/integration-tests/plugins/__tests__/customer/store/get-me.spec.ts index 24dc30af87..c5329a4c83 100644 --- a/integration-tests/plugins/__tests__/customer/store/get-me.spec.ts +++ b/integration-tests/plugins/__tests__/customer/store/get-me.spec.ts @@ -1,11 +1,12 @@ import { ModuleRegistrationName } from "@medusajs/modules-sdk" -import { ICustomerModuleService, IAuthModuleService } from "@medusajs/types" +import { ICustomerModuleService } 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" +import { createAuthenticatedCustomer } from "../../../helpers/create-authenticated-customer" jest.setTimeout(50000) @@ -43,22 +44,10 @@ describe("GET /store/customers", () => { }) it("should retrieve auth user's customer", async () => { - const customer = await customerModuleService.create({ - first_name: "John", - last_name: "Doe", - email: "john@me.com", - }) - - const authService: IAuthModuleService = appContainer.resolve( - ModuleRegistrationName.AUTH + const { customer, jwt } = await createAuthenticatedCustomer( + customerModuleService, + appContainer.resolve(ModuleRegistrationName.AUTH) ) - const authUser = await authService.createAuthUser({ - entity_id: "store_user", - provider_id: "test", - app_metadata: { customer_id: customer.id }, - }) - - const jwt = await authService.generateJwtToken(authUser.id, "store") const api = useApi() as any const response = await api.get(`/store/customers/me`, { @@ -68,7 +57,7 @@ describe("GET /store/customers", () => { expect(response.status).toEqual(200) expect(response.data.customer).toEqual( expect.objectContaining({ - id: expect.any(String), + id: customer.id, first_name: "John", last_name: "Doe", email: "john@me.com", diff --git a/integration-tests/plugins/__tests__/customer/store/list-customer-addresses.ts b/integration-tests/plugins/__tests__/customer/store/list-customer-addresses.ts new file mode 100644 index 0000000000..abaf5abe24 --- /dev/null +++ b/integration-tests/plugins/__tests__/customer/store/list-customer-addresses.ts @@ -0,0 +1,105 @@ +import { ModuleRegistrationName } from "@medusajs/modules-sdk" +import { ICustomerModuleService } 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 { createAuthenticatedCustomer } from "../../../helpers/create-authenticated-customer" + +const env = { MEDUSA_FF_MEDUSA_V2: true } + +describe("GET /store/customers/me/addresses", () => { + let dbConnection + let appContainer + let shutdownServer + let customerModuleService: ICustomerModuleService + + beforeAll(async () => { + const cwd = path.resolve(path.join(__dirname, "..", "..", "..")) + dbConnection = await initDb({ cwd, env } as any) + shutdownServer = await startBootstrapApp({ cwd, env }) + appContainer = getContainer() + customerModuleService = appContainer.resolve( + ModuleRegistrationName.CUSTOMER + ) + }) + + afterAll(async () => { + const db = useDb() + await db.shutdown() + await shutdownServer() + }) + + afterEach(async () => { + const db = useDb() + await db.teardown() + }) + + it("should get all customer addresses and its count", async () => { + const { customer, jwt } = await createAuthenticatedCustomer( + customerModuleService, + appContainer.resolve(ModuleRegistrationName.AUTH) + ) + + await customerModuleService.addAddresses([ + { + first_name: "Test", + last_name: "Test", + address_1: "Test street 1", + customer_id: customer.id, + }, + { + first_name: "Test", + last_name: "Test", + address_1: "Test street 2", + customer_id: customer.id, + }, + { + first_name: "Test", + last_name: "Test", + address_1: "Test street 3", + customer_id: customer.id, + }, + ]) + + await customerModuleService.create({ + first_name: "Test Test", + last_name: "Test Test", + addresses: [ + { + first_name: "Test TEST", + last_name: "Test TEST", + address_1: "NOT street 1", + }, + ], + }) + + const api = useApi() as any + const response = await api.get(`/store/customers/me/addresses`, { + headers: { authorization: `Bearer ${jwt}` }, + }) + + expect(response.status).toEqual(200) + expect(response.data.count).toEqual(3) + expect(response.data.addresses).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: expect.any(String), + customer_id: customer.id, + address_1: "Test street 1", + }), + expect.objectContaining({ + id: expect.any(String), + customer_id: customer.id, + address_1: "Test street 2", + }), + expect.objectContaining({ + id: expect.any(String), + customer_id: customer.id, + address_1: "Test street 3", + }), + ]) + ) + }) +}) diff --git a/integration-tests/plugins/__tests__/customer/store/update-customer-address.spec.ts b/integration-tests/plugins/__tests__/customer/store/update-customer-address.spec.ts new file mode 100644 index 0000000000..258d7a19c5 --- /dev/null +++ b/integration-tests/plugins/__tests__/customer/store/update-customer-address.spec.ts @@ -0,0 +1,99 @@ +import { ModuleRegistrationName } from "@medusajs/modules-sdk" +import { ICustomerModuleService } 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 { createAuthenticatedCustomer } from "../../../helpers/create-authenticated-customer" + +const env = { MEDUSA_FF_MEDUSA_V2: true } + +describe("POST /store/customers/:id/addresses/:address_id", () => { + let dbConnection + let appContainer + let shutdownServer + let customerModuleService: ICustomerModuleService + + beforeAll(async () => { + const cwd = path.resolve(path.join(__dirname, "..", "..", "..")) + dbConnection = await initDb({ cwd, env } as any) + shutdownServer = await startBootstrapApp({ cwd, env }) + appContainer = getContainer() + customerModuleService = appContainer.resolve( + ModuleRegistrationName.CUSTOMER + ) + }) + + afterAll(async () => { + const db = useDb() + await db.shutdown() + await shutdownServer() + }) + + afterEach(async () => { + const db = useDb() + await db.teardown() + }) + + it("should update a customer address", async () => { + const { customer, jwt } = await createAuthenticatedCustomer( + customerModuleService, + appContainer.resolve(ModuleRegistrationName.AUTH) + ) + + const address = await customerModuleService.addAddresses({ + customer_id: customer.id, + first_name: "John", + last_name: "Doe", + address_1: "Test street 1", + }) + + const api = useApi() as any + const response = await api.post( + `/store/customers/me/addresses/${address.id}`, + { + first_name: "Jane", + }, + { headers: { authorization: `Bearer ${jwt}` } } + ) + + expect(response.status).toEqual(200) + expect(response.data.address).toEqual( + expect.objectContaining({ + id: address.id, + first_name: "Jane", + last_name: "Doe", + }) + ) + }) + + it("should fail to update another customer's address", async () => { + const { jwt } = await createAuthenticatedCustomer( + customerModuleService, + appContainer.resolve(ModuleRegistrationName.AUTH) + ) + + const otherCustomer = await customerModuleService.create({ + first_name: "Jane", + last_name: "Doe", + }) + const address = await customerModuleService.addAddresses({ + customer_id: otherCustomer.id, + first_name: "John", + last_name: "Doe", + address_1: "Test street 1", + }) + + const api = useApi() as any + const response = await api + .post( + `/store/customers/me/addresses/${address.id}`, + { first_name: "Jane" }, + { headers: { authorization: `Bearer ${jwt}` } } + ) + .catch((e) => e.response) + + expect(response.status).toEqual(404) + }) +}) diff --git a/integration-tests/plugins/helpers/create-authenticated-customer.ts b/integration-tests/plugins/helpers/create-authenticated-customer.ts new file mode 100644 index 0000000000..54f19cf097 --- /dev/null +++ b/integration-tests/plugins/helpers/create-authenticated-customer.ts @@ -0,0 +1,22 @@ +import { ICustomerModuleService, IAuthModuleService } from "@medusajs/types" + +export const createAuthenticatedCustomer = async ( + customerModuleService: ICustomerModuleService, + authService: IAuthModuleService +) => { + const customer = await customerModuleService.create({ + first_name: "John", + last_name: "Doe", + email: "john@me.com", + }) + + const authUser = await authService.createAuthUser({ + entity_id: "store_user", + provider_id: "test", + app_metadata: { customer_id: customer.id }, + }) + + const jwt = await authService.generateJwtToken(authUser.id, "store") + + return { customer, authUser, jwt } +} diff --git a/packages/medusa/src/api-v2/store/customers/me/addresses/[address_id]/route.ts b/packages/medusa/src/api-v2/store/customers/me/addresses/[address_id]/route.ts new file mode 100644 index 0000000000..8ab50d4cdf --- /dev/null +++ b/packages/medusa/src/api-v2/store/customers/me/addresses/[address_id]/route.ts @@ -0,0 +1,94 @@ +import { + updateCustomerAddressesWorkflow, + deleteCustomerAddressesWorkflow, +} from "@medusajs/core-flows" +import { ModuleRegistrationName } from "@medusajs/modules-sdk" +import { CustomerAddressDTO, ICustomerModuleService } from "@medusajs/types" +import { MedusaError } from "@medusajs/utils" +import { MedusaRequest, MedusaResponse } from "../../../../../../types/routing" + +export const GET = async (req: MedusaRequest, res: MedusaResponse) => { + const id = req.auth_user!.app_metadata.customer_id + + const customerModuleService = req.scope.resolve( + ModuleRegistrationName.CUSTOMER + ) + + const [address] = await customerModuleService.listAddresses( + { id: req.params.address_id, customer_id: id }, + { + select: req.retrieveConfig.select, + relations: req.retrieveConfig.relations, + } + ) + + res.status(200).json({ address }) +} + +export const POST = async (req: MedusaRequest, res: MedusaResponse) => { + const id = req.auth_user!.app_metadata.customer_id + const service = req.scope.resolve( + ModuleRegistrationName.CUSTOMER + ) + + await validateCustomerAddress(service, id, req.params.address_id) + + const updateAddresses = updateCustomerAddressesWorkflow(req.scope) + const { result, errors } = await updateAddresses.run({ + input: { + selector: { id: req.params.address_id, customer_id: req.params.id }, + update: req.validatedBody as Partial, + }, + throwOnError: false, + }) + + if (Array.isArray(errors) && errors[0]) { + throw errors[0].error + } + + res.status(200).json({ address: result[0] }) +} + +export const DELETE = async (req: MedusaRequest, res: MedusaResponse) => { + const id = req.auth_user!.app_metadata.customer_id + + const service = req.scope.resolve( + ModuleRegistrationName.CUSTOMER + ) + + await validateCustomerAddress(service, id, req.params.address_id) + const deleteAddress = deleteCustomerAddressesWorkflow(req.scope) + + const { errors } = await deleteAddress.run({ + input: { ids: [req.params.address_id] }, + throwOnError: false, + }) + + if (Array.isArray(errors) && errors[0]) { + throw errors[0].error + } + + res.status(200).json({ + id, + object: "address", + deleted: true, + }) +} + +const validateCustomerAddress = async ( + customerModuleService: ICustomerModuleService, + customerId: string, + addressId: string +) => { + const [address] = await customerModuleService.listAddresses( + { id: addressId, customer_id: customerId }, + { select: ["id"] } + ) + + if (!address) { + throw new MedusaError( + MedusaError.Types.NOT_FOUND, + `Address with id: ${addressId} was not found` + ) + } +} diff --git a/packages/medusa/src/api-v2/store/customers/me/addresses/route.ts b/packages/medusa/src/api-v2/store/customers/me/addresses/route.ts new file mode 100644 index 0000000000..1cb19543f4 --- /dev/null +++ b/packages/medusa/src/api-v2/store/customers/me/addresses/route.ts @@ -0,0 +1,52 @@ +import { createCustomerAddressesWorkflow } from "@medusajs/core-flows" +import { ModuleRegistrationName } from "@medusajs/modules-sdk" +import { + CreateCustomerAddressDTO, + ICustomerModuleService, +} from "@medusajs/types" +import { MedusaRequest, MedusaResponse } from "../../../../../types/routing" + +export const GET = async (req: MedusaRequest, res: MedusaResponse) => { + const customerId = req.auth_user!.app_metadata.customer_id + + const customerModuleService = req.scope.resolve( + ModuleRegistrationName.CUSTOMER + ) + + const [addresses, count] = await customerModuleService.listAndCountAddresses( + { ...req.filterableFields, customer_id: customerId }, + req.listConfig + ) + + const { offset, limit } = req.validatedQuery + + res.json({ + count, + addresses, + offset, + limit, + }) +} + +export const POST = async (req: MedusaRequest, res: MedusaResponse) => { + const customerId = req.auth_user!.app_metadata.customer_id + + const createAddresses = createCustomerAddressesWorkflow(req.scope) + const addresses = [ + { + ...(req.validatedBody as CreateCustomerAddressDTO), + customer_id: customerId, + }, + ] + + const { result, errors } = await createAddresses.run({ + input: { addresses }, + throwOnError: false, + }) + + if (Array.isArray(errors) && errors[0]) { + throw errors[0].error + } + + res.status(200).json({ address: result[0] }) +} diff --git a/packages/medusa/src/api-v2/store/customers/middlewares.ts b/packages/medusa/src/api-v2/store/customers/middlewares.ts index b42ff3a60a..c60b5f1ea2 100644 --- a/packages/medusa/src/api-v2/store/customers/middlewares.ts +++ b/packages/medusa/src/api-v2/store/customers/middlewares.ts @@ -1,6 +1,12 @@ import { transformBody, transformQuery } from "../../../api/middlewares" import { MiddlewareRoute } from "../../../loaders/helpers/routing/types" -import { StorePostCustomersReq, StoreGetCustomersMeParams } from "./validators" +import { + StorePostCustomersReq, + StoreGetCustomersMeParams, + StorePostCustomersMeAddressesReq, + StorePostCustomersMeAddressesAddressReq, + StoreGetCustomersMeAddressesParams, +} from "./validators" import authenticate from "../../../utils/authenticate-middleware" import * as QueryConfig from "./query-config" @@ -25,4 +31,24 @@ export const storeCustomerRoutesMiddlewares: MiddlewareRoute[] = [ ), ], }, + { + method: ["POST"], + matcher: "/store/customers/me/addresses", + middlewares: [transformBody(StorePostCustomersMeAddressesReq)], + }, + { + method: ["POST"], + matcher: "/store/customers/me/addresses/:address_id", + middlewares: [transformBody(StorePostCustomersMeAddressesAddressReq)], + }, + { + method: ["GET"], + matcher: "/store/customers/me/addresses", + middlewares: [ + transformQuery( + StoreGetCustomersMeAddressesParams, + QueryConfig.listAddressesTransformQueryConfig + ), + ], + }, ] diff --git a/packages/medusa/src/api-v2/store/customers/query-config.ts b/packages/medusa/src/api-v2/store/customers/query-config.ts index 8a1828b5e7..5a54fd3bce 100644 --- a/packages/medusa/src/api-v2/store/customers/query-config.ts +++ b/packages/medusa/src/api-v2/store/customers/query-config.ts @@ -22,3 +22,35 @@ export const retrieveTransformQueryConfig = { allowedRelations: allowedStoreCustomersRelations, isList: false, } + +export const defaultStoreCustomerAddressRelations = [] +export const allowedStoreCustomerAddressRelations = ["customer"] +export const defaultStoreCustomerAddressFields = [ + "id", + "company", + "customer_id", + "first_name", + "last_name", + "address_1", + "address_2", + "city", + "province", + "postal_code", + "country_code", + "phone", + "metadata", + "created_at", + "updated_at", +] + +export const retrieveAddressTransformQueryConfig = { + defaultFields: defaultStoreCustomerAddressFields, + defaultRelations: defaultStoreCustomerAddressRelations, + allowedRelations: allowedStoreCustomerAddressRelations, + isList: false, +} + +export const listAddressesTransformQueryConfig = { + ...retrieveAddressTransformQueryConfig, + isList: true, +} diff --git a/packages/medusa/src/api-v2/store/customers/validators.ts b/packages/medusa/src/api-v2/store/customers/validators.ts index c32d2634b5..8bb0fc48d4 100644 --- a/packages/medusa/src/api-v2/store/customers/validators.ts +++ b/packages/medusa/src/api-v2/store/customers/validators.ts @@ -1,5 +1,16 @@ -import { IsEmail, IsObject, IsOptional, IsString } from "class-validator" -import { FindParams } from "../../../types/common" +import { OperatorMap } from "@medusajs/types" +import { Type } from "class-transformer" +import { + IsBoolean, + IsEmail, + IsNotEmpty, + IsObject, + IsOptional, + IsString, + ValidateNested, +} from "class-validator" +import { extendedFindParamsMixin, FindParams } from "../../../types/common" +import { OperatorMapValidator } from "../../../types/validators/operator-map" export class StoreGetCustomersMeParams extends FindParams {} @@ -27,3 +38,207 @@ export class StorePostCustomersReq { @IsOptional() metadata?: Record } + +export class StorePostCustomersMeAddressesReq { + @IsNotEmpty() + @IsString() + @IsOptional() + address_name?: string + + @IsBoolean() + @IsOptional() + is_default_shipping?: boolean + + @IsBoolean() + @IsOptional() + is_default_billing?: boolean + + @IsNotEmpty() + @IsString() + @IsOptional() + company?: string + + @IsNotEmpty() + @IsString() + @IsOptional() + first_name?: string + + @IsNotEmpty() + @IsString() + @IsOptional() + last_name?: string + + @IsNotEmpty() + @IsString() + @IsOptional() + address_1?: string + + @IsNotEmpty() + @IsString() + @IsOptional() + address_2?: string + + @IsNotEmpty() + @IsString() + @IsOptional() + city?: string + + @IsNotEmpty() + @IsString() + @IsOptional() + country_code?: string + + @IsNotEmpty() + @IsString() + @IsOptional() + province?: string + + @IsNotEmpty() + @IsString() + @IsOptional() + postal_code?: string + + @IsNotEmpty() + @IsString() + @IsOptional() + phone?: string + + @IsNotEmpty() + @IsString() + @IsOptional() + metadata?: Record +} + +export class StorePostCustomersMeAddressesAddressReq { + @IsNotEmpty() + @IsString() + @IsOptional() + address_name?: string + + @IsBoolean() + @IsOptional() + is_default_shipping?: boolean + + @IsBoolean() + @IsOptional() + is_default_billing?: boolean + + @IsNotEmpty() + @IsString() + @IsOptional() + company?: string + + @IsNotEmpty() + @IsString() + @IsOptional() + first_name?: string + + @IsNotEmpty() + @IsString() + @IsOptional() + last_name?: string + + @IsNotEmpty() + @IsString() + @IsOptional() + address_1?: string + + @IsNotEmpty() + @IsString() + @IsOptional() + address_2?: string + + @IsNotEmpty() + @IsString() + @IsOptional() + city?: string + + @IsNotEmpty() + @IsString() + @IsOptional() + country_code?: string + + @IsNotEmpty() + @IsString() + @IsOptional() + province?: string + + @IsNotEmpty() + @IsString() + @IsOptional() + postal_code?: string + + @IsNotEmpty() + @IsString() + @IsOptional() + phone?: string + + @IsNotEmpty() + @IsString() + @IsOptional() + metadata?: Record +} + +export class StoreGetCustomersMeAddressesParams extends extendedFindParamsMixin( + { + limit: 100, + offset: 0, + } +) { + @IsOptional() + @IsString({ each: true }) + address_name?: string | string[] | OperatorMap + + @IsOptional() + @IsBoolean() + is_default_shipping?: boolean + + @IsOptional() + @IsBoolean() + is_default_billing?: boolean + + @IsOptional() + @IsString({ each: true }) + company?: 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 }) + address_1?: string | string[] | OperatorMap | null + + @IsOptional() + @IsString({ each: true }) + address_2?: string | string[] | OperatorMap | null + + @IsOptional() + @IsString({ each: true }) + city?: string | string[] | OperatorMap | null + + @IsOptional() + @IsString({ each: true }) + country_code?: string | string[] | OperatorMap | null + + @IsOptional() + @IsString({ each: true }) + province?: string | string[] | OperatorMap | null + + @IsOptional() + @IsString({ each: true }) + postal_code?: string | string[] | OperatorMap | null + + @IsOptional() + @IsString({ each: true }) + phone?: string | string[] | OperatorMap | null + + @IsOptional() + @ValidateNested() + @Type(() => OperatorMapValidator) + metadata?: OperatorMap> +}