feat(medusa): variants expand inventory_items (#4203)
* add expand params for inventory items to product and variant endpoints in store * add changeset * update integration test naming * make priceSeelctionParams extends findParams and adjust api accordingly
This commit is contained in:
1 parent
4b5b7b5148
commit
eadf13cb21
12 files changed
+312
-48
No files matched your search
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/medusa": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
feat(medusa): add allowed relation to expand params for product and variant endpoints
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
const path = require("path")
|
||||||
|
|
||||||
|
const { bootstrapApp } = require("../../../../helpers/bootstrap-app")
|
||||||
|
const { initDb, useDb } = require("../../../../helpers/use-db")
|
||||||
|
const { setPort, useApi } = require("../../../../helpers/use-api")
|
||||||
|
|
||||||
|
const {
|
||||||
|
ProductVariantInventoryService,
|
||||||
|
ProductVariantService,
|
||||||
|
} = require("@medusajs/medusa")
|
||||||
|
|
||||||
|
const adminSeeder = require("../../../helpers/admin-seeder")
|
||||||
|
|
||||||
|
jest.setTimeout(30000)
|
||||||
|
|
||||||
|
const { simpleProductFactory } = require("../../../factories")
|
||||||
|
const { simpleSalesChannelFactory } = require("../../../../api/factories")
|
||||||
|
|
||||||
|
const adminHeaders = { headers: { Authorization: "Bearer test_token" } }
|
||||||
|
|
||||||
|
describe("Get products", () => {
|
||||||
|
let appContainer
|
||||||
|
let dbConnection
|
||||||
|
let express
|
||||||
|
const productId = "test-product"
|
||||||
|
const variantId = "test-variant"
|
||||||
|
let invItem
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const cwd = path.resolve(path.join(__dirname, "..", "..", ".."))
|
||||||
|
dbConnection = await initDb({ cwd })
|
||||||
|
const { container, app, port } = await bootstrapApp({ cwd })
|
||||||
|
appContainer = container
|
||||||
|
|
||||||
|
setPort(port)
|
||||||
|
express = app.listen(port, (err) => {
|
||||||
|
process.send(port)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.shutdown()
|
||||||
|
express.close()
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
const db = useDb()
|
||||||
|
return await db.teardown()
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await adminSeeder(dbConnection)
|
||||||
|
|
||||||
|
const productVariantInventoryService = appContainer.resolve(
|
||||||
|
"productVariantInventoryService"
|
||||||
|
)
|
||||||
|
const inventoryService = appContainer.resolve("inventoryService")
|
||||||
|
|
||||||
|
await simpleProductFactory(
|
||||||
|
dbConnection,
|
||||||
|
{
|
||||||
|
id: productId,
|
||||||
|
status: "published",
|
||||||
|
variants: [{ id: variantId }],
|
||||||
|
},
|
||||||
|
100
|
||||||
|
)
|
||||||
|
|
||||||
|
invItem = await inventoryService.createInventoryItem({
|
||||||
|
sku: "test-sku",
|
||||||
|
})
|
||||||
|
await productVariantInventoryService.attachInventoryItem(
|
||||||
|
variantId,
|
||||||
|
invItem.id
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("Expands inventory items when getting product with expand parameters", async () => {
|
||||||
|
const api = useApi()
|
||||||
|
|
||||||
|
const res = await api.get(
|
||||||
|
`/store/products/${productId}?expand=variants,variants.inventory_items`,
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(res.status).toEqual(200)
|
||||||
|
expect(res.data.product).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: productId,
|
||||||
|
variants: [
|
||||||
|
expect.objectContaining({
|
||||||
|
id: variantId,
|
||||||
|
inventory_items: [
|
||||||
|
expect.objectContaining({
|
||||||
|
inventory_item_id: invItem.id,
|
||||||
|
variant_id: variantId,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
expect.objectContaining({})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
const path = require("path")
|
||||||
|
|
||||||
|
const { bootstrapApp } = require("../../../../helpers/bootstrap-app")
|
||||||
|
const { initDb, useDb } = require("../../../../helpers/use-db")
|
||||||
|
const { setPort, useApi } = require("../../../../helpers/use-api")
|
||||||
|
|
||||||
|
const {
|
||||||
|
ProductVariantInventoryService,
|
||||||
|
ProductVariantService,
|
||||||
|
} = require("@medusajs/medusa")
|
||||||
|
|
||||||
|
const adminSeeder = require("../../../helpers/admin-seeder")
|
||||||
|
|
||||||
|
jest.setTimeout(30000)
|
||||||
|
|
||||||
|
const { simpleProductFactory } = require("../../../factories")
|
||||||
|
const { simpleSalesChannelFactory } = require("../../../../api/factories")
|
||||||
|
|
||||||
|
const adminHeaders = { headers: { Authorization: "Bearer test_token" } }
|
||||||
|
|
||||||
|
describe("Get variant", () => {
|
||||||
|
let appContainer
|
||||||
|
let dbConnection
|
||||||
|
let express
|
||||||
|
const productId = "test-product"
|
||||||
|
const variantId = "test-variant"
|
||||||
|
let invItem
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const cwd = path.resolve(path.join(__dirname, "..", "..", ".."))
|
||||||
|
dbConnection = await initDb({ cwd })
|
||||||
|
const { container, app, port } = await bootstrapApp({ cwd })
|
||||||
|
appContainer = container
|
||||||
|
|
||||||
|
setPort(port)
|
||||||
|
express = app.listen(port, (err) => {
|
||||||
|
process.send(port)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.shutdown()
|
||||||
|
express.close()
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
const db = useDb()
|
||||||
|
return await db.teardown()
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await adminSeeder(dbConnection)
|
||||||
|
|
||||||
|
const productVariantInventoryService = appContainer.resolve(
|
||||||
|
"productVariantInventoryService"
|
||||||
|
)
|
||||||
|
const inventoryService = appContainer.resolve("inventoryService")
|
||||||
|
|
||||||
|
await simpleProductFactory(
|
||||||
|
dbConnection,
|
||||||
|
{
|
||||||
|
id: productId,
|
||||||
|
status: "published",
|
||||||
|
variants: [{ id: variantId }],
|
||||||
|
},
|
||||||
|
100
|
||||||
|
)
|
||||||
|
|
||||||
|
invItem = await inventoryService.createInventoryItem({
|
||||||
|
sku: "test-sku",
|
||||||
|
})
|
||||||
|
await productVariantInventoryService.attachInventoryItem(
|
||||||
|
variantId,
|
||||||
|
invItem.id
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("Expands inventory items when getting variant with expand parameters", async () => {
|
||||||
|
const api = useApi()
|
||||||
|
|
||||||
|
const res = await api.get(
|
||||||
|
`/store/variants/${variantId}?expand=inventory_items`,
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(res.status).toEqual(200)
|
||||||
|
expect(res.data.variant).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: variantId,
|
||||||
|
inventory_items: [
|
||||||
|
expect.objectContaining({
|
||||||
|
inventory_item_id: invItem.id,
|
||||||
|
variant_id: variantId,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -199,6 +199,27 @@ describe("Create Variant", () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("includes inventory items when property is expanded", async () => {
|
||||||
|
const api = useApi()
|
||||||
|
|
||||||
|
const result = await api.get(
|
||||||
|
`/store/products?expand=variants,variants.inventory_items`
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(result.status).toEqual(200)
|
||||||
|
expect(result.data.products).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
expect.objectContaining({
|
||||||
|
variants: expect.arrayContaining([
|
||||||
|
expect.objectContaining({
|
||||||
|
inventory_items: [expect.any(Object)],
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
it("lists location availability correctly for store", async () => {
|
it("lists location availability correctly for store", async () => {
|
||||||
const api = useApi()
|
const api = useApi()
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ describe("List Variants", () => {
|
|||||||
|
|
||||||
describe("Inventory Items", () => {
|
describe("Inventory Items", () => {
|
||||||
const variantId = "test-variant"
|
const variantId = "test-variant"
|
||||||
|
let invItem
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await adminSeeder(dbConnection)
|
await adminSeeder(dbConnection)
|
||||||
@@ -78,7 +79,7 @@ describe("List Variants", () => {
|
|||||||
location.id
|
location.id
|
||||||
)
|
)
|
||||||
|
|
||||||
const invItem = await inventoryService.createInventoryItem({
|
invItem = await inventoryService.createInventoryItem({
|
||||||
sku: "test-sku",
|
sku: "test-sku",
|
||||||
})
|
})
|
||||||
const invItemId = invItem.id
|
const invItemId = invItem.id
|
||||||
@@ -103,5 +104,28 @@ describe("List Variants", () => {
|
|||||||
expect.objectContaining({ id: variantId, inventory_quantity: 10 })
|
expect.objectContaining({ id: variantId, inventory_quantity: 10 })
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("expands inventory_items when querying with expand parameter", async () => {
|
||||||
|
const api = useApi()
|
||||||
|
|
||||||
|
const listVariantsRes = await api.get(
|
||||||
|
`/admin/variants?expand=inventory_items`,
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(listVariantsRes.status).toEqual(200)
|
||||||
|
expect(listVariantsRes.data.variants.length).toEqual(1)
|
||||||
|
expect(listVariantsRes.data.variants[0]).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: variantId,
|
||||||
|
inventory_items: [
|
||||||
|
expect.objectContaining({
|
||||||
|
inventory_item_id: invItem.id,
|
||||||
|
variant_id: variantId,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import { IsOptional, IsString } from "class-validator"
|
|
||||||
import {
|
import {
|
||||||
CartService,
|
CartService,
|
||||||
PricingService,
|
PricingService,
|
||||||
@@ -6,6 +5,8 @@ import {
|
|||||||
ProductVariantInventoryService,
|
ProductVariantInventoryService,
|
||||||
RegionService,
|
RegionService,
|
||||||
} from "../../../../services"
|
} from "../../../../services"
|
||||||
|
import { IsOptional, IsString } from "class-validator"
|
||||||
|
|
||||||
import { PriceSelectionParams } from "../../../../types/price-selection"
|
import { PriceSelectionParams } from "../../../../types/price-selection"
|
||||||
import { cleanResponseData } from "../../../../utils/clean-response-data"
|
import { cleanResponseData } from "../../../../utils/clean-response-data"
|
||||||
|
|
||||||
@@ -148,12 +149,4 @@ export class StoreGetProductsProductParams extends PriceSelectionParams {
|
|||||||
@IsString()
|
@IsString()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
sales_channel_id?: string
|
sales_channel_id?: string
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@IsOptional()
|
|
||||||
fields?: string
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@IsOptional()
|
|
||||||
expand?: string
|
|
||||||
}
|
}
|
||||||
@@ -105,6 +105,7 @@ export const allowedStoreProductsFields = [
|
|||||||
export const allowedStoreProductsRelations = [
|
export const allowedStoreProductsRelations = [
|
||||||
...defaultStoreProductsRelations,
|
...defaultStoreProductsRelations,
|
||||||
"variants.title",
|
"variants.title",
|
||||||
|
"variants.inventory_items",
|
||||||
"variants.prices.amount",
|
"variants.prices.amount",
|
||||||
"sales_channels",
|
"sales_channels",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
import { Transform, Type } from "class-transformer"
|
import {
|
||||||
|
CartService,
|
||||||
|
ProductService,
|
||||||
|
ProductVariantInventoryService,
|
||||||
|
} from "../../../../services"
|
||||||
import {
|
import {
|
||||||
IsArray,
|
IsArray,
|
||||||
IsBoolean,
|
IsBoolean,
|
||||||
@@ -7,20 +11,17 @@ import {
|
|||||||
IsString,
|
IsString,
|
||||||
ValidateNested,
|
ValidateNested,
|
||||||
} from "class-validator"
|
} from "class-validator"
|
||||||
import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels"
|
import { Transform, Type } from "class-transformer"
|
||||||
import {
|
|
||||||
CartService,
|
|
||||||
ProductService,
|
|
||||||
ProductVariantInventoryService,
|
|
||||||
} from "../../../../services"
|
|
||||||
import PricingService from "../../../../services/pricing"
|
|
||||||
import { DateComparisonOperator } from "../../../../types/common"
|
import { DateComparisonOperator } from "../../../../types/common"
|
||||||
import { PriceSelectionParams } from "../../../../types/price-selection"
|
|
||||||
import { cleanResponseData } from "../../../../utils/clean-response-data"
|
|
||||||
import { FeatureFlagDecorators } from "../../../../utils/feature-flag-decorators"
|
import { FeatureFlagDecorators } from "../../../../utils/feature-flag-decorators"
|
||||||
import { optionalBooleanMapper } from "../../../../utils/validators/is-boolean"
|
|
||||||
import { IsType } from "../../../../utils/validators/is-type"
|
import { IsType } from "../../../../utils/validators/is-type"
|
||||||
|
import { PriceSelectionParams } from "../../../../types/price-selection"
|
||||||
|
import PricingService from "../../../../services/pricing"
|
||||||
|
import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels"
|
||||||
|
import { cleanResponseData } from "../../../../utils/clean-response-data"
|
||||||
import { defaultStoreCategoryScope } from "../product-categories"
|
import { defaultStoreCategoryScope } from "../product-categories"
|
||||||
|
import { optionalBooleanMapper } from "../../../../utils/validators/is-boolean"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @oas [get] /store/products
|
* @oas [get] /store/products
|
||||||
@@ -283,14 +284,6 @@ export default async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class StoreGetProductsPaginationParams extends PriceSelectionParams {
|
export class StoreGetProductsPaginationParams extends PriceSelectionParams {
|
||||||
@IsString()
|
|
||||||
@IsOptional()
|
|
||||||
fields?: string
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@IsOptional()
|
|
||||||
expand?: string
|
|
||||||
|
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@Type(() => Number)
|
@Type(() => Number)
|
||||||
|
|||||||
@@ -5,11 +5,12 @@ import {
|
|||||||
ProductVariantService,
|
ProductVariantService,
|
||||||
RegionService,
|
RegionService,
|
||||||
} from "../../../../services"
|
} from "../../../../services"
|
||||||
|
import { IsOptional, IsString } from "class-validator"
|
||||||
|
|
||||||
|
import { FindParams } from "../../../../types/common"
|
||||||
import { PriceSelectionParams } from "../../../../types/price-selection"
|
import { PriceSelectionParams } from "../../../../types/price-selection"
|
||||||
import { defaultStoreVariantRelations } from "."
|
import { defaultStoreVariantRelations } from "."
|
||||||
import { validator } from "../../../../utils/validator"
|
import { validator } from "../../../../utils/validator"
|
||||||
import { IsOptional, IsString } from "class-validator"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @oas [get] /store/variants/{variant_id}
|
* @oas [get] /store/variants/{variant_id}
|
||||||
@@ -75,9 +76,7 @@ export default async (req, res) => {
|
|||||||
|
|
||||||
const customer_id = req.user?.customer_id
|
const customer_id = req.user?.customer_id
|
||||||
|
|
||||||
const rawVariant = await variantService.retrieve(id, {
|
const rawVariant = await variantService.retrieve(id, req.retrieveConfig)
|
||||||
relations: defaultStoreVariantRelations,
|
|
||||||
})
|
|
||||||
|
|
||||||
let sales_channel_id = validated.sales_channel_id
|
let sales_channel_id = validated.sales_channel_id
|
||||||
if (req.publishableApiKeyScopes?.sales_channel_ids.length === 1) {
|
if (req.publishableApiKeyScopes?.sales_channel_ids.length === 1) {
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
|
import middlewares, { transformStoreQuery } from "../../../middlewares"
|
||||||
|
|
||||||
|
import { PricedVariant } from "../../../../types/pricing"
|
||||||
import { Router } from "express"
|
import { Router } from "express"
|
||||||
|
import { StoreGetVariantsParams } from "./list-variants"
|
||||||
|
import { StoreGetVariantsVariantParams } from "./get-variant"
|
||||||
import { extendRequestParams } from "../../../middlewares/publishable-api-key/extend-request-params"
|
import { extendRequestParams } from "../../../middlewares/publishable-api-key/extend-request-params"
|
||||||
import middlewares from "../../../middlewares"
|
|
||||||
import { validateProductVariantSalesChannelAssociation } from "../../../middlewares/publishable-api-key/validate-variant-sales-channel-association"
|
import { validateProductVariantSalesChannelAssociation } from "../../../middlewares/publishable-api-key/validate-variant-sales-channel-association"
|
||||||
import { validateSalesChannelParam } from "../../../middlewares/publishable-api-key/validate-sales-channel-param"
|
import { validateSalesChannelParam } from "../../../middlewares/publishable-api-key/validate-sales-channel-param"
|
||||||
import { PricedVariant } from "../../../../types/pricing"
|
|
||||||
|
|
||||||
const route = Router()
|
const route = Router()
|
||||||
|
|
||||||
@@ -12,14 +15,33 @@ export default (app) => {
|
|||||||
|
|
||||||
route.use("/:id", validateProductVariantSalesChannelAssociation)
|
route.use("/:id", validateProductVariantSalesChannelAssociation)
|
||||||
|
|
||||||
route.get("/", middlewares.wrap(require("./list-variants").default))
|
route.get(
|
||||||
route.get("/:id", middlewares.wrap(require("./get-variant").default))
|
"/",
|
||||||
|
transformStoreQuery(StoreGetVariantsParams, {
|
||||||
|
defaultRelations: defaultStoreVariantRelations,
|
||||||
|
allowedRelations: allowedStoreVariantRelations,
|
||||||
|
isList: true,
|
||||||
|
}),
|
||||||
|
middlewares.wrap(require("./list-variants").default)
|
||||||
|
)
|
||||||
|
route.get(
|
||||||
|
"/:id",
|
||||||
|
transformStoreQuery(StoreGetVariantsVariantParams, {
|
||||||
|
defaultRelations: defaultStoreVariantRelations,
|
||||||
|
allowedRelations: allowedStoreVariantRelations,
|
||||||
|
}),
|
||||||
|
middlewares.wrap(require("./get-variant").default)
|
||||||
|
)
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
export const defaultStoreVariantRelations = ["prices", "options", "product"]
|
export const defaultStoreVariantRelations = ["prices", "options", "product"]
|
||||||
|
|
||||||
|
export const allowedStoreVariantRelations = [
|
||||||
|
...defaultStoreVariantRelations,
|
||||||
|
"inventory_items",
|
||||||
|
]
|
||||||
/**
|
/**
|
||||||
* @schema StoreVariantsRes
|
* @schema StoreVariantsRes
|
||||||
* type: object
|
* type: object
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { IsInt, IsOptional, IsString } from "class-validator"
|
|
||||||
import {
|
import {
|
||||||
CartService,
|
CartService,
|
||||||
PricingService,
|
PricingService,
|
||||||
@@ -6,15 +5,16 @@ import {
|
|||||||
ProductVariantService,
|
ProductVariantService,
|
||||||
RegionService,
|
RegionService,
|
||||||
} from "../../../../services"
|
} from "../../../../services"
|
||||||
|
import { IsInt, IsOptional, IsString } from "class-validator"
|
||||||
|
|
||||||
import { Type } from "class-transformer"
|
import { FilterableProductVariantProps } from "../../../../types/product-variant"
|
||||||
import { omit } from "lodash"
|
import { IsType } from "../../../../utils/validators/is-type"
|
||||||
import { defaultStoreVariantRelations } from "."
|
|
||||||
import { NumericalComparisonOperator } from "../../../../types/common"
|
import { NumericalComparisonOperator } from "../../../../types/common"
|
||||||
import { PriceSelectionParams } from "../../../../types/price-selection"
|
import { PriceSelectionParams } from "../../../../types/price-selection"
|
||||||
import { FilterableProductVariantProps } from "../../../../types/product-variant"
|
import { Type } from "class-transformer"
|
||||||
|
import { defaultStoreVariantRelations } from "."
|
||||||
|
import { omit } from "lodash"
|
||||||
import { validator } from "../../../../utils/validator"
|
import { validator } from "../../../../utils/validator"
|
||||||
import { IsType } from "../../../../utils/validators/is-type"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @oas [get] /store/variants
|
* @oas [get] /store/variants
|
||||||
@@ -183,10 +183,6 @@ export class StoreGetVariantsParams extends PriceSelectionParams {
|
|||||||
@Type(() => Number)
|
@Type(() => Number)
|
||||||
offset?: number = 0
|
offset?: number = 0
|
||||||
|
|
||||||
@IsOptional()
|
|
||||||
@IsString()
|
|
||||||
expand?: string
|
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
ids?: string
|
ids?: string
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { IsOptional, IsString } from "class-validator"
|
import { IsOptional, IsString } from "class-validator"
|
||||||
|
|
||||||
export class PriceSelectionParams {
|
import { FindParams } from "./common"
|
||||||
|
|
||||||
|
export class PriceSelectionParams extends FindParams {
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
cart_id?: string
|
cart_id?: string
|
||||||
|
|||||||
Reference in new issue
Block a user