feat(customer): list customer (#6206)
**What** - GET /admin/customers - GET /admin/customer-groups
This commit is contained in:
1 parent
90cff0777f
commit
87390704be
17 files changed
+736
-3
No files matched your search
@@ -0,0 +1,63 @@
|
|||||||
|
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 adminSeeder from "../../../../helpers/admin-seeder"
|
||||||
|
|
||||||
|
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
||||||
|
const adminHeaders = {
|
||||||
|
headers: { "x-medusa-access-token": "test_token" },
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("GET /admin/customer-groups", () => {
|
||||||
|
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()
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await adminSeeder(dbConnection)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.teardown()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should get all customer groups and its count", async () => {
|
||||||
|
await customerModuleService.createCustomerGroup({
|
||||||
|
name: "Test",
|
||||||
|
})
|
||||||
|
|
||||||
|
const api = useApi() as any
|
||||||
|
const response = await api.get(`/admin/customer-groups`, adminHeaders)
|
||||||
|
|
||||||
|
expect(response.status).toEqual(200)
|
||||||
|
expect(response.data.count).toEqual(1)
|
||||||
|
expect(response.data.groups).toEqual([
|
||||||
|
expect.objectContaining({
|
||||||
|
id: expect.any(String),
|
||||||
|
name: "Test",
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
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 adminSeeder from "../../../../helpers/admin-seeder"
|
||||||
|
|
||||||
|
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
||||||
|
const adminHeaders = {
|
||||||
|
headers: { "x-medusa-access-token": "test_token" },
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("GET /admin/customers", () => {
|
||||||
|
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()
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await adminSeeder(dbConnection)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.teardown()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should get all customers and its count", async () => {
|
||||||
|
await customerModuleService.create([
|
||||||
|
{
|
||||||
|
first_name: "Test",
|
||||||
|
last_name: "Test",
|
||||||
|
email: "test@me.com",
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
const api = useApi() as any
|
||||||
|
const response = await api.get(`/admin/customers`, adminHeaders)
|
||||||
|
|
||||||
|
expect(response.status).toEqual(200)
|
||||||
|
expect(response.data.count).toEqual(1)
|
||||||
|
expect(response.data.customers).toEqual([
|
||||||
|
expect.objectContaining({
|
||||||
|
id: expect.any(String),
|
||||||
|
first_name: "Test",
|
||||||
|
last_name: "Test",
|
||||||
|
email: "test@me.com",
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should filter customers by last name", async () => {
|
||||||
|
await customerModuleService.create([
|
||||||
|
{
|
||||||
|
first_name: "Jane",
|
||||||
|
last_name: "Doe",
|
||||||
|
email: "jane@me.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
first_name: "John",
|
||||||
|
last_name: "Doe",
|
||||||
|
email: "john@me.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
first_name: "LeBron",
|
||||||
|
last_name: "James",
|
||||||
|
email: "lebron@me.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
first_name: "John",
|
||||||
|
last_name: "Silver",
|
||||||
|
email: "johns@me.com",
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
const api = useApi() as any
|
||||||
|
const response = await api.get(
|
||||||
|
`/admin/customers?last_name=Doe`,
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.status).toEqual(200)
|
||||||
|
expect(response.data.count).toEqual(2)
|
||||||
|
expect(response.data.customers).toContainEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: expect.any(String),
|
||||||
|
first_name: "Jane",
|
||||||
|
last_name: "Doe",
|
||||||
|
email: "jane@me.com",
|
||||||
|
})
|
||||||
|
)
|
||||||
|
expect(response.data.customers).toContainEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: expect.any(String),
|
||||||
|
first_name: "John",
|
||||||
|
last_name: "Doe",
|
||||||
|
email: "john@me.com",
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -71,6 +71,11 @@ module.exports = {
|
|||||||
resources: "shared",
|
resources: "shared",
|
||||||
resolve: "@medusajs/promotion",
|
resolve: "@medusajs/promotion",
|
||||||
},
|
},
|
||||||
|
[Modules.CUSTOMER]: {
|
||||||
|
scope: "internal",
|
||||||
|
resources: "shared",
|
||||||
|
resolve: "@medusajs/customer",
|
||||||
|
},
|
||||||
[Modules.SALES_CHANNEL]: {
|
[Modules.SALES_CHANNEL]: {
|
||||||
scope: "internal",
|
scope: "internal",
|
||||||
resources: "shared",
|
resources: "shared",
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@medusajs/cache-inmemory": "workspace:*",
|
"@medusajs/cache-inmemory": "workspace:*",
|
||||||
|
"@medusajs/customer": "workspace:^",
|
||||||
"@medusajs/event-bus-local": "workspace:*",
|
"@medusajs/event-bus-local": "workspace:*",
|
||||||
"@medusajs/inventory": "workspace:^",
|
"@medusajs/inventory": "workspace:^",
|
||||||
"@medusajs/medusa": "workspace:*",
|
"@medusajs/medusa": "workspace:*",
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
"@models": ["./src/models"],
|
"@models": ["./src/models"],
|
||||||
"@services": ["./src/services"],
|
"@services": ["./src/services"],
|
||||||
"@repositories": ["./src/repositories"],
|
"@repositories": ["./src/repositories"],
|
||||||
"@types": ["./src/types"],
|
"@types": ["./src/types"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": ["src"],
|
"include": ["src"],
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import { MedusaV2Flag } from "@medusajs/utils"
|
||||||
|
|
||||||
|
import {
|
||||||
|
isFeatureFlagEnabled,
|
||||||
|
transformBody,
|
||||||
|
transformQuery,
|
||||||
|
} from "../../../api/middlewares"
|
||||||
|
import { MiddlewareRoute } from "../../../loaders/helpers/routing/types"
|
||||||
|
import * as QueryConfig from "./query-config"
|
||||||
|
import {
|
||||||
|
AdminGetCustomerGroupsParams,
|
||||||
|
AdminGetCustomerGroupsGroupParams,
|
||||||
|
AdminPostCustomerGroupsReq,
|
||||||
|
AdminPostCustomerGroupsGroupReq,
|
||||||
|
} from "./validators"
|
||||||
|
|
||||||
|
export const adminCustomerGroupRoutesMiddlewares: MiddlewareRoute[] = [
|
||||||
|
{
|
||||||
|
matcher: "/admin/customer-groups*",
|
||||||
|
middlewares: [isFeatureFlagEnabled(MedusaV2Flag.key)],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: ["GET"],
|
||||||
|
matcher: "/admin/customer-groups",
|
||||||
|
middlewares: [
|
||||||
|
transformQuery(
|
||||||
|
AdminGetCustomerGroupsParams,
|
||||||
|
QueryConfig.listTransformQueryConfig
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: ["GET"],
|
||||||
|
matcher: "/admin/customer-groups/:id",
|
||||||
|
middlewares: [
|
||||||
|
transformQuery(
|
||||||
|
AdminGetCustomerGroupsGroupParams,
|
||||||
|
QueryConfig.retrieveTransformQueryConfig
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: ["POST"],
|
||||||
|
matcher: "/admin/customer-groups",
|
||||||
|
middlewares: [transformBody(AdminPostCustomerGroupsReq)],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: ["POST"],
|
||||||
|
matcher: "/admin/customer-groups/:id",
|
||||||
|
middlewares: [transformBody(AdminPostCustomerGroupsGroupReq)],
|
||||||
|
},
|
||||||
|
]
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
export const defaultAdminCustomerGroupRelations = []
|
||||||
|
export const allowedAdminCustomerGroupRelations = ["customers"]
|
||||||
|
export const defaultAdminCustomerGroupFields = [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"deleted_at",
|
||||||
|
]
|
||||||
|
|
||||||
|
export const retrieveTransformQueryConfig = {
|
||||||
|
defaultFields: defaultAdminCustomerGroupFields,
|
||||||
|
defaultRelations: defaultAdminCustomerGroupRelations,
|
||||||
|
allowedRelations: allowedAdminCustomerGroupRelations,
|
||||||
|
isList: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const listTransformQueryConfig = {
|
||||||
|
...retrieveTransformQueryConfig,
|
||||||
|
isList: true,
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { ICustomerModuleService } from "@medusajs/types"
|
||||||
|
import { MedusaRequest, MedusaResponse } from "../../../types/routing"
|
||||||
|
|
||||||
|
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||||
|
const customerModuleService = req.scope.resolve<ICustomerModuleService>(
|
||||||
|
ModuleRegistrationName.CUSTOMER
|
||||||
|
)
|
||||||
|
|
||||||
|
const [groups, count] =
|
||||||
|
await customerModuleService.listAndCountCustomerGroups(
|
||||||
|
req.filterableFields,
|
||||||
|
req.listConfig
|
||||||
|
)
|
||||||
|
|
||||||
|
const { offset, limit } = req.validatedQuery
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
count,
|
||||||
|
groups,
|
||||||
|
offset,
|
||||||
|
limit,
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
import { OperatorMap } from "@medusajs/types"
|
||||||
|
import { Type } from "class-transformer"
|
||||||
|
import {
|
||||||
|
IsNotEmpty,
|
||||||
|
IsOptional,
|
||||||
|
IsString,
|
||||||
|
ValidateNested,
|
||||||
|
} from "class-validator"
|
||||||
|
import { FindParams, extendedFindParamsMixin } from "../../../types/common"
|
||||||
|
import { OperatorMapValidator } from "../../../types/validators/operator-map"
|
||||||
|
|
||||||
|
export class AdminGetCustomerGroupsGroupParams extends FindParams {}
|
||||||
|
|
||||||
|
class FilterableCustomerPropsValidator {
|
||||||
|
@IsOptional()
|
||||||
|
@IsString({ each: true })
|
||||||
|
id?: string | string[]
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@ValidateNested({ each: true })
|
||||||
|
@Type(() => OperatorMapValidator)
|
||||||
|
email?: string | string[] | OperatorMap<string>
|
||||||
|
|
||||||
|
@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<string> | null
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString({ each: true })
|
||||||
|
first_name?: string | string[] | OperatorMap<string> | null
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString({ each: true })
|
||||||
|
last_name?: string | string[] | OperatorMap<string> | null
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString({ each: true })
|
||||||
|
created_by?: string | string[] | null
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@ValidateNested()
|
||||||
|
@Type(() => OperatorMapValidator)
|
||||||
|
created_at?: OperatorMap<string>
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@ValidateNested()
|
||||||
|
@Type(() => OperatorMapValidator)
|
||||||
|
updated_at?: OperatorMap<string>
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AdminGetCustomerGroupsParams extends extendedFindParamsMixin({
|
||||||
|
limit: 100,
|
||||||
|
offset: 0,
|
||||||
|
}) {
|
||||||
|
@IsOptional()
|
||||||
|
@IsString({ each: true })
|
||||||
|
id?: string | string[]
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@ValidateNested({ each: true })
|
||||||
|
@Type(() => OperatorMapValidator)
|
||||||
|
name?: string | OperatorMap<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<string>
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@ValidateNested()
|
||||||
|
@Type(() => OperatorMapValidator)
|
||||||
|
updated_at?: OperatorMap<string>
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
import { MedusaV2Flag } from "@medusajs/utils"
|
||||||
|
|
||||||
|
import {
|
||||||
|
isFeatureFlagEnabled,
|
||||||
|
transformBody,
|
||||||
|
transformQuery,
|
||||||
|
} from "../../../api/middlewares"
|
||||||
|
import { MiddlewareRoute } from "../../../loaders/helpers/routing/types"
|
||||||
|
import * as QueryConfig from "./query-config"
|
||||||
|
import {
|
||||||
|
AdminGetCustomersParams,
|
||||||
|
AdminGetCustomersCustomerParams,
|
||||||
|
AdminPostCustomersCustomerReq,
|
||||||
|
} from "./validators"
|
||||||
|
|
||||||
|
export const adminCustomerRoutesMiddlewares: MiddlewareRoute[] = [
|
||||||
|
{
|
||||||
|
matcher: "/admin/customers*",
|
||||||
|
middlewares: [isFeatureFlagEnabled(MedusaV2Flag.key)],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: ["GET"],
|
||||||
|
matcher: "/admin/customers",
|
||||||
|
middlewares: [
|
||||||
|
transformQuery(
|
||||||
|
AdminGetCustomersParams,
|
||||||
|
QueryConfig.listTransformQueryConfig
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: ["GET"],
|
||||||
|
matcher: "/admin/customers/:id",
|
||||||
|
middlewares: [
|
||||||
|
transformQuery(
|
||||||
|
AdminGetCustomersCustomerParams,
|
||||||
|
QueryConfig.retrieveTransformQueryConfig
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: ["POST"],
|
||||||
|
matcher: "/admin/customers/:id",
|
||||||
|
middlewares: [transformBody(AdminPostCustomersCustomerReq)],
|
||||||
|
},
|
||||||
|
]
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
export const defaultAdminCustomerRelations = []
|
||||||
|
export const allowedAdminCustomerRelations = [
|
||||||
|
"groups",
|
||||||
|
"default_shipping_address",
|
||||||
|
"default_billing_address",
|
||||||
|
"addresses",
|
||||||
|
]
|
||||||
|
export const defaultAdminCustomerFields = [
|
||||||
|
"id",
|
||||||
|
"company_name",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"email",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"deleted_at",
|
||||||
|
]
|
||||||
|
|
||||||
|
export const retrieveTransformQueryConfig = {
|
||||||
|
defaultFields: defaultAdminCustomerFields,
|
||||||
|
defaultRelations: defaultAdminCustomerRelations,
|
||||||
|
allowedRelations: allowedAdminCustomerRelations,
|
||||||
|
isList: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const listTransformQueryConfig = {
|
||||||
|
...retrieveTransformQueryConfig,
|
||||||
|
isList: true,
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { ICustomerModuleService } from "@medusajs/types"
|
||||||
|
import { MedusaRequest, MedusaResponse } from "../../../types/routing"
|
||||||
|
|
||||||
|
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||||
|
const customerModuleService = req.scope.resolve<ICustomerModuleService>(
|
||||||
|
ModuleRegistrationName.CUSTOMER
|
||||||
|
)
|
||||||
|
|
||||||
|
const [customers, count] = await customerModuleService.listAndCount(
|
||||||
|
req.filterableFields,
|
||||||
|
req.listConfig
|
||||||
|
)
|
||||||
|
|
||||||
|
const { offset, limit } = req.validatedQuery
|
||||||
|
|
||||||
|
// TODO: Replace with remote query
|
||||||
|
//const remoteQuery = req.scope.resolve("remoteQuery")
|
||||||
|
|
||||||
|
//const variables = {
|
||||||
|
// filters: req.filterableFields,
|
||||||
|
// order: req.listConfig.order,
|
||||||
|
// skip: req.listConfig.skip,
|
||||||
|
// take: req.listConfig.take,
|
||||||
|
//}
|
||||||
|
|
||||||
|
//const query = remoteQueryObjectFromString({
|
||||||
|
// entryPoint: "customer",
|
||||||
|
// variables,
|
||||||
|
// fields: [...req.listConfig.select!, ...req.listConfig.relations!],
|
||||||
|
//})
|
||||||
|
|
||||||
|
//const results = await remoteQuery(query)
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
count,
|
||||||
|
customers,
|
||||||
|
offset,
|
||||||
|
limit,
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
import { OperatorMap } from "@medusajs/types"
|
||||||
|
import { Transform, Type } from "class-transformer"
|
||||||
|
import {
|
||||||
|
IsNotEmpty,
|
||||||
|
IsOptional,
|
||||||
|
IsString,
|
||||||
|
ValidateNested,
|
||||||
|
} from "class-validator"
|
||||||
|
import { FindParams, extendedFindParamsMixin } from "../../../types/common"
|
||||||
|
import { OperatorMapValidator } from "../../../types/validators/operator-map"
|
||||||
|
import { IsType } from "../../../utils"
|
||||||
|
|
||||||
|
export class AdminGetCustomersCustomerParams extends FindParams {}
|
||||||
|
|
||||||
|
export class AdminGetCustomersParams extends extendedFindParamsMixin({
|
||||||
|
limit: 100,
|
||||||
|
offset: 0,
|
||||||
|
}) {
|
||||||
|
@IsOptional()
|
||||||
|
@IsString({ each: true })
|
||||||
|
id?: string | string[]
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsType([String, [String], OperatorMapValidator])
|
||||||
|
email?: string | string[] | OperatorMap<string>
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@ValidateNested()
|
||||||
|
@Type(() => FilterableCustomerGroupPropsValidator)
|
||||||
|
groups?: FilterableCustomerGroupPropsValidator | string | string[]
|
||||||
|
|
||||||
|
@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<string> | null
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString({ each: true })
|
||||||
|
first_name?: string | string[] | OperatorMap<string> | null
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsType([String, [String], OperatorMapValidator])
|
||||||
|
@Transform(({ value }) => (value === "null" ? null : value))
|
||||||
|
last_name?: string | string[] | OperatorMap<string> | null
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString({ each: true })
|
||||||
|
created_by?: string | string[] | null
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@ValidateNested()
|
||||||
|
@Type(() => OperatorMapValidator)
|
||||||
|
created_at?: OperatorMap<string>
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@ValidateNested()
|
||||||
|
@Type(() => OperatorMapValidator)
|
||||||
|
updated_at?: OperatorMap<string>
|
||||||
|
|
||||||
|
// Additional filters from BaseFilterable
|
||||||
|
@IsOptional()
|
||||||
|
@ValidateNested({ each: true })
|
||||||
|
@Type(() => AdminGetCustomersParams)
|
||||||
|
$and?: AdminGetCustomersParams[]
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@ValidateNested({ each: true })
|
||||||
|
@Type(() => AdminGetCustomersParams)
|
||||||
|
$or?: AdminGetCustomersParams[]
|
||||||
|
}
|
||||||
|
|
||||||
|
class FilterableCustomerGroupPropsValidator {
|
||||||
|
@IsOptional()
|
||||||
|
@IsString({ each: true })
|
||||||
|
id?: string | string[]
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@ValidateNested({ each: true })
|
||||||
|
@Type(() => OperatorMapValidator)
|
||||||
|
name?: string | OperatorMap<string>
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString({ each: true })
|
||||||
|
created_by?: string | string[] | null
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@ValidateNested()
|
||||||
|
@Type(() => OperatorMapValidator)
|
||||||
|
created_at?: OperatorMap<string>
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@ValidateNested()
|
||||||
|
@Type(() => OperatorMapValidator)
|
||||||
|
updated_at?: OperatorMap<string>
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AdminPostCustomersReq {
|
||||||
|
@IsNotEmpty()
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
company_name?: string
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
first_name?: string
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
last_name?: string
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
email?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AdminPostCustomersCustomerReq {
|
||||||
|
@IsNotEmpty()
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
company_name?: string
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
first_name?: string
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
last_name?: string
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
email?: string
|
||||||
|
}
|
||||||
@@ -1,9 +1,13 @@
|
|||||||
import { MiddlewaresConfig } from "../loaders/helpers/routing/types"
|
import { MiddlewaresConfig } from "../loaders/helpers/routing/types"
|
||||||
import { adminCampaignRoutesMiddlewares } from "./admin/campaigns/middlewares"
|
import { adminCampaignRoutesMiddlewares } from "./admin/campaigns/middlewares"
|
||||||
import { adminPromotionRoutesMiddlewares } from "./admin/promotions/middlewares"
|
import { adminPromotionRoutesMiddlewares } from "./admin/promotions/middlewares"
|
||||||
|
import { adminCustomerRoutesMiddlewares } from "./admin/customers/middlewares"
|
||||||
|
import { adminCustomerGroupRoutesMiddlewares } from "./admin/customer-groups/middlewares"
|
||||||
|
|
||||||
export const config: MiddlewaresConfig = {
|
export const config: MiddlewaresConfig = {
|
||||||
routes: [
|
routes: [
|
||||||
|
...adminCustomerGroupRoutesMiddlewares,
|
||||||
|
...adminCustomerRoutesMiddlewares,
|
||||||
...adminPromotionRoutesMiddlewares,
|
...adminPromotionRoutesMiddlewares,
|
||||||
...adminCampaignRoutesMiddlewares,
|
...adminCampaignRoutesMiddlewares,
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
import { IsArray, IsBoolean, IsOptional, IsString } from "class-validator"
|
||||||
|
|
||||||
|
export class OperatorMapValidator {
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
$eq?: string | string[]
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
$ne?: string
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsArray()
|
||||||
|
$in?: string[]
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsArray()
|
||||||
|
$nin?: string[]
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
$like?: string
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
$re?: string
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
$ilike?: string
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
$fulltext?: string
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsArray()
|
||||||
|
$overlap?: string[]
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
$contains?: string
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsArray()
|
||||||
|
$contained?: string[]
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
|
$exists?: boolean
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
$gt?: string
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
$gte?: string
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
$lt?: string
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
$lte?: string
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Dictionary, FilterQuery, Order } from "./utils"
|
import { Dictionary, FilterQuery, Order } from "./utils"
|
||||||
|
|
||||||
export { FilterQuery } from "./utils"
|
export { FilterQuery, OperatorMap } from "./utils"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @interface
|
* @interface
|
||||||
|
|||||||
@@ -8009,7 +8009,7 @@ __metadata:
|
|||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
"@medusajs/customer@workspace:packages/customer":
|
"@medusajs/customer@workspace:^, @medusajs/customer@workspace:packages/customer":
|
||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@medusajs/customer@workspace:packages/customer"
|
resolution: "@medusajs/customer@workspace:packages/customer"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -31378,6 +31378,7 @@ __metadata:
|
|||||||
"@babel/core": ^7.12.10
|
"@babel/core": ^7.12.10
|
||||||
"@babel/node": ^7.12.10
|
"@babel/node": ^7.12.10
|
||||||
"@medusajs/cache-inmemory": "workspace:*"
|
"@medusajs/cache-inmemory": "workspace:*"
|
||||||
|
"@medusajs/customer": "workspace:^"
|
||||||
"@medusajs/event-bus-local": "workspace:*"
|
"@medusajs/event-bus-local": "workspace:*"
|
||||||
"@medusajs/inventory": "workspace:^"
|
"@medusajs/inventory": "workspace:^"
|
||||||
"@medusajs/medusa": "workspace:*"
|
"@medusajs/medusa": "workspace:*"
|
||||||
|
|||||||
Reference in new issue
Block a user