feat: Add support for search to all endpoints (#7149)
* feat: Add search capability to api keys * feat: Add support for searching to currency and customer endpoints * fix: Clean up product search filters * feat: Add search support to regions * feat: Add search support to sales channels * feat: Add search support to store module * feat: Add search support to user module * fix: Clean up inventory search * feat: Add search support for payments * fix: Add searchable attributes to stock location models * feat: Add search support to tax * feat: Add search support to promotions * feat: Add search support for pricing, filtering cleanup * fix: Further cleanups around search
This commit is contained in:
@@ -85,6 +85,43 @@ medusaIntegrationTestRunner({
|
||||
expect(listedApiKeys.data.api_keys).toHaveLength(0)
|
||||
})
|
||||
|
||||
it("should allow searching for api keys", async () => {
|
||||
await api.post(
|
||||
`/admin/api-keys`,
|
||||
{
|
||||
title: "Test Secret Key",
|
||||
type: ApiKeyType.SECRET,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
await api.post(
|
||||
`/admin/api-keys`,
|
||||
{
|
||||
title: "Test Publishable Key",
|
||||
type: ApiKeyType.PUBLISHABLE,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
const listedSecretKeys = await api.get(
|
||||
`/admin/api-keys?q=Secret`,
|
||||
adminHeaders
|
||||
)
|
||||
const listedPublishableKeys = await api.get(
|
||||
`/admin/api-keys?q=Publish`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(listedSecretKeys.data.api_keys).toHaveLength(1)
|
||||
expect(listedSecretKeys.data.api_keys[0].title).toEqual(
|
||||
"Test Secret Key"
|
||||
)
|
||||
expect(listedPublishableKeys.data.api_keys).toHaveLength(1)
|
||||
expect(listedPublishableKeys.data.api_keys[0].title).toEqual(
|
||||
"Test Publishable Key"
|
||||
)
|
||||
})
|
||||
|
||||
it("can use a secret api key for authentication", async () => {
|
||||
const created = await api.post(
|
||||
`/admin/api-keys`,
|
||||
|
||||
@@ -1948,6 +1948,46 @@ medusaIntegrationTestRunner({
|
||||
])
|
||||
)
|
||||
})
|
||||
|
||||
it("should allow searching of variants", async () => {
|
||||
await breaking(
|
||||
() => {},
|
||||
async () => {
|
||||
const newProduct = (
|
||||
await api.post(
|
||||
"/admin/products",
|
||||
getProductFixture({
|
||||
variants: [
|
||||
{ title: "First variant", prices: [] },
|
||||
{ title: "Second variant", prices: [] },
|
||||
],
|
||||
}),
|
||||
adminHeaders
|
||||
)
|
||||
).data.product
|
||||
|
||||
const res = await api
|
||||
.get(
|
||||
`/admin/products/${newProduct.id}/variants?q=first`,
|
||||
adminHeaders
|
||||
)
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
|
||||
expect(res.status).toEqual(200)
|
||||
expect(res.data.variants).toHaveLength(1)
|
||||
expect(res.data.variants).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
title: "First variant",
|
||||
product_id: newProduct.id,
|
||||
}),
|
||||
])
|
||||
)
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("updates a variant's default prices (ignores prices associated with a Price List)", () => {
|
||||
|
||||
@@ -157,40 +157,30 @@ medusaIntegrationTestRunner({
|
||||
})
|
||||
|
||||
it("should list the sales channel using filters", async () => {
|
||||
const response = await breaking(
|
||||
async () => {
|
||||
return await api.get(`/admin/sales-channels?q=2`, adminReqConfig)
|
||||
},
|
||||
() => undefined
|
||||
const response = await api.get(
|
||||
`/admin/sales-channels?q=2`,
|
||||
adminReqConfig
|
||||
)
|
||||
|
||||
breaking(
|
||||
() => {
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.sales_channels).toBeTruthy()
|
||||
expect(response.data.sales_channels.length).toBe(1)
|
||||
expect(response.data).toEqual({
|
||||
count: 1,
|
||||
limit: 20,
|
||||
offset: 0,
|
||||
sales_channels: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
name: salesChannel2.name,
|
||||
description: salesChannel2.description,
|
||||
is_disabled: false,
|
||||
deleted_at: null,
|
||||
created_at: expect.any(String),
|
||||
updated_at: expect.any(String),
|
||||
}),
|
||||
]),
|
||||
})
|
||||
},
|
||||
() => {
|
||||
// TODO: Free text search is not supported in the new sales channel API (yet)
|
||||
expect(response).toBeUndefined()
|
||||
}
|
||||
)
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.sales_channels).toBeTruthy()
|
||||
expect(response.data.sales_channels.length).toBe(1)
|
||||
expect(response.data).toEqual({
|
||||
count: 1,
|
||||
limit: 20,
|
||||
offset: 0,
|
||||
sales_channels: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
name: salesChannel2.name,
|
||||
description: salesChannel2.description,
|
||||
is_disabled: false,
|
||||
deleted_at: null,
|
||||
created_at: expect.any(String),
|
||||
updated_at: expect.any(String),
|
||||
}),
|
||||
]),
|
||||
})
|
||||
})
|
||||
|
||||
it("should list the sales channel using properties filters", async () => {
|
||||
@@ -219,6 +209,37 @@ medusaIntegrationTestRunner({
|
||||
]),
|
||||
})
|
||||
})
|
||||
|
||||
it("should support searching of sales channels", async () => {
|
||||
await breaking(
|
||||
() => {},
|
||||
async () => {
|
||||
await api.post(
|
||||
"/admin/sales-channels",
|
||||
{ name: "first channel", description: "to fetch" },
|
||||
adminReqConfig
|
||||
)
|
||||
|
||||
await api.post(
|
||||
"/admin/sales-channels",
|
||||
{ name: "second channel", description: "not in response" },
|
||||
adminReqConfig
|
||||
)
|
||||
|
||||
const response = await api.get(
|
||||
`/admin/sales-channels?q=fetch`,
|
||||
adminReqConfig
|
||||
)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.sales_channels).toEqual([
|
||||
expect.objectContaining({
|
||||
name: "first channel",
|
||||
}),
|
||||
])
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("POST /admin/sales-channels/:id", () => {
|
||||
|
||||
@@ -50,7 +50,11 @@ medusaIntegrationTestRunner({
|
||||
() =>
|
||||
api
|
||||
.get("/admin/stores", adminHeaders)
|
||||
.then((r) => r.data.stores[0])
|
||||
.then((r) =>
|
||||
r.data.stores.find(
|
||||
(s) => s.default_sales_channel_id === "sc_12345"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
expect(store).toEqual(
|
||||
@@ -245,6 +249,35 @@ medusaIntegrationTestRunner({
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("GET /admin/store", () => {
|
||||
it("supports searching of stores", async () => {
|
||||
await breaking(
|
||||
() => {},
|
||||
async () => {
|
||||
const service = container.resolve(ModuleRegistrationName.STORE)
|
||||
const secondStore = await service.create({
|
||||
name: "Second Store",
|
||||
supported_currency_codes: ["eur"],
|
||||
default_currency_code: "eur",
|
||||
})
|
||||
|
||||
const response = await api.get(
|
||||
"/admin/stores?q=second",
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.stores).toEqual([
|
||||
expect.objectContaining({
|
||||
id: secondStore.id,
|
||||
name: "Second Store",
|
||||
}),
|
||||
])
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
@@ -143,7 +143,6 @@ medusaIntegrationTestRunner({
|
||||
)
|
||||
})
|
||||
|
||||
// TODO: Free text search not supported in 2.0 yet
|
||||
it("should list users that match the free text search", async () => {
|
||||
const response = await api.get("/admin/users?q=member", adminHeaders)
|
||||
|
||||
@@ -159,7 +158,10 @@ medusaIntegrationTestRunner({
|
||||
last_name: "user",
|
||||
created_at: expect.any(String),
|
||||
updated_at: expect.any(String),
|
||||
role: "member",
|
||||
...breaking(
|
||||
() => ({ role: "member" }),
|
||||
() => ({})
|
||||
),
|
||||
}),
|
||||
])
|
||||
)
|
||||
|
||||
@@ -53,6 +53,18 @@ medusaIntegrationTestRunner({
|
||||
expect.objectContaining({ code: "zwl", name: "Zimbabwean Dollar" })
|
||||
)
|
||||
})
|
||||
|
||||
it("should allow for searching of currencies", async () => {
|
||||
const listResp = await api.get(
|
||||
"/admin/currencies?q=zimbabwean",
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(listResp.data.currencies).toHaveLength(1)
|
||||
expect(listResp.data.currencies[0]).toEqual(
|
||||
expect.objectContaining({ code: "zwl", name: "Zimbabwean Dollar" })
|
||||
)
|
||||
})
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
@@ -44,6 +44,29 @@ medusaIntegrationTestRunner({
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
it("should support searching of customer groups", async () => {
|
||||
await customerModuleService.createCustomerGroup([
|
||||
{
|
||||
name: "First group",
|
||||
},
|
||||
{ name: "Second group" },
|
||||
])
|
||||
|
||||
const response = await api.get(
|
||||
`/admin/customer-groups?q=fir`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.customer_groups).toHaveLength(1)
|
||||
expect(response.data.customer_groups[0]).toEqual(
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
name: "First group",
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
@@ -92,6 +92,53 @@ medusaIntegrationTestRunner({
|
||||
])
|
||||
)
|
||||
})
|
||||
|
||||
it("should support searching through the addresses", async () => {
|
||||
const [customer] = await customerModuleService.create([
|
||||
{
|
||||
first_name: "Test",
|
||||
last_name: "Test",
|
||||
email: "test@me.com",
|
||||
addresses: [
|
||||
{
|
||||
first_name: "John",
|
||||
last_name: "Doe",
|
||||
address_1: "Huntingdon 123",
|
||||
},
|
||||
{
|
||||
first_name: "Jane",
|
||||
last_name: "Doe",
|
||||
address_1: "Horseshoe 555",
|
||||
},
|
||||
{
|
||||
first_name: "Jack",
|
||||
last_name: "Doe",
|
||||
address_1: "Hawkins 12",
|
||||
},
|
||||
],
|
||||
},
|
||||
])
|
||||
|
||||
const response = await api.get(
|
||||
`/admin/customers/${customer.id}/addresses?q=12`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.addresses).toHaveLength(2)
|
||||
expect(response.data.addresses).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
address_1: "Huntingdon 123",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
address_1: "Hawkins 12",
|
||||
}),
|
||||
])
|
||||
)
|
||||
})
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
@@ -141,6 +141,43 @@ medusaIntegrationTestRunner({
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should support searching of customers", 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",
|
||||
},
|
||||
])
|
||||
|
||||
const response = await api.get(`/admin/customers?q=do`, adminHeaders)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.customers).toHaveLength(2)
|
||||
expect(response.data.customers).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
first_name: "Jane",
|
||||
last_name: "Doe",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
first_name: "John",
|
||||
last_name: "Doe",
|
||||
}),
|
||||
])
|
||||
)
|
||||
})
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
@@ -162,6 +162,71 @@ medusaIntegrationTestRunner({
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
it("should support searching of price lists", async () => {
|
||||
const priceSet = await createVariantPriceSet({
|
||||
container: appContainer,
|
||||
variantId: variant.id,
|
||||
prices: [],
|
||||
})
|
||||
|
||||
await pricingModule.createPriceLists([
|
||||
{
|
||||
title: "first price list",
|
||||
description: "test price",
|
||||
ends_at: new Date(),
|
||||
starts_at: new Date(),
|
||||
status: PriceListStatus.ACTIVE,
|
||||
type: PriceListType.OVERRIDE,
|
||||
prices: [
|
||||
{
|
||||
amount: 5000,
|
||||
currency_code: "usd",
|
||||
price_set_id: priceSet.id,
|
||||
rules: {
|
||||
region_id: region.id,
|
||||
},
|
||||
},
|
||||
],
|
||||
rules: {
|
||||
customer_group_id: [customerGroup.id],
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "second price list",
|
||||
description: "second test",
|
||||
ends_at: new Date(),
|
||||
starts_at: new Date(),
|
||||
status: PriceListStatus.ACTIVE,
|
||||
type: PriceListType.OVERRIDE,
|
||||
prices: [
|
||||
{
|
||||
amount: 5000,
|
||||
currency_code: "usd",
|
||||
price_set_id: priceSet.id,
|
||||
rules: {
|
||||
region_id: region.id,
|
||||
},
|
||||
},
|
||||
],
|
||||
rules: {
|
||||
customer_group_id: [customerGroup.id],
|
||||
},
|
||||
},
|
||||
])
|
||||
|
||||
let response = await api.get(
|
||||
`/admin/price-lists?q=second`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.price_lists).toEqual([
|
||||
expect.objectContaining({
|
||||
title: "second price list",
|
||||
}),
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
describe("GET /admin/price-lists/:id", () => {
|
||||
|
||||
@@ -130,6 +130,20 @@ medusaIntegrationTestRunner({
|
||||
)
|
||||
})
|
||||
|
||||
it("should support search on campaigns", async () => {
|
||||
const response = await api.get(
|
||||
`/admin/campaigns?q=ign%202`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.campaigns).toEqual([
|
||||
expect.objectContaining({
|
||||
name: "campaign 2",
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
it("should get all campaigns and its count filtered", async () => {
|
||||
const response = await api.get(
|
||||
`/admin/campaigns?fields=name,created_at,budget.id`,
|
||||
|
||||
@@ -67,6 +67,38 @@ medusaIntegrationTestRunner({
|
||||
])
|
||||
})
|
||||
|
||||
it("should support search of promotions", async () => {
|
||||
await promotionModuleService.create([
|
||||
{
|
||||
code: "first",
|
||||
type: PromotionType.STANDARD,
|
||||
application_method: {
|
||||
type: "fixed",
|
||||
target_type: "order",
|
||||
value: 100,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: "second",
|
||||
type: PromotionType.STANDARD,
|
||||
application_method: {
|
||||
type: "fixed",
|
||||
target_type: "order",
|
||||
value: 100,
|
||||
},
|
||||
},
|
||||
])
|
||||
|
||||
const response = await api.get(`/admin/promotions?q=fir`, adminHeaders)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.promotions).toEqual([
|
||||
expect.objectContaining({
|
||||
code: "first",
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
it("should get all promotions and its count filtered", async () => {
|
||||
await promotionModuleService.create([
|
||||
{
|
||||
|
||||
@@ -343,6 +343,31 @@ medusaIntegrationTestRunner({
|
||||
])
|
||||
})
|
||||
|
||||
it("should support searching of regions", async () => {
|
||||
await service.create([
|
||||
{
|
||||
name: "APAC",
|
||||
currency_code: "usd",
|
||||
countries: ["jp"],
|
||||
},
|
||||
{
|
||||
name: "Europe",
|
||||
currency_code: "eur",
|
||||
countries: ["de"],
|
||||
},
|
||||
])
|
||||
|
||||
const response = await api.get(`/admin/regions?q=eu`, adminHeaders)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.regions).toEqual([
|
||||
expect.objectContaining({
|
||||
name: "Europe",
|
||||
currency_code: "eur",
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
it("should get a region", async () => {
|
||||
const [region] = await service.create([
|
||||
{
|
||||
|
||||
@@ -64,6 +64,33 @@ medusaIntegrationTestRunner({
|
||||
})
|
||||
})
|
||||
|
||||
it("can search through tax rates", async () => {
|
||||
const region = await service.createTaxRegions({
|
||||
country_code: "us",
|
||||
})
|
||||
|
||||
await service.create({
|
||||
tax_region_id: region.id,
|
||||
code: "low",
|
||||
rate: 2.5,
|
||||
name: "low rate",
|
||||
})
|
||||
|
||||
await service.create({
|
||||
tax_region_id: region.id,
|
||||
code: "high",
|
||||
rate: 5,
|
||||
name: "high rate",
|
||||
})
|
||||
|
||||
const response = await api.get(`/admin/tax-rates?q=high`, adminHeaders)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.tax_rates).toEqual(
|
||||
expect.arrayContaining([expect.objectContaining({ code: "high" })])
|
||||
)
|
||||
})
|
||||
|
||||
it("can create a tax region with rates and rules", async () => {
|
||||
const regionRes = await api.post(
|
||||
`/admin/tax-regions`,
|
||||
@@ -402,6 +429,31 @@ medusaIntegrationTestRunner({
|
||||
})
|
||||
})
|
||||
|
||||
it("can search through tax regions", async () => {
|
||||
await service.createTaxRegions([
|
||||
{
|
||||
country_code: "us",
|
||||
province_code: "texas",
|
||||
},
|
||||
{
|
||||
country_code: "us",
|
||||
province_code: "florida",
|
||||
},
|
||||
])
|
||||
|
||||
const response = await api.get(`/admin/tax-regions?q=ida`, adminHeaders)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.tax_regions).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
country_code: "us",
|
||||
province_code: "florida",
|
||||
}),
|
||||
])
|
||||
)
|
||||
})
|
||||
|
||||
it("can create a tax region and delete it", async () => {
|
||||
const regionRes = await api.post(
|
||||
`/admin/tax-regions`,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
Searchable,
|
||||
createPsqlIndexStatementHelper,
|
||||
generateEntityId,
|
||||
} from "@medusajs/utils"
|
||||
@@ -35,9 +36,11 @@ export default class ApiKey {
|
||||
@Property({ columnType: "text" })
|
||||
salt: string
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text" })
|
||||
redacted: string
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text" })
|
||||
title: string
|
||||
|
||||
|
||||
@@ -443,6 +443,10 @@ export default class ApiKeyModuleService<TEntity extends ApiKey = ApiKey>
|
||||
|
||||
// There can only be 2 secret keys at most, and one has to be with a revoked_at date set, so only 1 can be newly created.
|
||||
const secretKeysToCreate = data.filter((k) => k.type === ApiKeyType.SECRET)
|
||||
if (!secretKeysToCreate.length) {
|
||||
return
|
||||
}
|
||||
|
||||
if (secretKeysToCreate.length > 1) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { DAL } from "@medusajs/types"
|
||||
import { generateEntityId } from "@medusajs/utils"
|
||||
import { Searchable, generateEntityId } from "@medusajs/utils"
|
||||
import {
|
||||
BeforeCreate,
|
||||
Cascade,
|
||||
@@ -37,6 +37,7 @@ export default class Address {
|
||||
@PrimaryKey({ columnType: "text" })
|
||||
id!: string
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
address_name: string | null = null
|
||||
|
||||
@@ -56,30 +57,38 @@ export default class Address {
|
||||
})
|
||||
customer: Customer
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
company: string | null = null
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
first_name: string | null = null
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
last_name: string | null = null
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
address_1: string | null = null
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
address_2: string | null = null
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
city: string | null = null
|
||||
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
country_code: string | null = null
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
province: string | null = null
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
postal_code: string | null = null
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { DAL } from "@medusajs/types"
|
||||
import { DALUtils, generateEntityId } from "@medusajs/utils"
|
||||
import { DALUtils, Searchable, generateEntityId } from "@medusajs/utils"
|
||||
import {
|
||||
BeforeCreate,
|
||||
Entity,
|
||||
@@ -24,6 +24,7 @@ export default class CustomerGroup {
|
||||
@PrimaryKey({ columnType: "text" })
|
||||
id!: string
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
name: string | null = null
|
||||
|
||||
|
||||
@@ -70,9 +70,11 @@ export class InventoryItem {
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
origin_country: string | null = null
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
hs_code: string | null = null
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
mid_code: string | null = null
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ export const AdminGetApiKeysParams = createFindParams({
|
||||
limit: 50,
|
||||
}).merge(
|
||||
z.object({
|
||||
q: z.string().optional(),
|
||||
id: z.union([z.string(), z.array(z.string())]).optional(),
|
||||
title: z.union([z.string(), z.array(z.string())]).optional(),
|
||||
token: z.union([z.string(), z.array(z.string())]).optional(),
|
||||
|
||||
@@ -12,6 +12,7 @@ export const AdminGetCampaignsParams = createFindParams({
|
||||
limit: 50,
|
||||
}).merge(
|
||||
z.object({
|
||||
q: z.string().optional(),
|
||||
campaign_identifier: z.string().optional(),
|
||||
currency: z.string().optional(),
|
||||
$and: z.lazy(() => AdminGetCampaignsParams.array()).optional(),
|
||||
|
||||
@@ -82,6 +82,7 @@ export const AdminCustomerAdressesParams = createFindParams({
|
||||
limit: 50,
|
||||
}).merge(
|
||||
z.object({
|
||||
q: z.string().optional(),
|
||||
address_name: z.union([z.string(), z.array(z.string())]).optional(),
|
||||
is_default_shipping: z.boolean().optional(),
|
||||
is_default_billing: z.boolean().optional(),
|
||||
|
||||
@@ -14,6 +14,7 @@ export const AdminGetPaymentsParams = createFindParams({
|
||||
offset: 0,
|
||||
}).merge(
|
||||
z.object({
|
||||
q: z.string().optional(),
|
||||
id: z.union([z.string(), z.array(z.string())]).optional(),
|
||||
created_at: createOperatorMap().optional(),
|
||||
updated_at: createOperatorMap().optional(),
|
||||
|
||||
@@ -1,17 +1,29 @@
|
||||
import { PriceListStatus, PriceListType } from "@medusajs/types"
|
||||
import { z } from "zod"
|
||||
import { createFindParams, createSelectParams } from "../../utils/validators"
|
||||
import {
|
||||
createFindParams,
|
||||
createOperatorMap,
|
||||
createSelectParams,
|
||||
} from "../../utils/validators"
|
||||
|
||||
export const AdminGetPriceListPricesParams = createSelectParams()
|
||||
export const AdminGetPriceListsParams = createFindParams({
|
||||
offset: 0,
|
||||
limit: 50,
|
||||
})
|
||||
}).merge(
|
||||
z.object({
|
||||
q: z.string().optional(),
|
||||
id: z.union([z.string(), z.array(z.string())]).optional(),
|
||||
starts_at: createOperatorMap().optional(),
|
||||
ends_at: createOperatorMap().optional(),
|
||||
status: z.array(z.nativeEnum(PriceListStatus)).optional(),
|
||||
rules_count: z.array(z.number()).optional(),
|
||||
$and: z.lazy(() => AdminGetPriceListsParams.array()).optional(),
|
||||
$or: z.lazy(() => AdminGetPriceListsParams.array()).optional(),
|
||||
})
|
||||
)
|
||||
|
||||
export const AdminGetPriceListParams = createFindParams({
|
||||
offset: 0,
|
||||
limit: 50,
|
||||
})
|
||||
export const AdminGetPriceListParams = createSelectParams()
|
||||
|
||||
export const AdminCreatePriceListPrice = z.object({
|
||||
currency_code: z.string(),
|
||||
|
||||
@@ -14,6 +14,7 @@ export const AdminGetRegionsParams = createFindParams({
|
||||
offset: 0,
|
||||
}).merge(
|
||||
z.object({
|
||||
q: z.string().optional(),
|
||||
id: z.union([z.string(), z.array(z.string())]).optional(),
|
||||
code: z.union([z.string(), z.array(z.string())]).optional(),
|
||||
name: z.union([z.string(), z.array(z.string())]).optional(),
|
||||
|
||||
@@ -18,6 +18,7 @@ export const AdminGetSalesChannelsParams = createFindParams({
|
||||
offset: 0,
|
||||
}).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(),
|
||||
description: z.string().optional(),
|
||||
|
||||
@@ -10,6 +10,7 @@ export const AdminGetStoresParams = createFindParams({
|
||||
offset: 0,
|
||||
}).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(),
|
||||
$and: z.lazy(() => AdminGetStoresParams.array()).optional(),
|
||||
|
||||
@@ -18,8 +18,8 @@ export const AdminGetTaxRegionsParams = createFindParams({
|
||||
offset: 0,
|
||||
}).merge(
|
||||
z.object({
|
||||
id: z.union([z.string(), z.array(z.string())]).optional(),
|
||||
q: z.string().optional(),
|
||||
id: z.union([z.string(), z.array(z.string())]).optional(),
|
||||
country_code: z
|
||||
.union([z.string(), z.array(z.string()), createOperatorMap()])
|
||||
.optional(),
|
||||
|
||||
@@ -13,6 +13,7 @@ export const AdminGetUsersParams = createFindParams({
|
||||
limit: 50,
|
||||
}).merge(
|
||||
z.object({
|
||||
q: z.string().optional(),
|
||||
id: z.union([z.string(), z.array(z.string())]).optional(),
|
||||
created_at: createOperatorMap().optional(),
|
||||
updated_at: createOperatorMap().optional(),
|
||||
@@ -20,7 +21,6 @@ export const AdminGetUsersParams = createFindParams({
|
||||
email: z.string().optional(),
|
||||
first_name: z.string().optional(),
|
||||
last_name: z.string().optional(),
|
||||
q: z.string().optional(),
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
BigNumber,
|
||||
DALUtils,
|
||||
MikroOrmBigNumberProperty,
|
||||
Searchable,
|
||||
generateEntityId,
|
||||
} from "@medusajs/utils"
|
||||
import {
|
||||
@@ -46,12 +47,15 @@ export default class Payment {
|
||||
@Property({ columnType: "text" })
|
||||
provider_id: string
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
cart_id: string | null = null
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
order_id: string | null = null
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
customer_id: string | null = null
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
generateEntityId,
|
||||
PriceListStatus,
|
||||
PriceListType,
|
||||
Searchable,
|
||||
} from "@medusajs/utils"
|
||||
import {
|
||||
BeforeCreate,
|
||||
@@ -46,9 +47,11 @@ export default class PriceList {
|
||||
@PrimaryKey({ columnType: "text" })
|
||||
id!: string
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text" })
|
||||
title: string
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text" })
|
||||
description: string
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { DAL } from "@medusajs/types"
|
||||
import { DALUtils, generateEntityId } from "@medusajs/utils"
|
||||
import { DALUtils, Searchable, generateEntityId } from "@medusajs/utils"
|
||||
import {
|
||||
BeforeCreate,
|
||||
Collection,
|
||||
@@ -32,9 +32,11 @@ export default class Campaign {
|
||||
@PrimaryKey({ columnType: "text" })
|
||||
id!: string
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text" })
|
||||
name: string
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
description: string | null = null
|
||||
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import { DAL, PromotionTypeValues } from "@medusajs/types"
|
||||
import { DALUtils, PromotionUtils, generateEntityId } from "@medusajs/utils"
|
||||
import {
|
||||
DALUtils,
|
||||
PromotionUtils,
|
||||
Searchable,
|
||||
generateEntityId,
|
||||
} from "@medusajs/utils"
|
||||
import {
|
||||
BeforeCreate,
|
||||
Collection,
|
||||
@@ -31,6 +36,7 @@ export default class Promotion {
|
||||
@PrimaryKey({ columnType: "text" })
|
||||
id!: string
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text" })
|
||||
@Index({ name: "IDX_promotion_code" })
|
||||
@Unique({
|
||||
@@ -39,6 +45,7 @@ export default class Promotion {
|
||||
})
|
||||
code: string
|
||||
|
||||
@Searchable()
|
||||
@ManyToOne(() => Campaign, {
|
||||
fieldName: "campaign_id",
|
||||
nullable: true,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { DAL } from "@medusajs/types"
|
||||
import { DALUtils, generateEntityId } from "@medusajs/utils"
|
||||
import { DALUtils, Searchable, generateEntityId } from "@medusajs/utils"
|
||||
import {
|
||||
BeforeCreate,
|
||||
Collection,
|
||||
@@ -24,9 +24,11 @@ export default class Region {
|
||||
@PrimaryKey({ columnType: "text" })
|
||||
id: string
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text" })
|
||||
name: string
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text" })
|
||||
currency_code: string
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { DALUtils, generateEntityId } from "@medusajs/utils"
|
||||
import { DALUtils, Searchable, generateEntityId } from "@medusajs/utils"
|
||||
|
||||
import { DAL } from "@medusajs/types"
|
||||
import {
|
||||
@@ -22,9 +22,11 @@ export default class SalesChannel {
|
||||
@PrimaryKey({ columnType: "text" })
|
||||
id!: string
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text" })
|
||||
name!: string
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
description: string | null = null
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { generateEntityId } from "@medusajs/utils"
|
||||
import { Searchable, generateEntityId } from "@medusajs/utils"
|
||||
import {
|
||||
BeforeInsert,
|
||||
Column,
|
||||
@@ -24,15 +24,19 @@ export class StockLocationAddress {
|
||||
@DeleteDateColumn({ type: "timestamptz" })
|
||||
deleted_at: Date | null
|
||||
|
||||
@Searchable()
|
||||
@Column({ type: "text" })
|
||||
address_1: string
|
||||
|
||||
@Searchable()
|
||||
@Column({ type: "text", nullable: true })
|
||||
address_2: string | null
|
||||
|
||||
@Searchable()
|
||||
@Column({ type: "text", nullable: true })
|
||||
company: string | null
|
||||
|
||||
@Searchable()
|
||||
@Column({ type: "text", nullable: true })
|
||||
city: string | null
|
||||
|
||||
@@ -43,9 +47,11 @@ export class StockLocationAddress {
|
||||
@Column({ type: "text", nullable: true })
|
||||
phone: string | null
|
||||
|
||||
@Searchable()
|
||||
@Column({ type: "text", nullable: true })
|
||||
province: string | null
|
||||
|
||||
@Searchable()
|
||||
@Column({ type: "text", nullable: true })
|
||||
postal_code: string | null
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { generateEntityId } from "@medusajs/utils"
|
||||
import { Searchable, generateEntityId } from "@medusajs/utils"
|
||||
import {
|
||||
BeforeInsert,
|
||||
Column,
|
||||
@@ -27,6 +27,7 @@ export class StockLocation {
|
||||
@DeleteDateColumn({ type: "timestamptz" })
|
||||
deleted_at: Date | null
|
||||
|
||||
@Searchable()
|
||||
@Column({ type: "text" })
|
||||
name: string
|
||||
|
||||
@@ -34,6 +35,7 @@ export class StockLocation {
|
||||
@Column({ type: "text", nullable: true })
|
||||
address_id: string | null
|
||||
|
||||
@Searchable()
|
||||
@ManyToOne(() => StockLocationAddress)
|
||||
@JoinColumn({ name: "address_id" })
|
||||
address: StockLocationAddress | null
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
DALUtils,
|
||||
Searchable,
|
||||
createPsqlIndexStatementHelper,
|
||||
generateEntityId,
|
||||
} from "@medusajs/utils"
|
||||
@@ -32,6 +33,7 @@ export default class Store {
|
||||
@PrimaryKey({ columnType: "text" })
|
||||
id: string
|
||||
|
||||
@Searchable()
|
||||
@Property({ columnType: "text", default: "Medusa Store" })
|
||||
name: string
|
||||
|
||||
|
||||
@@ -67,6 +67,10 @@ export interface ApiKeyDTO {
|
||||
*/
|
||||
export interface FilterableApiKeyProps
|
||||
extends BaseFilterable<FilterableApiKeyProps> {
|
||||
/**
|
||||
* Search through the api key names and redacted keys using this search term.
|
||||
*/
|
||||
q?: string
|
||||
/**
|
||||
* The IDs to filter the API keys by.
|
||||
*/
|
||||
|
||||
@@ -43,6 +43,10 @@ export interface CurrencyDTO {
|
||||
*/
|
||||
export interface FilterableCurrencyProps
|
||||
extends BaseFilterable<FilterableCurrencyProps> {
|
||||
/**
|
||||
* Search through currencies using this search term.
|
||||
*/
|
||||
q?: string
|
||||
/**
|
||||
* The codes to filter the currencies by.
|
||||
*/
|
||||
|
||||
@@ -102,6 +102,11 @@ export interface CustomerAddressDTO {
|
||||
*/
|
||||
export interface FilterableCustomerAddressProps
|
||||
extends BaseFilterable<FilterableCustomerAddressProps> {
|
||||
/**
|
||||
* Searches for addreses by properties such as name and street using this search term.
|
||||
*/
|
||||
q?: string
|
||||
|
||||
/**
|
||||
* The IDs to filter the customer address by.
|
||||
*/
|
||||
@@ -203,6 +208,11 @@ export interface FilterableCustomerAddressProps
|
||||
*/
|
||||
export interface FilterableCustomerGroupProps
|
||||
extends BaseFilterable<FilterableCustomerGroupProps> {
|
||||
/**
|
||||
* Searches for customer groups by name using this search term.
|
||||
*/
|
||||
q?: string
|
||||
|
||||
/**
|
||||
* The IDs to filter the customer group by.
|
||||
*/
|
||||
@@ -285,6 +295,11 @@ export interface FilterableCustomerGroupCustomerProps
|
||||
*/
|
||||
export interface FilterableCustomerProps
|
||||
extends BaseFilterable<FilterableCustomerProps> {
|
||||
/**
|
||||
* Searches for customers by properties such as name and email using this search term.
|
||||
*/
|
||||
q?: string
|
||||
|
||||
/**
|
||||
* The IDs to filter the customer by.
|
||||
*/
|
||||
|
||||
@@ -101,6 +101,11 @@ export interface InventoryItemDTO {
|
||||
* The filters to apply on retrieved inventory items.
|
||||
*/
|
||||
export interface FilterableInventoryItemProps {
|
||||
/**
|
||||
* Search term to search inventory items' attributes.
|
||||
*/
|
||||
q?: string
|
||||
|
||||
/**
|
||||
* The IDs to filter inventory items by.
|
||||
*/
|
||||
@@ -111,11 +116,6 @@ export interface FilterableInventoryItemProps {
|
||||
*/
|
||||
location_id?: string | string[]
|
||||
|
||||
/**
|
||||
* Search term to search inventory items' attributes.
|
||||
*/
|
||||
q?: string
|
||||
|
||||
/**
|
||||
* The SKUs to filter inventory items by.
|
||||
*/
|
||||
|
||||
@@ -419,6 +419,11 @@ export interface PaymentDTO {
|
||||
*/
|
||||
export interface FilterablePaymentProps
|
||||
extends BaseFilterable<FilterablePaymentProps> {
|
||||
/**
|
||||
* Find payments based on cart, order, or customer IDs through this search term.
|
||||
*/
|
||||
q?: string
|
||||
|
||||
/**
|
||||
* The IDs to filter the payments by.
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { BaseFilterable } from "../../dal"
|
||||
import { BaseFilterable, OperatorMap } from "../../dal"
|
||||
import {
|
||||
CreateMoneyAmountDTO,
|
||||
MoneyAmountDTO,
|
||||
@@ -240,18 +240,22 @@ export interface UpdatePriceListDTO {
|
||||
*/
|
||||
export interface FilterablePriceListProps
|
||||
extends BaseFilterable<FilterablePriceListProps> {
|
||||
/**
|
||||
* Find price lists by title or description through this search term.
|
||||
*/
|
||||
q?: string
|
||||
/**
|
||||
* The IDs to filter price lists by
|
||||
*/
|
||||
id?: string[]
|
||||
id?: string | string[]
|
||||
/**
|
||||
* The start dates to filter price lists by.
|
||||
*/
|
||||
starts_at?: string[]
|
||||
starts_at?: OperatorMap<string>
|
||||
/**
|
||||
* The end dates to filter price lists by.
|
||||
*/
|
||||
ends_at?: string[]
|
||||
ends_at?: OperatorMap<string>
|
||||
/**
|
||||
* The statuses to filter price lists by.
|
||||
*/
|
||||
|
||||
@@ -888,6 +888,10 @@ export interface FilterableProductVariantProps
|
||||
*/
|
||||
export interface FilterableProductCategoryProps
|
||||
extends BaseFilterable<FilterableProductCategoryProps> {
|
||||
/**
|
||||
* Filter product categories based on searchable fields
|
||||
*/
|
||||
q?: string
|
||||
/**
|
||||
* The IDs to filter product categories by.
|
||||
*/
|
||||
@@ -920,10 +924,6 @@ export interface FilterableProductCategoryProps
|
||||
* Whether to include parents of retrieved product categories.
|
||||
*/
|
||||
include_ancestors_tree?: boolean
|
||||
/**
|
||||
* Filter product categories based on searchable fields
|
||||
*/
|
||||
q?: string
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -51,6 +51,10 @@ export interface CampaignDTO {
|
||||
*/
|
||||
export interface FilterableCampaignProps
|
||||
extends BaseFilterable<FilterableCampaignProps> {
|
||||
/**
|
||||
* Find campaigns by their name or description through this search term.
|
||||
*/
|
||||
q?: string
|
||||
/**
|
||||
* The IDs to filter the campaigns by.
|
||||
*/
|
||||
|
||||
@@ -141,6 +141,11 @@ export interface UpdatePromotionDTO {
|
||||
*/
|
||||
export interface FilterablePromotionProps
|
||||
extends BaseFilterable<FilterablePromotionProps> {
|
||||
/**
|
||||
* The IDs to filter the promotions by.
|
||||
*/
|
||||
q?: string
|
||||
|
||||
/**
|
||||
* The IDs to filter the promotions by.
|
||||
*/
|
||||
|
||||
@@ -90,6 +90,10 @@ export interface RegionCountryDTO {
|
||||
*/
|
||||
export interface FilterableRegionProps
|
||||
extends BaseFilterable<FilterableRegionProps> {
|
||||
/**
|
||||
* Find regions by name through this search term
|
||||
*/
|
||||
q?: string
|
||||
/**
|
||||
* The IDs to filter the regions by.
|
||||
*/
|
||||
|
||||
@@ -60,6 +60,11 @@ export interface SalesChannelDTO {
|
||||
*/
|
||||
export interface FilterableSalesChannelProps
|
||||
extends BaseFilterable<FilterableSalesChannelProps> {
|
||||
/**
|
||||
* Find sales channels by their name or description through this search term.
|
||||
*/
|
||||
q?: string
|
||||
|
||||
/**
|
||||
* The IDs to filter the sales channel by.
|
||||
*/
|
||||
|
||||
@@ -60,6 +60,10 @@ export interface StoreDTO {
|
||||
*/
|
||||
export interface FilterableStoreProps
|
||||
extends BaseFilterable<FilterableStoreProps> {
|
||||
/**
|
||||
* Find stores by name through this search term.
|
||||
*/
|
||||
q?: string
|
||||
/**
|
||||
* The IDs to filter the stores by.
|
||||
*/
|
||||
|
||||
@@ -93,6 +93,11 @@ export interface TaxProviderDTO {
|
||||
*/
|
||||
export interface FilterableTaxRateProps
|
||||
extends BaseFilterable<FilterableTaxRateProps> {
|
||||
/**
|
||||
* Find tax rates based on name and code properties through this search term.
|
||||
*/
|
||||
q?: string
|
||||
|
||||
/**
|
||||
* The IDs to filter the tax rates by.
|
||||
*/
|
||||
@@ -190,6 +195,11 @@ export interface TaxRegionDTO {
|
||||
*/
|
||||
export interface FilterableTaxRegionProps
|
||||
extends BaseFilterable<FilterableTaxRegionProps> {
|
||||
/**
|
||||
* Find tax regions based on currency and province codes through this search term.
|
||||
*/
|
||||
q?: string
|
||||
|
||||
/**
|
||||
* The IDs to filter the tax regions by.
|
||||
*/
|
||||
|
||||
@@ -52,6 +52,10 @@ export interface UserDTO {
|
||||
*/
|
||||
export interface FilterableUserProps
|
||||
extends BaseFilterable<FilterableUserProps> {
|
||||
/**
|
||||
* Find users by name or email through this search term
|
||||
*/
|
||||
q?: string
|
||||
/**
|
||||
* The IDs to filter users by.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user