Clean up product typings (#7663)
There are a lot of issues in the admin after applying the correct typings, but fixing those should be done gradually, it's better to keep it out of this PR
This commit is contained in:
@@ -864,7 +864,7 @@ medusaIntegrationTestRunner({
|
||||
|
||||
it("successfully creates, updates and deletes an inventory item link from a variant", async () => {
|
||||
const res = await api.post(
|
||||
`/admin/products/${baseProduct.id}/variants/inventory-items/batch`,
|
||||
`/admin/products/${inventoryProduct.id}/variants/inventory-items/batch`,
|
||||
{
|
||||
create: [
|
||||
{
|
||||
@@ -894,7 +894,7 @@ medusaIntegrationTestRunner({
|
||||
|
||||
const createdLinkVariant = (
|
||||
await api.get(
|
||||
`/admin/products/${baseProduct.id}/variants/${inventoryVariant3.id}?fields=inventory_items.inventory.*,inventory_items.*`,
|
||||
`/admin/products/${inventoryProduct.id}/variants/${inventoryVariant3.id}?fields=inventory_items.inventory.*,inventory_items.*`,
|
||||
adminHeaders
|
||||
)
|
||||
).data.variant
|
||||
@@ -911,7 +911,7 @@ medusaIntegrationTestRunner({
|
||||
|
||||
const updatedLinkVariant = (
|
||||
await api.get(
|
||||
`/admin/products/${baseProduct.id}/variants/${inventoryVariant1.id}?fields=inventory_items.inventory.*,inventory_items.*`,
|
||||
`/admin/products/${inventoryProduct.id}/variants/${inventoryVariant1.id}?fields=inventory_items.inventory.*,inventory_items.*`,
|
||||
adminHeaders
|
||||
)
|
||||
).data.variant
|
||||
@@ -928,7 +928,7 @@ medusaIntegrationTestRunner({
|
||||
|
||||
const deletedLinkVariant = (
|
||||
await api.get(
|
||||
`/admin/products/${baseProduct.id}/variants/${inventoryVariant2.id}?fields=inventory_items.inventory.*,inventory_items.*`,
|
||||
`/admin/products/${inventoryProduct.id}/variants/${inventoryVariant2.id}?fields=inventory_items.inventory.*,inventory_items.*`,
|
||||
adminHeaders
|
||||
)
|
||||
).data.variant
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
import { useTranslation } from "react-i18next"
|
||||
|
||||
import { ProductCollectionDTO } from "@medusajs/types"
|
||||
import { PlaceholderCell } from "../../common/placeholder-cell"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type CollectionCellProps = {
|
||||
collection?: ProductCollectionDTO | null
|
||||
collection?: HttpTypes.AdminCollection | null
|
||||
}
|
||||
|
||||
export const CollectionCell = ({ collection }: CollectionCellProps) => {
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
import { useTranslation } from "react-i18next"
|
||||
|
||||
import { ProductDTO } from "@medusajs/types"
|
||||
import { Thumbnail } from "../../../../common/thumbnail"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type ProductCellProps = {
|
||||
product: ProductDTO
|
||||
product: HttpTypes.AdminProduct
|
||||
}
|
||||
|
||||
export const ProductCell = ({ product }: ProductCellProps) => {
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
import { ProductStatus } from "@medusajs/types"
|
||||
import { useTranslation } from "react-i18next"
|
||||
|
||||
import { StatusCell } from "../../common/status-cell"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type ProductStatusCellProps = {
|
||||
status: ProductStatus
|
||||
status: HttpTypes.AdminProductStatus
|
||||
}
|
||||
|
||||
export const ProductStatusCell = ({ status }: ProductStatusCellProps) => {
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
import { useTranslation } from "react-i18next"
|
||||
|
||||
import { ProductVariantDTO } from "@medusajs/types"
|
||||
import { PlaceholderCell } from "../../common/placeholder-cell"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type VariantCellProps = {
|
||||
variants?: ProductVariantDTO[] | null
|
||||
variants?: HttpTypes.AdminProductVariant[] | null
|
||||
}
|
||||
|
||||
export const VariantCell = ({ variants }: VariantCellProps) => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { QueryKey, UseQueryOptions, useQuery } from "@tanstack/react-query"
|
||||
import { client } from "../../lib/client"
|
||||
import { queryKeysFactory } from "../../lib/query-key-factory"
|
||||
import { ProductTypeListRes, ProductTypeRes } from "../../types/api-responses"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
const PRODUCT_TYPES_QUERY_KEY = "product_types" as const
|
||||
const productTypesQueryKeys = queryKeysFactory(PRODUCT_TYPES_QUERY_KEY)
|
||||
@@ -10,7 +10,12 @@ export const useProductType = (
|
||||
id: string,
|
||||
query?: Record<string, any>,
|
||||
options?: Omit<
|
||||
UseQueryOptions<ProductTypeRes, Error, ProductTypeRes, QueryKey>,
|
||||
UseQueryOptions<
|
||||
{ product_type: HttpTypes.AdminProductType },
|
||||
Error,
|
||||
{ product_type: HttpTypes.AdminProductType },
|
||||
QueryKey
|
||||
>,
|
||||
"queryKey" | "queryFn"
|
||||
>
|
||||
) => {
|
||||
@@ -26,7 +31,12 @@ export const useProductType = (
|
||||
export const useProductTypes = (
|
||||
query?: Record<string, any>,
|
||||
options?: Omit<
|
||||
UseQueryOptions<ProductTypeListRes, Error, ProductTypeListRes, QueryKey>,
|
||||
UseQueryOptions<
|
||||
{ product_types: HttpTypes.AdminProductType[] },
|
||||
Error,
|
||||
{ product_types: HttpTypes.AdminProductType[] },
|
||||
QueryKey
|
||||
>,
|
||||
"queryKey" | "queryFn"
|
||||
>
|
||||
) => {
|
||||
|
||||
@@ -5,14 +5,9 @@ import {
|
||||
useQuery,
|
||||
UseQueryOptions,
|
||||
} from "@tanstack/react-query"
|
||||
import { client, sdk } from "../../lib/client"
|
||||
import { sdk } from "../../lib/client"
|
||||
import { queryClient } from "../../lib/query-client"
|
||||
import { queryKeysFactory } from "../../lib/query-key-factory"
|
||||
import {
|
||||
ProductDeleteRes,
|
||||
ProductListRes,
|
||||
ProductRes,
|
||||
} from "../../types/api-responses"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
const PRODUCTS_QUERY_KEY = "products" as const
|
||||
@@ -29,8 +24,8 @@ export const useCreateProductOption = (
|
||||
options?: UseMutationOptions<any, Error, any>
|
||||
) => {
|
||||
return useMutation({
|
||||
mutationFn: (payload: any) =>
|
||||
client.products.createOption(productId, payload),
|
||||
mutationFn: (payload: HttpTypes.AdminCreateProductOption) =>
|
||||
sdk.admin.product.createOption(productId, payload),
|
||||
onSuccess: (data: any, variables: any, context: any) => {
|
||||
queryClient.invalidateQueries({ queryKey: optionsQueryKeys.lists() })
|
||||
queryClient.invalidateQueries({
|
||||
@@ -48,8 +43,8 @@ export const useUpdateProductOption = (
|
||||
options?: UseMutationOptions<any, Error, any>
|
||||
) => {
|
||||
return useMutation({
|
||||
mutationFn: (payload: any) =>
|
||||
client.products.updateOption(productId, optionId, payload),
|
||||
mutationFn: (payload: HttpTypes.AdminUpdateProductOption) =>
|
||||
sdk.admin.product.updateOption(productId, optionId, payload),
|
||||
onSuccess: (data: any, variables: any, context: any) => {
|
||||
queryClient.invalidateQueries({ queryKey: optionsQueryKeys.lists() })
|
||||
queryClient.invalidateQueries({
|
||||
@@ -71,7 +66,7 @@ export const useDeleteProductOption = (
|
||||
options?: UseMutationOptions<any, Error, void>
|
||||
) => {
|
||||
return useMutation({
|
||||
mutationFn: () => client.products.deleteOption(productId, optionId),
|
||||
mutationFn: () => sdk.admin.product.deleteOption(productId, optionId),
|
||||
onSuccess: (data: any, variables: any, context: any) => {
|
||||
queryClient.invalidateQueries({ queryKey: optionsQueryKeys.lists() })
|
||||
queryClient.invalidateQueries({
|
||||
@@ -97,7 +92,8 @@ export const useProductVariant = (
|
||||
>
|
||||
) => {
|
||||
const { data, ...rest } = useQuery({
|
||||
queryFn: () => client.products.retrieveVariant(productId, variantId, query),
|
||||
queryFn: () =>
|
||||
sdk.admin.product.retrieveVariant(productId, variantId, query),
|
||||
queryKey: variantsQueryKeys.detail(variantId),
|
||||
...options,
|
||||
})
|
||||
@@ -114,7 +110,7 @@ export const useProductVariants = (
|
||||
>
|
||||
) => {
|
||||
const { data, ...rest } = useQuery({
|
||||
queryFn: () => client.products.listVariants(productId, query),
|
||||
queryFn: () => sdk.admin.product.listVariants(productId, query),
|
||||
queryKey: variantsQueryKeys.list({ productId, ...query }),
|
||||
...options,
|
||||
})
|
||||
@@ -127,8 +123,8 @@ export const useCreateProductVariant = (
|
||||
options?: UseMutationOptions<any, Error, any>
|
||||
) => {
|
||||
return useMutation({
|
||||
mutationFn: (payload: any) =>
|
||||
client.products.createVariant(productId, payload),
|
||||
mutationFn: (payload: HttpTypes.AdminCreateProductVariant) =>
|
||||
sdk.admin.product.createVariant(productId, payload),
|
||||
onSuccess: (data: any, variables: any, context: any) => {
|
||||
queryClient.invalidateQueries({ queryKey: variantsQueryKeys.lists() })
|
||||
queryClient.invalidateQueries({
|
||||
@@ -146,8 +142,8 @@ export const useUpdateProductVariant = (
|
||||
options?: UseMutationOptions<any, Error, any>
|
||||
) => {
|
||||
return useMutation({
|
||||
mutationFn: (payload: any) =>
|
||||
client.products.updateVariant(productId, variantId, payload),
|
||||
mutationFn: (payload: HttpTypes.AdminUpdateProductVariant) =>
|
||||
sdk.admin.product.updateVariant(productId, variantId, payload),
|
||||
onSuccess: (data: any, variables: any, context: any) => {
|
||||
queryClient.invalidateQueries({ queryKey: variantsQueryKeys.lists() })
|
||||
queryClient.invalidateQueries({
|
||||
@@ -168,8 +164,9 @@ export const useUpdateProductVariantsBatch = (
|
||||
options?: UseMutationOptions<any, Error, any>
|
||||
) => {
|
||||
return useMutation({
|
||||
mutationFn: (payload: any) =>
|
||||
client.products.updateVariantsBatch(productId, payload),
|
||||
mutationFn: (
|
||||
payload: HttpTypes.AdminBatchProductVariantRequest["update"]
|
||||
) => sdk.admin.product.batchVariants(productId, { update: payload }),
|
||||
onSuccess: (data: any, variables: any, context: any) => {
|
||||
queryClient.invalidateQueries({ queryKey: variantsQueryKeys.lists() })
|
||||
queryClient.invalidateQueries({
|
||||
@@ -188,7 +185,7 @@ export const useDeleteVariant = (
|
||||
options?: UseMutationOptions<any, Error, void>
|
||||
) => {
|
||||
return useMutation({
|
||||
mutationFn: () => client.products.deleteVariant(productId, variantId),
|
||||
mutationFn: () => sdk.admin.product.deleteVariant(productId, variantId),
|
||||
onSuccess: (data: any, variables: any, context: any) => {
|
||||
queryClient.invalidateQueries({ queryKey: variantsQueryKeys.lists() })
|
||||
queryClient.invalidateQueries({
|
||||
@@ -213,7 +210,7 @@ export const useProduct = (
|
||||
>
|
||||
) => {
|
||||
const { data, ...rest } = useQuery({
|
||||
queryFn: () => client.products.retrieve(id, query),
|
||||
queryFn: () => sdk.admin.product.retrieve(id, query),
|
||||
queryKey: productsQueryKeys.detail(id),
|
||||
...options,
|
||||
})
|
||||
@@ -224,12 +221,17 @@ export const useProduct = (
|
||||
export const useProducts = (
|
||||
query?: Record<string, any>,
|
||||
options?: Omit<
|
||||
UseQueryOptions<ProductListRes, Error, ProductListRes, QueryKey>,
|
||||
UseQueryOptions<
|
||||
HttpTypes.AdminProductListResponse,
|
||||
Error,
|
||||
HttpTypes.AdminProductListResponse,
|
||||
QueryKey
|
||||
>,
|
||||
"queryFn" | "queryKey"
|
||||
>
|
||||
) => {
|
||||
const { data, ...rest } = useQuery({
|
||||
queryFn: () => client.products.list(query),
|
||||
queryFn: () => sdk.admin.product.list(query),
|
||||
queryKey: productsQueryKeys.list(query),
|
||||
...options,
|
||||
})
|
||||
@@ -245,7 +247,8 @@ export const useCreateProduct = (
|
||||
>
|
||||
) => {
|
||||
return useMutation({
|
||||
mutationFn: (payload: any) => sdk.admin.product.create(payload),
|
||||
mutationFn: (payload: HttpTypes.AdminCreateProduct) =>
|
||||
sdk.admin.product.create(payload),
|
||||
onSuccess: (data: any, variables: any, context: any) => {
|
||||
queryClient.invalidateQueries({ queryKey: productsQueryKeys.lists() })
|
||||
options?.onSuccess?.(data, variables, context)
|
||||
@@ -256,10 +259,11 @@ export const useCreateProduct = (
|
||||
|
||||
export const useUpdateProduct = (
|
||||
id: string,
|
||||
options?: UseMutationOptions<ProductRes, Error, any>
|
||||
options?: UseMutationOptions<HttpTypes.AdminProductResponse, Error, any>
|
||||
) => {
|
||||
return useMutation({
|
||||
mutationFn: (payload: any) => client.products.update(id, payload),
|
||||
mutationFn: (payload: HttpTypes.AdminUpdateProduct) =>
|
||||
sdk.admin.product.update(id, payload),
|
||||
onSuccess: (data: any, variables: any, context: any) => {
|
||||
queryClient.invalidateQueries({ queryKey: productsQueryKeys.lists() })
|
||||
queryClient.invalidateQueries({ queryKey: productsQueryKeys.detail(id) })
|
||||
@@ -272,10 +276,14 @@ export const useUpdateProduct = (
|
||||
|
||||
export const useDeleteProduct = (
|
||||
id: string,
|
||||
options?: UseMutationOptions<ProductDeleteRes, Error, void>
|
||||
options?: UseMutationOptions<
|
||||
HttpTypes.AdminProductDeleteResponse,
|
||||
Error,
|
||||
void
|
||||
>
|
||||
) => {
|
||||
return useMutation({
|
||||
mutationFn: () => client.products.delete(id),
|
||||
mutationFn: () => sdk.admin.product.delete(id),
|
||||
onSuccess: (data: any, variables: any, context: any) => {
|
||||
queryClient.invalidateQueries({ queryKey: productsQueryKeys.lists() })
|
||||
queryClient.invalidateQueries({ queryKey: productsQueryKeys.detail(id) })
|
||||
|
||||
@@ -21,9 +21,9 @@ import {
|
||||
VariantCell,
|
||||
VariantHeader,
|
||||
} from "../../../components/table/table-cells/product/variant-cell"
|
||||
import { ExtendedProductDTO } from "../../../types/api-responses"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
const columnHelper = createColumnHelper<ExtendedProductDTO>()
|
||||
const columnHelper = createColumnHelper<HttpTypes.AdminProduct>()
|
||||
|
||||
export const useProductTableColumns = () => {
|
||||
return useMemo(
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import { AdminGetProductsParams } from "@medusajs/medusa"
|
||||
import { ProductStatus } from "@medusajs/types"
|
||||
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import { useQueryParams } from "../../use-query-params"
|
||||
|
||||
type UseProductTableQueryProps = {
|
||||
@@ -46,7 +44,7 @@ export const useProductTableQuery = ({
|
||||
q,
|
||||
} = queryObject
|
||||
|
||||
const searchParams: AdminGetProductsParams = {
|
||||
const searchParams: HttpTypes.AdminProductParams = {
|
||||
limit: pageSize,
|
||||
offset: offset ? Number(offset) : 0,
|
||||
sales_channel_id: sales_channel_id?.split(","),
|
||||
@@ -56,9 +54,9 @@ export const useProductTableQuery = ({
|
||||
collection_id: collection_id?.split(","),
|
||||
is_giftcard: is_giftcard ? is_giftcard === "true" : undefined,
|
||||
order: order,
|
||||
tags: tags?.split(","),
|
||||
tags: tags ? { value: tags.split(",") } : undefined,
|
||||
type_id: type_id?.split(","),
|
||||
status: status?.split(",") as ProductStatus[],
|
||||
status: status?.split(",") as HttpTypes.AdminProductStatus[],
|
||||
q,
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import { invites } from "./invites"
|
||||
import { payments } from "./payments"
|
||||
import { priceLists } from "./price-lists"
|
||||
import { productTypes } from "./product-types"
|
||||
import { products } from "./products"
|
||||
import { promotions } from "./promotions"
|
||||
import { reservations } from "./reservations"
|
||||
import { salesChannels } from "./sales-channels"
|
||||
@@ -42,7 +41,6 @@ export const client = {
|
||||
reservations: reservations,
|
||||
fulfillments: fulfillments,
|
||||
fulfillmentProviders: fulfillmentProviders,
|
||||
products: products,
|
||||
productTypes: productTypes,
|
||||
priceLists: priceLists,
|
||||
stockLocations: stockLocations,
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
import { ProductTypeListRes, ProductTypeRes } from "../../types/api-responses"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import { getRequest } from "./common"
|
||||
|
||||
async function listProductTypes(query?: Record<string, any>) {
|
||||
return getRequest<ProductTypeListRes>(`/admin/product-types`, query)
|
||||
return getRequest<{ product_types: HttpTypes.AdminProductType[] }>(
|
||||
`/admin/product-types`,
|
||||
query
|
||||
)
|
||||
}
|
||||
|
||||
async function retrieveProductType(id: string, query?: Record<string, any>) {
|
||||
return getRequest<ProductTypeRes>(`/admin/product-types/${id}`, query)
|
||||
return getRequest<{ product_type: HttpTypes.AdminProductType }>(
|
||||
`/admin/product-types/${id}`,
|
||||
query
|
||||
)
|
||||
}
|
||||
|
||||
export const productTypes = {
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
import { ProductDeleteRes, ProductListRes } from "../../types/api-responses"
|
||||
import { deleteRequest, getRequest, postRequest } from "./common"
|
||||
|
||||
async function retrieveProduct(id: string, query?: Record<string, any>) {
|
||||
return getRequest<any>(`/admin/products/${id}`, query)
|
||||
}
|
||||
|
||||
async function createProduct(payload: any) {
|
||||
return postRequest<any>(`/admin/products`, payload)
|
||||
}
|
||||
|
||||
async function listProducts(query?: Record<string, any>) {
|
||||
return getRequest<ProductListRes>(`/admin/products`, query)
|
||||
}
|
||||
|
||||
async function updateProduct(id: string, payload: any) {
|
||||
return postRequest<any>(`/admin/products/${id}`, payload)
|
||||
}
|
||||
|
||||
async function deleteProduct(id: string) {
|
||||
return deleteRequest<ProductDeleteRes>(`/admin/products/${id}`)
|
||||
}
|
||||
|
||||
async function retrieveVariant(
|
||||
productId: string,
|
||||
variantId: string,
|
||||
query?: Record<string, any>
|
||||
) {
|
||||
return getRequest<any>(
|
||||
`/admin/products/${productId}/variants/${variantId}`,
|
||||
query
|
||||
)
|
||||
}
|
||||
|
||||
async function listVariants(productId: string, query?: Record<string, any>) {
|
||||
return getRequest<any>(`/admin/products/${productId}/variants`, query)
|
||||
}
|
||||
|
||||
async function createVariant(productId: string, payload: any) {
|
||||
return postRequest<any>(`/admin/products/${productId}/variants`, payload)
|
||||
}
|
||||
|
||||
async function updateVariant(
|
||||
productId: string,
|
||||
variantId: string,
|
||||
payload: any
|
||||
) {
|
||||
return postRequest<any>(
|
||||
`/admin/products/${productId}/variants/${variantId}`,
|
||||
payload
|
||||
)
|
||||
}
|
||||
|
||||
async function updateVariantsBatch(
|
||||
productId: string,
|
||||
payload: { add: any[]; update: any[]; remove: any[] }
|
||||
) {
|
||||
return postRequest<any>(
|
||||
`/admin/products/${productId}/variants/batch`,
|
||||
payload
|
||||
)
|
||||
}
|
||||
|
||||
async function deleteVariant(productId: string, variantId: string) {
|
||||
return deleteRequest<any>(
|
||||
`/admin/products/${productId}/variants/${variantId}`
|
||||
)
|
||||
}
|
||||
|
||||
async function createOption(productId: string, payload: any) {
|
||||
return postRequest<any>(`/admin/products/${productId}/options`, payload)
|
||||
}
|
||||
|
||||
async function updateOption(productId: string, optionId: string, payload: any) {
|
||||
return postRequest<any>(
|
||||
`/admin/products/${productId}/options/${optionId}`,
|
||||
payload
|
||||
)
|
||||
}
|
||||
|
||||
async function deleteOption(productId: string, optionId: string) {
|
||||
return deleteRequest<any>(`/admin/products/${productId}/options/${optionId}`)
|
||||
}
|
||||
|
||||
export const products = {
|
||||
retrieve: retrieveProduct,
|
||||
list: listProducts,
|
||||
create: createProduct,
|
||||
update: updateProduct,
|
||||
delete: deleteProduct,
|
||||
retrieveVariant,
|
||||
listVariants,
|
||||
createVariant,
|
||||
updateVariant,
|
||||
updateVariantsBatch,
|
||||
deleteVariant,
|
||||
createOption,
|
||||
updateOption,
|
||||
deleteOption,
|
||||
}
|
||||
@@ -63,7 +63,7 @@ export const RouteMap: RouteObject[] = [
|
||||
path: ":id",
|
||||
lazy: () => import("../../routes/products/product-detail"),
|
||||
handle: {
|
||||
crumb: (data: { product: HttpTypes.AdminProduct }) =>
|
||||
crumb: (data: HttpTypes.AdminProductResponse) =>
|
||||
data.product.title,
|
||||
},
|
||||
children: [
|
||||
|
||||
+1
-2
@@ -22,7 +22,6 @@ import { useProductTableColumns } from "../../../../../hooks/table/columns/use-p
|
||||
import { useProductTableFilters } from "../../../../../hooks/table/filters/use-product-table-filters.tsx"
|
||||
import { useProductTableQuery } from "../../../../../hooks/table/query/use-product-table-query.tsx"
|
||||
import { useDataTable } from "../../../../../hooks/use-data-table.tsx"
|
||||
import { ExtendedProductDTO } from "../../../../../types/api-responses.ts"
|
||||
|
||||
type AddProductsToCollectionFormProps = {
|
||||
collection: HttpTypes.AdminCollection
|
||||
@@ -186,7 +185,7 @@ export const AddProductsToCollectionForm = ({
|
||||
)
|
||||
}
|
||||
|
||||
const columnHelper = createColumnHelper<ExtendedProductDTO>()
|
||||
const columnHelper = createColumnHelper<HttpTypes.AdminProduct>()
|
||||
|
||||
const useColumns = () => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
+2
-3
@@ -13,7 +13,6 @@ import { useProductTableColumns } from "../../../../../hooks/table/columns/use-p
|
||||
import { useProductTableFilters } from "../../../../../hooks/table/filters/use-product-table-filters"
|
||||
import { useProductTableQuery } from "../../../../../hooks/table/query/use-product-table-query"
|
||||
import { useDataTable } from "../../../../../hooks/use-data-table"
|
||||
import { ExtendedProductDTO } from "../../../../../types/api-responses"
|
||||
|
||||
type CollectionProductSectionProps = {
|
||||
collection: HttpTypes.AdminCollection
|
||||
@@ -139,7 +138,7 @@ const ProductActions = ({
|
||||
product,
|
||||
collectionId,
|
||||
}: {
|
||||
product: ExtendedProductDTO
|
||||
product: HttpTypes.AdminProduct
|
||||
collectionId: string
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
@@ -201,7 +200,7 @@ const ProductActions = ({
|
||||
)
|
||||
}
|
||||
|
||||
const columnHelper = createColumnHelper<ExtendedProductDTO>()
|
||||
const columnHelper = createColumnHelper<HttpTypes.AdminProduct>()
|
||||
|
||||
const useColumns = () => {
|
||||
const columns = useProductTableColumns()
|
||||
|
||||
+2
-2
@@ -4,16 +4,16 @@ import { useForm } from "react-hook-form"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import * as zod from "zod"
|
||||
|
||||
import { ProductCollectionDTO } from "@medusajs/types"
|
||||
import { Form } from "../../../../../components/common/form"
|
||||
import {
|
||||
RouteDrawer,
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
import { useUpdateCollection } from "../../../../../hooks/api/collections"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type EditCollectionFormProps = {
|
||||
collection: ProductCollectionDTO
|
||||
collection: HttpTypes.AdminCollection
|
||||
}
|
||||
|
||||
const EditCollectionSchema = zod.object({
|
||||
|
||||
+4
-4
@@ -1,15 +1,15 @@
|
||||
import { Container, Heading } from "@medusajs/ui"
|
||||
import { ProductVariantDTO } from "@medusajs/types"
|
||||
|
||||
import { ActionMenu } from "../../../../components/common/action-menu"
|
||||
import { InventoryItemRes } from "../../../../types/api-responses"
|
||||
import { PencilSquare } from "@medusajs/icons"
|
||||
import { SectionRow } from "../../../../components/common/section"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type InventoryItemGeneralSectionProps = {
|
||||
inventoryItem: InventoryItemRes["inventory_item"] & {
|
||||
variant: ProductVariantDTO | ProductVariantDTO[]
|
||||
variant: HttpTypes.AdminProductVariant | HttpTypes.AdminProductVariant[]
|
||||
}
|
||||
}
|
||||
export const InventoryItemGeneralSection = ({
|
||||
@@ -74,7 +74,7 @@ export const InventoryItemGeneralSection = ({
|
||||
)
|
||||
}
|
||||
|
||||
const getQuantityFormat = (quantity: number, locations: number) => {
|
||||
const getQuantityFormat = (quantity: number, locations?: number) => {
|
||||
return `${quantity ?? "-"}
|
||||
${quantity ? `across ${locations} locations` : ""}`
|
||||
${quantity ? `across ${locations ?? "-"} locations` : ""}`
|
||||
}
|
||||
|
||||
+42
-42
@@ -1,4 +1,4 @@
|
||||
import { CurrencyDTO, HttpTypes, ProductVariantDTO } from "@medusajs/types"
|
||||
import { CurrencyDTO, HttpTypes } from "@medusajs/types"
|
||||
import { ColumnDef, createColumnHelper } from "@tanstack/react-table"
|
||||
import { useEffect, useMemo, useState } from "react"
|
||||
import { UseFormReturn } from "react-hook-form"
|
||||
@@ -9,7 +9,6 @@ import { CurrencyCell } from "../../../../../components/grid/grid-cells/common/c
|
||||
import { DataGrid } from "../../../../../components/grid/data-grid"
|
||||
import { DataGridMeta } from "../../../../../components/grid/types"
|
||||
import { useCurrencies } from "../../../../../hooks/api/currencies"
|
||||
import { ExtendedProductDTO } from "../../../../../types/api-responses"
|
||||
import { useRegions } from "../../../../../hooks/api/regions"
|
||||
import { useStore } from "../../../../../hooks/api/store"
|
||||
|
||||
@@ -95,7 +94,7 @@ export const CreateShippingOptionsPricesForm = ({
|
||||
}
|
||||
|
||||
const columnHelper = createColumnHelper<
|
||||
ExtendedProductDTO | ProductVariantDTO
|
||||
HttpTypes.AdminProduct | HttpTypes.AdminProductVariant
|
||||
>()
|
||||
|
||||
const useColumns = ({
|
||||
@@ -107,45 +106,46 @@ const useColumns = ({
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const colDefs: ColumnDef<ExtendedProductDTO | ProductVariantDTO>[] =
|
||||
useMemo(() => {
|
||||
return [
|
||||
...currencies.map((currency) => {
|
||||
return columnHelper.display({
|
||||
header: t("fields.priceTemplate", {
|
||||
regionOrCountry: currency.code.toUpperCase(),
|
||||
}),
|
||||
cell: ({ row, table }) => {
|
||||
return (
|
||||
<CurrencyCell
|
||||
currency={currency}
|
||||
meta={table.options.meta as DataGridMeta<any>}
|
||||
field={`currency_prices.${currency.code}`}
|
||||
/>
|
||||
)
|
||||
},
|
||||
})
|
||||
}),
|
||||
...regions.map((region) => {
|
||||
return columnHelper.display({
|
||||
header: t("fields.priceTemplate", {
|
||||
regionOrCountry: region.name,
|
||||
}),
|
||||
cell: ({ row, table }) => {
|
||||
return (
|
||||
<CurrencyCell
|
||||
currency={currencies.find(
|
||||
(c) => c.code === region.currency_code
|
||||
)}
|
||||
meta={table.options.meta as DataGridMeta<any>}
|
||||
field={`region_prices.${region.id}`}
|
||||
/>
|
||||
)
|
||||
},
|
||||
})
|
||||
}),
|
||||
]
|
||||
}, [t, currencies, regions])
|
||||
const colDefs: ColumnDef<
|
||||
HttpTypes.AdminProduct | HttpTypes.AdminProductVariant
|
||||
>[] = useMemo(() => {
|
||||
return [
|
||||
...currencies.map((currency) => {
|
||||
return columnHelper.display({
|
||||
header: t("fields.priceTemplate", {
|
||||
regionOrCountry: currency.code.toUpperCase(),
|
||||
}),
|
||||
cell: ({ row, table }) => {
|
||||
return (
|
||||
<CurrencyCell
|
||||
currency={currency}
|
||||
meta={table.options.meta as DataGridMeta<any>}
|
||||
field={`currency_prices.${currency.code}`}
|
||||
/>
|
||||
)
|
||||
},
|
||||
})
|
||||
}),
|
||||
...regions.map((region) => {
|
||||
return columnHelper.display({
|
||||
header: t("fields.priceTemplate", {
|
||||
regionOrCountry: region.name,
|
||||
}),
|
||||
cell: ({ row, table }) => {
|
||||
return (
|
||||
<CurrencyCell
|
||||
currency={currencies.find(
|
||||
(c) => c.code === region.currency_code
|
||||
)}
|
||||
meta={table.options.meta as DataGridMeta<any>}
|
||||
field={`region_prices.${region.id}`}
|
||||
/>
|
||||
)
|
||||
},
|
||||
})
|
||||
}),
|
||||
]
|
||||
}, [t, currencies, regions])
|
||||
|
||||
return colDefs
|
||||
}
|
||||
|
||||
+42
-43
@@ -6,13 +6,12 @@ import * as zod from "zod"
|
||||
import {
|
||||
CurrencyDTO,
|
||||
PriceDTO,
|
||||
ProductVariantDTO,
|
||||
ShippingOptionDTO,
|
||||
HttpTypes,
|
||||
} from "@medusajs/types"
|
||||
import { Button, toast } from "@medusajs/ui"
|
||||
import { useTranslation } from "react-i18next"
|
||||
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import { ColumnDef, createColumnHelper } from "@tanstack/react-table"
|
||||
import { DataGrid } from "../../../../../components/grid/data-grid/index"
|
||||
import { CurrencyCell } from "../../../../../components/grid/grid-cells/common/currency-cell/index"
|
||||
@@ -25,7 +24,6 @@ import { useCurrencies } from "../../../../../hooks/api/currencies"
|
||||
import { useRegions } from "../../../../../hooks/api/regions"
|
||||
import { useUpdateShippingOptions } from "../../../../../hooks/api/shipping-options"
|
||||
import { useStore } from "../../../../../hooks/api/store"
|
||||
import { ExtendedProductDTO } from "../../../../../types/api-responses"
|
||||
import { castNumber } from "../../../../../lib/cast-number.ts"
|
||||
|
||||
const getInitialCurrencyPrices = (prices: PriceDTO[]) => {
|
||||
@@ -254,7 +252,7 @@ export function EditShippingOptionsPricingForm({
|
||||
}
|
||||
|
||||
const columnHelper = createColumnHelper<
|
||||
ExtendedProductDTO | ProductVariantDTO
|
||||
HttpTypes.AdminProduct | HttpTypes.AdminProductVariant
|
||||
>()
|
||||
|
||||
const useColumns = ({
|
||||
@@ -266,45 +264,46 @@ const useColumns = ({
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const colDefs: ColumnDef<ExtendedProductDTO | ProductVariantDTO>[] =
|
||||
useMemo(() => {
|
||||
return [
|
||||
...currencies.map((currency) => {
|
||||
return columnHelper.display({
|
||||
header: t("fields.priceTemplate", {
|
||||
regionOrCountry: currency.code.toUpperCase(),
|
||||
}),
|
||||
cell: ({ row, table }) => {
|
||||
return (
|
||||
<CurrencyCell
|
||||
currency={currency}
|
||||
meta={table.options.meta as DataGridMeta<any>}
|
||||
field={`currency_prices.${currency.code}`}
|
||||
/>
|
||||
)
|
||||
},
|
||||
})
|
||||
}),
|
||||
...regions.map((region) => {
|
||||
return columnHelper.display({
|
||||
header: t("fields.priceTemplate", {
|
||||
regionOrCountry: region.name,
|
||||
}),
|
||||
cell: ({ row, table }) => {
|
||||
return (
|
||||
<CurrencyCell
|
||||
currency={currencies.find(
|
||||
(c) => c.code === region.currency_code
|
||||
)}
|
||||
meta={table.options.meta as DataGridMeta<any>}
|
||||
field={`region_prices.${region.id}`}
|
||||
/>
|
||||
)
|
||||
},
|
||||
})
|
||||
}),
|
||||
]
|
||||
}, [t, currencies, regions])
|
||||
const colDefs: ColumnDef<
|
||||
HttpTypes.AdminProduct | HttpTypes.AdminProductVariant
|
||||
>[] = useMemo(() => {
|
||||
return [
|
||||
...currencies.map((currency) => {
|
||||
return columnHelper.display({
|
||||
header: t("fields.priceTemplate", {
|
||||
regionOrCountry: currency.code.toUpperCase(),
|
||||
}),
|
||||
cell: ({ row, table }) => {
|
||||
return (
|
||||
<CurrencyCell
|
||||
currency={currency}
|
||||
meta={table.options.meta as DataGridMeta<any>}
|
||||
field={`currency_prices.${currency.code}`}
|
||||
/>
|
||||
)
|
||||
},
|
||||
})
|
||||
}),
|
||||
...regions.map((region) => {
|
||||
return columnHelper.display({
|
||||
header: t("fields.priceTemplate", {
|
||||
regionOrCountry: region.name,
|
||||
}),
|
||||
cell: ({ row, table }) => {
|
||||
return (
|
||||
<CurrencyCell
|
||||
currency={currencies.find(
|
||||
(c) => c.code === region.currency_code
|
||||
)}
|
||||
meta={table.options.meta as DataGridMeta<any>}
|
||||
field={`region_prices.${region.id}`}
|
||||
/>
|
||||
)
|
||||
},
|
||||
})
|
||||
}),
|
||||
]
|
||||
}, [t, currencies, regions])
|
||||
|
||||
return colDefs
|
||||
}
|
||||
|
||||
+2
-7
@@ -1,10 +1,5 @@
|
||||
import { Buildings, XCircle } from "@medusajs/icons"
|
||||
import {
|
||||
AdminOrder,
|
||||
FulfillmentDTO,
|
||||
OrderLineItemDTO,
|
||||
ProductVariantDTO,
|
||||
} from "@medusajs/types"
|
||||
import { AdminOrder, FulfillmentDTO, OrderLineItemDTO } from "@medusajs/types"
|
||||
import {
|
||||
Container,
|
||||
Copy,
|
||||
@@ -49,7 +44,7 @@ const UnfulfilledItem = ({
|
||||
item,
|
||||
currencyCode,
|
||||
}: {
|
||||
item: OrderLineItemDTO & { variant: ProductVariantDTO }
|
||||
item: OrderLineItemDTO & { variant: HttpTypes.AdminProductVariant }
|
||||
currencyCode: string
|
||||
}) => {
|
||||
return (
|
||||
|
||||
+46
-46
@@ -1,4 +1,4 @@
|
||||
import { CurrencyDTO, ProductVariantDTO } from "@medusajs/types"
|
||||
import { CurrencyDTO, HttpTypes } from "@medusajs/types"
|
||||
import { ColumnDef, createColumnHelper } from "@tanstack/react-table"
|
||||
import { useMemo } from "react"
|
||||
import { useTranslation } from "react-i18next"
|
||||
@@ -7,11 +7,10 @@ import { CurrencyCell } from "../../../../components/grid/grid-cells/common/curr
|
||||
import { ReadonlyCell } from "../../../../components/grid/grid-cells/common/readonly-cell"
|
||||
import { VoidCell } from "../../../../components/grid/grid-cells/common/void-cell"
|
||||
import { DataGridMeta } from "../../../../components/grid/types"
|
||||
import { ExtendedProductDTO } from "../../../../types/api-responses"
|
||||
import { isProductRow } from "../utils"
|
||||
|
||||
const columnHelper = createColumnHelper<
|
||||
ExtendedProductDTO | ProductVariantDTO
|
||||
HttpTypes.AdminProduct | HttpTypes.AdminProductVariant
|
||||
>()
|
||||
|
||||
export const usePriceListGridColumns = ({
|
||||
@@ -21,57 +20,58 @@ export const usePriceListGridColumns = ({
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const colDefs: ColumnDef<ExtendedProductDTO | ProductVariantDTO>[] =
|
||||
useMemo(() => {
|
||||
return [
|
||||
columnHelper.display({
|
||||
id: t("fields.title"),
|
||||
header: t("fields.title"),
|
||||
cell: ({ row }) => {
|
||||
const colDefs: ColumnDef<
|
||||
HttpTypes.AdminProduct | HttpTypes.AdminProductVariant
|
||||
>[] = useMemo(() => {
|
||||
return [
|
||||
columnHelper.display({
|
||||
id: t("fields.title"),
|
||||
header: t("fields.title"),
|
||||
cell: ({ row }) => {
|
||||
const entity = row.original
|
||||
|
||||
if (isProductRow(entity)) {
|
||||
return (
|
||||
<VoidCell>
|
||||
<div className="flex h-full w-full items-center gap-x-2 overflow-hidden">
|
||||
<Thumbnail src={entity.thumbnail} />
|
||||
<span className="truncate">{entity.title}</span>
|
||||
</div>
|
||||
</VoidCell>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<ReadonlyCell>
|
||||
<div className="flex h-full w-full items-center gap-x-2 overflow-hidden">
|
||||
<span className="truncate">{entity.title}</span>
|
||||
</div>
|
||||
</ReadonlyCell>
|
||||
)
|
||||
},
|
||||
}),
|
||||
...currencies.map((currency) => {
|
||||
return columnHelper.display({
|
||||
header: `Price ${currency.code.toUpperCase()}`,
|
||||
cell: ({ row, table }) => {
|
||||
const entity = row.original
|
||||
|
||||
if (isProductRow(entity)) {
|
||||
return (
|
||||
<VoidCell>
|
||||
<div className="flex h-full w-full items-center gap-x-2 overflow-hidden">
|
||||
<Thumbnail src={entity.thumbnail} />
|
||||
<span className="truncate">{entity.title}</span>
|
||||
</div>
|
||||
</VoidCell>
|
||||
)
|
||||
return <VoidCell />
|
||||
}
|
||||
|
||||
return (
|
||||
<ReadonlyCell>
|
||||
<div className="flex h-full w-full items-center gap-x-2 overflow-hidden">
|
||||
<span className="truncate">{entity.title}</span>
|
||||
</div>
|
||||
</ReadonlyCell>
|
||||
<CurrencyCell
|
||||
currency={currency}
|
||||
meta={table.options.meta as DataGridMeta}
|
||||
field={`products.${entity.product_id}.variants.${entity.id}.currency_prices.${currency.code}.amount`}
|
||||
/>
|
||||
)
|
||||
},
|
||||
}),
|
||||
...currencies.map((currency) => {
|
||||
return columnHelper.display({
|
||||
header: `Price ${currency.code.toUpperCase()}`,
|
||||
cell: ({ row, table }) => {
|
||||
const entity = row.original
|
||||
|
||||
if (isProductRow(entity)) {
|
||||
return <VoidCell />
|
||||
}
|
||||
|
||||
return (
|
||||
<CurrencyCell
|
||||
currency={currency}
|
||||
meta={table.options.meta as DataGridMeta}
|
||||
field={`products.${entity.product_id}.variants.${entity.id}.currency_prices.${currency.code}.amount`}
|
||||
/>
|
||||
)
|
||||
},
|
||||
})
|
||||
}),
|
||||
]
|
||||
}, [t, currencies])
|
||||
})
|
||||
}),
|
||||
]
|
||||
}, [t, currencies])
|
||||
|
||||
return colDefs
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { PriceListDTO, ProductVariantDTO } from "@medusajs/types"
|
||||
import { PriceListDTO, HttpTypes } from "@medusajs/types"
|
||||
import { TFunction } from "i18next"
|
||||
import { ExtendedProductDTO } from "../../../types/api-responses"
|
||||
import { PriceListStatus } from "./constants"
|
||||
|
||||
const getValues = (priceList: PriceListDTO) => {
|
||||
@@ -49,7 +48,7 @@ export const getPriceListStatus = (
|
||||
}
|
||||
|
||||
export const isProductRow = (
|
||||
row: ExtendedProductDTO | ProductVariantDTO
|
||||
): row is ExtendedProductDTO => {
|
||||
row: HttpTypes.AdminProduct | HttpTypes.AdminProductVariant
|
||||
): row is HttpTypes.AdminProduct => {
|
||||
return "variants" in row
|
||||
}
|
||||
|
||||
+2
-2
@@ -13,9 +13,9 @@ import { useProductTableColumns } from "../../../../../hooks/table/columns/use-p
|
||||
import { useProductTableFilters } from "../../../../../hooks/table/filters/use-product-table-filters"
|
||||
import { useProductTableQuery } from "../../../../../hooks/table/query/use-product-table-query"
|
||||
import { useDataTable } from "../../../../../hooks/use-data-table"
|
||||
import { ExtendedProductDTO } from "../../../../../types/api-responses"
|
||||
import { PricingProductsRecordType } from "../../../common/schemas"
|
||||
import { PricingCreateSchemaType } from "./schema"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type PricingProductsFormProps = {
|
||||
form: UseFormReturn<PricingCreateSchemaType>
|
||||
@@ -132,7 +132,7 @@ export const PricingProductsForm = ({ form }: PricingProductsFormProps) => {
|
||||
)
|
||||
}
|
||||
|
||||
const columnHelper = createColumnHelper<ExtendedProductDTO>()
|
||||
const columnHelper = createColumnHelper<HttpTypes.AdminProduct>()
|
||||
|
||||
const useColumns = () => {
|
||||
const base = useProductTableColumns()
|
||||
|
||||
+3
-4
@@ -1,5 +1,5 @@
|
||||
import { PencilSquare, Plus, Trash } from "@medusajs/icons"
|
||||
import { PriceListDTO } from "@medusajs/types"
|
||||
import { PriceListDTO, HttpTypes } from "@medusajs/types"
|
||||
import { Checkbox, Container, Heading, usePrompt } from "@medusajs/ui"
|
||||
import { keepPreviousData } from "@tanstack/react-query"
|
||||
import { RowSelectionState, createColumnHelper } from "@tanstack/react-table"
|
||||
@@ -13,7 +13,6 @@ import { useProductTableColumns } from "../../../../../hooks/table/columns/use-p
|
||||
import { useProductTableFilters } from "../../../../../hooks/table/filters/use-product-table-filters"
|
||||
import { useProductTableQuery } from "../../../../../hooks/table/query/use-product-table-query"
|
||||
import { useDataTable } from "../../../../../hooks/use-data-table"
|
||||
import { ExtendedProductDTO } from "../../../../../types/api-responses"
|
||||
|
||||
type PricingProductSectionProps = {
|
||||
priceList: PriceListDTO
|
||||
@@ -145,7 +144,7 @@ export const PricingProductSection = ({
|
||||
)
|
||||
}
|
||||
|
||||
const ProductRowAction = ({ product }: { product: ExtendedProductDTO }) => {
|
||||
const ProductRowAction = ({ product }: { product: HttpTypes.AdminProduct }) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
// TODO: The endpoint to remove prices by product id is not implemented in v2.
|
||||
@@ -171,7 +170,7 @@ const ProductRowAction = ({ product }: { product: ExtendedProductDTO }) => {
|
||||
)
|
||||
}
|
||||
|
||||
const columnHelper = createColumnHelper<ExtendedProductDTO>()
|
||||
const columnHelper = createColumnHelper<HttpTypes.AdminProduct>()
|
||||
|
||||
const useColumns = () => {
|
||||
const base = useProductTableColumns()
|
||||
|
||||
+3
-3
@@ -2,6 +2,7 @@ import {
|
||||
CreatePriceListPriceDTO,
|
||||
PriceListDTO,
|
||||
UpdatePriceListPriceDTO,
|
||||
HttpTypes,
|
||||
} from "@medusajs/types"
|
||||
import { Button } from "@medusajs/ui"
|
||||
import { UseFormReturn, useForm, useWatch } from "react-hook-form"
|
||||
@@ -23,7 +24,6 @@ import {
|
||||
} from "../../../../../hooks/api/price-lists"
|
||||
import { useStore } from "../../../../../hooks/api/store"
|
||||
import { castNumber } from "../../../../../lib/cast-number"
|
||||
import { ExtendedProductDTO } from "../../../../../types/api-responses"
|
||||
import { usePriceListGridColumns } from "../../../common/hooks/use-price-list-grid-columns"
|
||||
import {
|
||||
PricingProductsRecordSchema,
|
||||
@@ -33,7 +33,7 @@ import { isProductRow } from "../../../common/utils"
|
||||
|
||||
type PricingProductPricesFormProps = {
|
||||
priceList: PriceListDTO
|
||||
products: ExtendedProductDTO[]
|
||||
products: HttpTypes.AdminProduct[]
|
||||
}
|
||||
|
||||
const PricingProductPricesSchema = z.object({
|
||||
@@ -245,7 +245,7 @@ export const PricingProductPricesForm = ({
|
||||
}
|
||||
|
||||
function initDefaultValues(
|
||||
products: ExtendedProductDTO[],
|
||||
products: HttpTypes.AdminProduct[],
|
||||
existingProducts: any,
|
||||
form: UseFormReturn<z.infer<typeof PricingProductPricesSchema>>,
|
||||
record: VariantsPriceRecord
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { CurrencyDTO, ProductVariantDTO } from "@medusajs/types"
|
||||
import { CurrencyDTO, HttpTypes } from "@medusajs/types"
|
||||
import { ColumnDef, createColumnHelper } from "@tanstack/react-table"
|
||||
import { useMemo } from "react"
|
||||
import { UseFormReturn, useWatch } from "react-hook-form"
|
||||
@@ -48,7 +48,7 @@ export const VariantPricingForm = ({ form }: VariantPricingFormProps) => {
|
||||
)
|
||||
}
|
||||
|
||||
const columnHelper = createColumnHelper<ProductVariantDTO>()
|
||||
const columnHelper = createColumnHelper<HttpTypes.AdminProductVariant>()
|
||||
|
||||
export const useVariantPriceGridColumns = ({
|
||||
currencies = [],
|
||||
@@ -57,7 +57,7 @@ export const useVariantPriceGridColumns = ({
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const colDefs: ColumnDef<ProductVariantDTO>[] = useMemo(() => {
|
||||
const colDefs: ColumnDef<HttpTypes.AdminProductVariant>[] = useMemo(() => {
|
||||
return [
|
||||
columnHelper.display({
|
||||
id: t("fields.title"),
|
||||
|
||||
+2
-2
@@ -1,5 +1,4 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { Product } from "@medusajs/medusa"
|
||||
import { Button, Input } from "@medusajs/ui"
|
||||
import { useForm } from "react-hook-form"
|
||||
import { useTranslation } from "react-i18next"
|
||||
@@ -11,9 +10,10 @@ import {
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
import { useUpdateProduct } from "../../../../../hooks/api/products"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type ProductAttributesFormProps = {
|
||||
product: Product
|
||||
product: HttpTypes.AdminProduct
|
||||
}
|
||||
|
||||
const dimension = zod
|
||||
|
||||
+2
-2
@@ -1,5 +1,4 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { Product } from "@medusajs/medusa"
|
||||
import { Button, Input, toast } from "@medusajs/ui"
|
||||
import { useForm } from "react-hook-form"
|
||||
import { useTranslation } from "react-i18next"
|
||||
@@ -12,9 +11,10 @@ import {
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
import { useCreateProductOption } from "../../../../../hooks/api/products"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type EditProductOptionsFormProps = {
|
||||
product: Product
|
||||
product: HttpTypes.AdminProduct
|
||||
}
|
||||
|
||||
const CreateProductOptionSchema = z.object({
|
||||
|
||||
+2
-2
@@ -1,5 +1,4 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { Product } from "@medusajs/medusa"
|
||||
import { Button, Heading, Input, Switch } from "@medusajs/ui"
|
||||
import { useForm } from "react-hook-form"
|
||||
import { useTranslation } from "react-i18next"
|
||||
@@ -17,9 +16,10 @@ import {
|
||||
import { useCreateProductVariant } from "../../../../../hooks/api/products"
|
||||
import { castNumber } from "../../../../../lib/cast-number"
|
||||
import { optionalInt } from "../../../../../lib/validation"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type CreateProductVariantFormProps = {
|
||||
product: Product
|
||||
product: HttpTypes.AdminProduct
|
||||
isStockAndInventoryEnabled?: boolean
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -3,7 +3,7 @@ import { Button, ProgressStatus, ProgressTabs, toast } from "@medusajs/ui"
|
||||
import { useEffect, useMemo, useState } from "react"
|
||||
import { useForm, useWatch } from "react-hook-form"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { SalesChannelDTO } from "@medusajs/types"
|
||||
import { SalesChannelDTO, HttpTypes } from "@medusajs/types"
|
||||
import {
|
||||
RouteFocusModal,
|
||||
useRouteModal,
|
||||
@@ -21,7 +21,6 @@ import { ProductCreateInventoryKitForm } from "../product-create-inventory-kit-f
|
||||
import { ProductCreateVariantsForm } from "../product-create-variants-form"
|
||||
import { isFetchError } from "../../../../../lib/is-fetch-error"
|
||||
import { sdk } from "../../../../../lib/client"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
enum Tab {
|
||||
DETAILS = "details",
|
||||
|
||||
+2
-3
@@ -1,4 +1,4 @@
|
||||
import { ProductVariantDTO, RegionDTO } from "@medusajs/types"
|
||||
import { HttpTypes, RegionDTO } from "@medusajs/types"
|
||||
import { useMemo } from "react"
|
||||
import { UseFormReturn, useWatch } from "react-hook-form"
|
||||
import { useTranslation } from "react-i18next"
|
||||
@@ -10,7 +10,6 @@ import { DataGridTextCell } from "../../../../../components/data-grid/data-grid-
|
||||
import { createDataGridHelper } from "../../../../../components/data-grid/utils"
|
||||
import { DataGridCurrencyCell } from "../../../../../components/data-grid/data-grid-cells/data-grid-currency-cell"
|
||||
import { DataGridBooleanCell } from "../../../../../components/data-grid/data-grid-cells/data-grid-boolean-cell"
|
||||
import { DataGridCountrySelectCell } from "../../../../../components/data-grid/data-grid-cells/data-grid-country-select-cell"
|
||||
import { useRegions } from "../../../../../hooks/api/regions"
|
||||
|
||||
type ProductCreateVariantsFormProps = {
|
||||
@@ -64,7 +63,7 @@ export const ProductCreateVariantsForm = ({
|
||||
)
|
||||
}
|
||||
|
||||
const columnHelper = createDataGridHelper<ProductVariantDTO>()
|
||||
const columnHelper = createDataGridHelper<HttpTypes.AdminProductVariant>()
|
||||
|
||||
const useColumns = ({
|
||||
options,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { CreateProductDTO } from "@medusajs/types"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import { ProductCreateSchemaType } from "./types"
|
||||
import { castNumber } from "../../../lib/cast-number"
|
||||
|
||||
export const normalizeProductFormValues = (
|
||||
values: ProductCreateSchemaType & { status: CreateProductDTO["status"] }
|
||||
values: ProductCreateSchemaType & { status: HttpTypes.AdminProductStatus }
|
||||
) => {
|
||||
const thumbnail = values.media?.find((media) => media.isThumbnail)?.url
|
||||
const images = values.media
|
||||
|
||||
+2
-2
@@ -1,13 +1,13 @@
|
||||
import { PencilSquare } from "@medusajs/icons"
|
||||
import { Product } from "@medusajs/medusa"
|
||||
import { Container, Heading, Text } from "@medusajs/ui"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { ActionMenu } from "../../../../../components/common/action-menu"
|
||||
import { SectionRow } from "../../../../../components/common/section"
|
||||
import { getFormattedCountry } from "../../../../../lib/addresses"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type ProductAttributeSectionProps = {
|
||||
product: Product
|
||||
product: HttpTypes.AdminProduct
|
||||
}
|
||||
|
||||
export const ProductAttributeSection = ({
|
||||
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
import { PencilSquare, Trash } from "@medusajs/icons"
|
||||
import { Product } from "@medusajs/medusa"
|
||||
import { Container, Heading, StatusBadge, usePrompt } from "@medusajs/ui"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { useNavigate } from "react-router-dom"
|
||||
import { ActionMenu } from "../../../../../components/common/action-menu"
|
||||
import { SectionRow } from "../../../../../components/common/section"
|
||||
import { useDeleteProduct } from "../../../../../hooks/api/products"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
const productStatusColor = (status: string) => {
|
||||
switch (status) {
|
||||
@@ -23,7 +23,7 @@ const productStatusColor = (status: string) => {
|
||||
}
|
||||
|
||||
type ProductGeneralSectionProps = {
|
||||
product: Product
|
||||
product: HttpTypes.AdminProduct
|
||||
}
|
||||
|
||||
export const ProductGeneralSection = ({
|
||||
|
||||
+2
-2
@@ -1,5 +1,4 @@
|
||||
import { PencilSquare, ThumbnailBadge } from "@medusajs/icons"
|
||||
import { Product } from "@medusajs/medusa"
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
@@ -16,9 +15,10 @@ import { useTranslation } from "react-i18next"
|
||||
import { Link } from "react-router-dom"
|
||||
import { ActionMenu } from "../../../../../components/common/action-menu"
|
||||
import { useUpdateProduct } from "../../../../../hooks/api/products"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type ProductMedisaSectionProps = {
|
||||
product: Product
|
||||
product: HttpTypes.AdminProduct
|
||||
}
|
||||
|
||||
export const ProductMediaSection = ({ product }: ProductMedisaSectionProps) => {
|
||||
|
||||
+6
-6
@@ -1,17 +1,17 @@
|
||||
import { PencilSquare, Plus, Trash } from "@medusajs/icons"
|
||||
import { Product } from "@medusajs/medusa"
|
||||
import { Badge, Container, Heading, usePrompt } from "@medusajs/ui"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { ActionMenu } from "../../../../../components/common/action-menu"
|
||||
import { SectionRow } from "../../../../../components/common/section"
|
||||
import { useDeleteProductOption } from "../../../../../hooks/api/products"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
const OptionActions = ({
|
||||
product,
|
||||
option,
|
||||
}: {
|
||||
product: Product
|
||||
option: any
|
||||
product: HttpTypes.AdminProduct
|
||||
option: HttpTypes.AdminProductOption
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const { mutateAsync } = useDeleteProductOption(product.id, option.id)
|
||||
@@ -61,7 +61,7 @@ const OptionActions = ({
|
||||
}
|
||||
|
||||
type ProductOptionSectionProps = {
|
||||
product: Product
|
||||
product: HttpTypes.AdminProduct
|
||||
}
|
||||
|
||||
export const ProductOptionSection = ({
|
||||
@@ -88,12 +88,12 @@ export const ProductOptionSection = ({
|
||||
/>
|
||||
</div>
|
||||
|
||||
{product.options.map((option) => {
|
||||
{product.options?.map((option) => {
|
||||
return (
|
||||
<SectionRow
|
||||
title={option.title}
|
||||
key={option.id}
|
||||
value={option.values.map((val) => {
|
||||
value={option.values?.map((val) => {
|
||||
return (
|
||||
<Badge
|
||||
key={val.value}
|
||||
|
||||
+4
-4
@@ -1,13 +1,13 @@
|
||||
import { PencilSquare } from "@medusajs/icons"
|
||||
import { Product } from "@medusajs/medusa"
|
||||
import { Badge, Container, Heading } from "@medusajs/ui"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { Link } from "react-router-dom"
|
||||
import { ActionMenu } from "../../../../../components/common/action-menu"
|
||||
import { SectionRow } from "../../../../../components/common/section"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type ProductOrganizationSectionProps = {
|
||||
product: Product
|
||||
product: HttpTypes.AdminProduct
|
||||
}
|
||||
|
||||
export const ProductOrganizationSection = ({
|
||||
@@ -37,7 +37,7 @@ export const ProductOrganizationSection = ({
|
||||
<SectionRow
|
||||
title={t("fields.tags")}
|
||||
value={
|
||||
product.tags.length > 0
|
||||
product.tags?.length
|
||||
? product.tags.map((tag) => (
|
||||
<Badge key={tag.id} className="w-fit" size="2xsmall" asChild>
|
||||
<Link to={`/products?tags=${tag.id}`}>{tag.value}</Link>
|
||||
@@ -75,7 +75,7 @@ export const ProductOrganizationSection = ({
|
||||
<SectionRow
|
||||
title={t("fields.categories")}
|
||||
value={
|
||||
product.categories?.length > 0
|
||||
product.categories?.length
|
||||
? product.categories.map((pcat) => (
|
||||
<Badge
|
||||
key={pcat.id}
|
||||
|
||||
+2
-2
@@ -1,12 +1,12 @@
|
||||
import { Channels, PencilSquare } from "@medusajs/icons"
|
||||
import { Product } from "@medusajs/medusa"
|
||||
import { Container, Heading, Text, Tooltip } from "@medusajs/ui"
|
||||
import { Trans, useTranslation } from "react-i18next"
|
||||
import { ActionMenu } from "../../../../../components/common/action-menu"
|
||||
import { useSalesChannels } from "../../../../../hooks/api/sales-channels"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type ProductSalesChannelSectionProps = {
|
||||
product: Product
|
||||
product: HttpTypes.AdminProduct
|
||||
}
|
||||
|
||||
// TODO: The fetched sales channel doesn't contain all necessary info
|
||||
|
||||
+2
-2
@@ -1,7 +1,6 @@
|
||||
import { PencilSquare, Plus } from "@medusajs/icons"
|
||||
import { Container, Heading } from "@medusajs/ui"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { ProductDTO } from "@medusajs/types"
|
||||
import { keepPreviousData } from "@tanstack/react-query"
|
||||
|
||||
import { ActionMenu } from "../../../../../components/common/action-menu"
|
||||
@@ -11,9 +10,10 @@ import { useProductVariantTableColumns } from "./use-variant-table-columns"
|
||||
import { useProductVariantTableFilters } from "./use-variant-table-filters"
|
||||
import { useProductVariantTableQuery } from "./use-variant-table-query"
|
||||
import { useProductVariants } from "../../../../../hooks/api/products"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type ProductVariantSectionProps = {
|
||||
product: ProductDTO
|
||||
product: HttpTypes.AdminProduct
|
||||
}
|
||||
|
||||
const PAGE_SIZE = 10
|
||||
|
||||
+10
-6
@@ -1,5 +1,4 @@
|
||||
import { PencilSquare, Trash } from "@medusajs/icons"
|
||||
import { Product, ProductVariant } from "@medusajs/medusa"
|
||||
import { Badge, usePrompt } from "@medusajs/ui"
|
||||
import { createColumnHelper } from "@tanstack/react-table"
|
||||
import { useMemo } from "react"
|
||||
@@ -8,13 +7,14 @@ import { useTranslation } from "react-i18next"
|
||||
import { ActionMenu } from "../../../../../components/common/action-menu"
|
||||
import { PlaceholderCell } from "../../../../../components/table/table-cells/common/placeholder-cell"
|
||||
import { useDeleteVariant } from "../../../../../hooks/api/products"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
const VariantActions = ({
|
||||
variant,
|
||||
product,
|
||||
}: {
|
||||
variant: ProductVariant
|
||||
product: Product
|
||||
variant: HttpTypes.AdminProductVariant
|
||||
product: HttpTypes.AdminProduct
|
||||
}) => {
|
||||
const { mutateAsync } = useDeleteVariant(product.id, variant.id)
|
||||
const { t } = useTranslation()
|
||||
@@ -63,9 +63,11 @@ const VariantActions = ({
|
||||
)
|
||||
}
|
||||
|
||||
const columnHelper = createColumnHelper<ProductVariant>()
|
||||
const columnHelper = createColumnHelper<HttpTypes.AdminProductVariant>()
|
||||
|
||||
export const useProductVariantTableColumns = (product?: Product) => {
|
||||
export const useProductVariantTableColumns = (
|
||||
product?: HttpTypes.AdminProduct
|
||||
) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const optionColumns = useMemo(() => {
|
||||
@@ -141,7 +143,9 @@ export const useProductVariantTableColumns = (product?: Product) => {
|
||||
columnHelper.display({
|
||||
id: "actions",
|
||||
cell: ({ row, table }) => {
|
||||
const { product } = table.options.meta as { product: Product }
|
||||
const { product } = table.options.meta as {
|
||||
product: HttpTypes.AdminProduct
|
||||
}
|
||||
|
||||
return <VariantActions variant={row.original} product={product} />
|
||||
},
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
import { AdminGetProductsVariantsParams } from "@medusajs/medusa"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import { useQueryParams } from "../../../../../hooks/use-query-params"
|
||||
|
||||
export const useProductVariantTableQuery = ({
|
||||
@@ -31,7 +31,7 @@ export const useProductVariantTableQuery = ({
|
||||
order,
|
||||
} = queryObject
|
||||
|
||||
const searchParams: AdminGetProductsVariantsParams = {
|
||||
const searchParams: HttpTypes.AdminProductVariantParams = {
|
||||
limit: pageSize,
|
||||
offset: offset ? Number(offset) : 0,
|
||||
manage_inventory: manage_inventory
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { LoaderFunctionArgs } from "react-router-dom"
|
||||
|
||||
import { productsQueryKeys } from "../../../hooks/api/products"
|
||||
import { client } from "../../../lib/client"
|
||||
import { sdk } from "../../../lib/client"
|
||||
import { queryClient } from "../../../lib/query-client"
|
||||
import { PRODUCT_DETAIL_FIELDS } from "./constants"
|
||||
|
||||
const productDetailQuery = (id: string) => ({
|
||||
queryKey: productsQueryKeys.detail(id),
|
||||
queryFn: async () =>
|
||||
client.products.retrieve(id, { fields: PRODUCT_DETAIL_FIELDS }),
|
||||
sdk.admin.product.retrieve(id, { fields: PRODUCT_DETAIL_FIELDS }),
|
||||
})
|
||||
|
||||
export const productLoader = async ({ params }: LoaderFunctionArgs) => {
|
||||
|
||||
+2
-2
@@ -1,5 +1,4 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { ProductOption } from "@medusajs/medusa"
|
||||
import { Button, Input } from "@medusajs/ui"
|
||||
import { useForm } from "react-hook-form"
|
||||
import { useTranslation } from "react-i18next"
|
||||
@@ -12,9 +11,10 @@ import {
|
||||
useRouteModal,
|
||||
} from "../../../../../components/route-modal"
|
||||
import { useUpdateProductOption } from "../../../../../hooks/api/products"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type EditProductOptionFormProps = {
|
||||
option: ProductOption
|
||||
option: HttpTypes.AdminProductOption
|
||||
}
|
||||
|
||||
const CreateProductOptionSchema = z.object({
|
||||
|
||||
+3
-3
@@ -1,5 +1,4 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { Product, ProductVariant } from "@medusajs/medusa"
|
||||
import { Button, Heading, Input, Switch } from "@medusajs/ui"
|
||||
import { useForm } from "react-hook-form"
|
||||
import { useTranslation } from "react-i18next"
|
||||
@@ -19,10 +18,11 @@ import {
|
||||
parseOptionalFormNumber,
|
||||
} from "../../../../../lib/form-helpers"
|
||||
import { optionalInt } from "../../../../../lib/validation"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type ProductEditVariantFormProps = {
|
||||
product: Product
|
||||
variant: ProductVariant
|
||||
product: HttpTypes.AdminProduct
|
||||
variant: HttpTypes.AdminProductVariant
|
||||
}
|
||||
|
||||
const ProductEditVariantSchema = z.object({
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { LoaderFunctionArgs } from "react-router-dom"
|
||||
|
||||
import { productsQueryKeys } from "../../../hooks/api/products"
|
||||
import { client } from "../../../lib/client"
|
||||
import { sdk } from "../../../lib/client"
|
||||
import { queryClient } from "../../../lib/query-client"
|
||||
|
||||
const queryKey = (id: string) => {
|
||||
@@ -9,7 +9,7 @@ const queryKey = (id: string) => {
|
||||
}
|
||||
|
||||
const queryFn = async (id: string) => {
|
||||
return await client.products.retrieve(id)
|
||||
return await sdk.admin.product.retrieve(id)
|
||||
}
|
||||
|
||||
const editProductVariantQuery = (id: string) => ({
|
||||
|
||||
+3
-3
@@ -1,4 +1,3 @@
|
||||
import { ProductVariant } from "@medusajs/medusa"
|
||||
import { Heading } from "@medusajs/ui"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { json, useLoaderData, useParams } from "react-router-dom"
|
||||
@@ -6,6 +5,7 @@ import { RouteDrawer } from "../../../components/route-modal"
|
||||
import { useProduct } from "../../../hooks/api/products"
|
||||
import { ProductEditVariantForm } from "./components/product-edit-variant-form"
|
||||
import { editProductVariantLoader } from "./loader"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
export const ProductEditVariant = () => {
|
||||
const initialData = useLoaderData() as Awaited<
|
||||
@@ -20,7 +20,7 @@ export const ProductEditVariant = () => {
|
||||
})
|
||||
|
||||
const variant = product?.variants.find(
|
||||
(v: ProductVariant) => v.id === variant_id
|
||||
(v: HttpTypes.AdminProductVariant) => v.id === variant_id
|
||||
)
|
||||
|
||||
if (!isLoading && !variant) {
|
||||
@@ -44,7 +44,7 @@ export const ProductEditVariant = () => {
|
||||
{ready && (
|
||||
<ProductEditVariantForm
|
||||
product={product}
|
||||
variant={variant as unknown as ProductVariant}
|
||||
variant={variant as unknown as HttpTypes.AdminProductVariant}
|
||||
/>
|
||||
)}
|
||||
</RouteDrawer>
|
||||
|
||||
+3
-4
@@ -1,6 +1,4 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { Product } from "@medusajs/medusa"
|
||||
import { ProductStatus } from "@medusajs/types"
|
||||
import { Button, Input, Select, Text, Textarea } from "@medusajs/ui"
|
||||
import { useForm } from "react-hook-form"
|
||||
import { useTranslation } from "react-i18next"
|
||||
@@ -14,9 +12,10 @@ import {
|
||||
} from "../../../../../components/route-modal"
|
||||
import { useUpdateProduct } from "../../../../../hooks/api/products"
|
||||
import { parseOptionalFormData } from "../../../../../lib/form-helpers"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type EditProductFormProps = {
|
||||
product: Product
|
||||
product: HttpTypes.AdminProduct
|
||||
}
|
||||
|
||||
const EditProductSchema = zod.object({
|
||||
@@ -58,7 +57,7 @@ export const EditProductForm = ({ product }: EditProductFormProps) => {
|
||||
title,
|
||||
discountable,
|
||||
handle,
|
||||
status: status as ProductStatus,
|
||||
status: status as HttpTypes.AdminProductStatus,
|
||||
...nullableData,
|
||||
},
|
||||
{
|
||||
|
||||
+4
-4
@@ -16,8 +16,8 @@ import { useProductTableColumns } from "../../../../../hooks/table/columns/use-p
|
||||
import { useProductTableFilters } from "../../../../../hooks/table/filters/use-product-table-filters"
|
||||
import { useProductTableQuery } from "../../../../../hooks/table/query/use-product-table-query"
|
||||
import { useDataTable } from "../../../../../hooks/use-data-table"
|
||||
import { ExtendedProductDTO } from "../../../../../types/api-responses"
|
||||
import { productsLoader } from "../../loader"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
const PAGE_SIZE = 20
|
||||
|
||||
@@ -43,7 +43,7 @@ export const ProductListTable = () => {
|
||||
const columns = useColumns()
|
||||
|
||||
const { table } = useDataTable({
|
||||
data: (products ?? []) as ExtendedProductDTO[],
|
||||
data: (products ?? []) as HttpTypes.AdminProduct[],
|
||||
columns,
|
||||
count,
|
||||
enablePagination: true,
|
||||
@@ -81,7 +81,7 @@ export const ProductListTable = () => {
|
||||
)
|
||||
}
|
||||
|
||||
const ProductActions = ({ product }: { product: ExtendedProductDTO }) => {
|
||||
const ProductActions = ({ product }: { product: HttpTypes.AdminProduct }) => {
|
||||
const { t } = useTranslation()
|
||||
const prompt = usePrompt()
|
||||
const { mutateAsync } = useDeleteProduct(product.id)
|
||||
@@ -144,7 +144,7 @@ const ProductActions = ({ product }: { product: ExtendedProductDTO }) => {
|
||||
)
|
||||
}
|
||||
|
||||
const columnHelper = createColumnHelper<ExtendedProductDTO>()
|
||||
const columnHelper = createColumnHelper<HttpTypes.AdminProduct>()
|
||||
|
||||
const useColumns = () => {
|
||||
const base = useProductTableColumns()
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { QueryClient } from "@tanstack/react-query"
|
||||
|
||||
import { productsQueryKeys } from "../../../hooks/api/products"
|
||||
import { client } from "../../../lib/client"
|
||||
import { sdk } from "../../../lib/client"
|
||||
import { queryClient } from "../../../lib/query-client"
|
||||
import { ProductListRes } from "../../../types/api-responses"
|
||||
|
||||
const productsListQuery = () => ({
|
||||
queryKey: productsQueryKeys.list({ limit: 20, offset: 0 }),
|
||||
queryFn: async () => client.products.list({ limit: 20, offset: 0 }),
|
||||
queryFn: async () => sdk.admin.product.list({ limit: 20, offset: 0 }),
|
||||
})
|
||||
|
||||
export const productsLoader = (client: QueryClient) => {
|
||||
|
||||
+6
-3
@@ -5,7 +5,6 @@ import {
|
||||
TriangleLeftMini,
|
||||
TriangleRightMini,
|
||||
} from "@medusajs/icons"
|
||||
import { Image, Product } from "@medusajs/medusa"
|
||||
import { Button, IconButton, Text, Tooltip, clx, usePrompt } from "@medusajs/ui"
|
||||
import { useCallback, useEffect, useState } from "react"
|
||||
import { useTranslation } from "react-i18next"
|
||||
@@ -13,9 +12,10 @@ import { Link, useLocation } from "react-router-dom"
|
||||
|
||||
import { RouteFocusModal } from "../../../../../components/route-modal"
|
||||
import { useUpdateProduct } from "../../../../../hooks/api/products"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type ProductMediaGalleryProps = {
|
||||
product: Product
|
||||
product: HttpTypes.AdminProduct
|
||||
}
|
||||
|
||||
export const ProductMediaGallery = ({ product }: ProductMediaGalleryProps) => {
|
||||
@@ -303,7 +303,10 @@ type Media = {
|
||||
isThumbnail: boolean
|
||||
}
|
||||
|
||||
const getMedia = (images: Image[] | null, thumbnail: string | null) => {
|
||||
const getMedia = (
|
||||
images: HttpTypes.AdminProductImage[] | null,
|
||||
thumbnail: string | null
|
||||
) => {
|
||||
const media: Media[] =
|
||||
images?.map((image) => ({
|
||||
id: image.id,
|
||||
|
||||
+2
-2
@@ -1,5 +1,4 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { Product } from "@medusajs/medusa"
|
||||
import { Button, toast } from "@medusajs/ui"
|
||||
import { useForm } from "react-hook-form"
|
||||
import { useTranslation } from "react-i18next"
|
||||
@@ -14,9 +13,10 @@ import { useUpdateProduct } from "../../../../../hooks/api/products"
|
||||
import { useComboboxData } from "../../../../../hooks/use-combobox-data"
|
||||
import { client, sdk } from "../../../../../lib/client"
|
||||
import { CategoryCombobox } from "../../../common/components/category-combobox"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type ProductOrganizationFormProps = {
|
||||
product: Product
|
||||
product: HttpTypes.AdminProduct
|
||||
}
|
||||
|
||||
const ProductOrganizationSchema = zod.object({
|
||||
|
||||
@@ -5,9 +5,9 @@ import { useTranslation } from "react-i18next"
|
||||
import * as zod from "zod"
|
||||
import { RouteFocusModal, useRouteModal } from "../../../components/route-modal"
|
||||
import { useUpdateProductVariantsBatch } from "../../../hooks/api/products"
|
||||
import { ExtendedProductDTO } from "../../../types/api-responses"
|
||||
import { VariantPricingForm } from "../common/variant-pricing-form"
|
||||
import { castNumber } from "../../../lib/cast-number"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
export const UpdateVariantPricesSchema = zod.object({
|
||||
variants: zod.array(
|
||||
@@ -23,7 +23,11 @@ export type UpdateVariantPricesSchemaType = zod.infer<
|
||||
typeof UpdateVariantPricesSchema
|
||||
>
|
||||
|
||||
export const PricingEdit = ({ product }: { product: ExtendedProductDTO }) => {
|
||||
export const PricingEdit = ({
|
||||
product,
|
||||
}: {
|
||||
product: HttpTypes.AdminProduct
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const { handleSuccess } = useRouteModal()
|
||||
const form = useForm<UpdateVariantPricesSchemaType>({
|
||||
|
||||
+3
-2
@@ -1,4 +1,4 @@
|
||||
import { Product, SalesChannel } from "@medusajs/medusa"
|
||||
import { SalesChannel } from "@medusajs/medusa"
|
||||
import { Button, Checkbox } from "@medusajs/ui"
|
||||
import { RowSelectionState, createColumnHelper } from "@tanstack/react-table"
|
||||
import { useEffect, useMemo, useState } from "react"
|
||||
@@ -18,9 +18,10 @@ import { useSalesChannelTableQuery } from "../../../../../hooks/table/query/use-
|
||||
import { useDataTable } from "../../../../../hooks/use-data-table"
|
||||
import { useSalesChannels } from "../../../../../hooks/api/sales-channels"
|
||||
import { useUpdateProduct } from "../../../../../hooks/api/products"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type EditSalesChannelsFormProps = {
|
||||
product: Product
|
||||
product: HttpTypes.AdminProduct
|
||||
}
|
||||
|
||||
const EditSalesChannelsSchema = zod.object({
|
||||
|
||||
+2
-2
@@ -22,7 +22,7 @@ import { useProductTableColumns } from "../../../../hooks/table/columns/use-prod
|
||||
import { useProductTableFilters } from "../../../../hooks/table/filters/use-product-table-filters"
|
||||
import { useProductTableQuery } from "../../../../hooks/table/query/use-product-table-query"
|
||||
import { useDataTable } from "../../../../hooks/use-data-table"
|
||||
import { ExtendedProductDTO } from "../../../../types/api-responses"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type AddProductsToSalesChannelFormProps = {
|
||||
salesChannel: SalesChannelDTO
|
||||
@@ -176,7 +176,7 @@ export const AddProductsToSalesChannelForm = ({
|
||||
)
|
||||
}
|
||||
|
||||
const columnHelper = createColumnHelper<ExtendedProductDTO>()
|
||||
const columnHelper = createColumnHelper<HttpTypes.AdminProduct>()
|
||||
|
||||
const useColumns = () => {
|
||||
const base = useProductTableColumns()
|
||||
|
||||
+2
-2
@@ -22,7 +22,7 @@ import { useProductTableColumns } from "../../../../../hooks/table/columns/use-p
|
||||
import { useProductTableFilters } from "../../../../../hooks/table/filters/use-product-table-filters"
|
||||
import { useProductTableQuery } from "../../../../../hooks/table/query/use-product-table-query"
|
||||
import { useDataTable } from "../../../../../hooks/use-data-table"
|
||||
import { ExtendedProductDTO } from "../../../../../types/api-responses"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
const PAGE_SIZE = 10
|
||||
|
||||
@@ -154,7 +154,7 @@ export const SalesChannelProductSection = ({
|
||||
)
|
||||
}
|
||||
|
||||
const columnHelper = createColumnHelper<ExtendedProductDTO>()
|
||||
const columnHelper = createColumnHelper<HttpTypes.AdminProduct>()
|
||||
|
||||
const useColumns = () => {
|
||||
const base = useProductTableColumns()
|
||||
|
||||
+5
-5
@@ -1,4 +1,4 @@
|
||||
import { CustomerGroup, Product, ProductType } from "@medusajs/medusa"
|
||||
import { CustomerGroup } from "@medusajs/medusa"
|
||||
import { Button } from "@medusajs/ui"
|
||||
import { OnChangeFn, RowSelectionState } from "@tanstack/react-table"
|
||||
import { useState } from "react"
|
||||
@@ -25,7 +25,6 @@ import { useProductCollectionConditionsTableColumns } from "../../hooks/columns/
|
||||
import { useProductCollectionConditionsTableFilters } from "../../hooks/filters/use-product-collection-conditions-table-filters"
|
||||
import { useProductCollectionConditionsTableQuery } from "../../hooks/query/use-product-collection-conditions-table-query"
|
||||
|
||||
import { ProductCollectionDTO } from "@medusajs/types"
|
||||
import { keepPreviousData } from "@tanstack/react-query"
|
||||
import { useCollections } from "../../../../../hooks/api/collections"
|
||||
import { useCustomerGroups } from "../../../../../hooks/api/customer-groups"
|
||||
@@ -33,6 +32,7 @@ import { useProductTypes } from "../../../../../hooks/api/product-types"
|
||||
import { useProducts } from "../../../../../hooks/api/products"
|
||||
import { ConditionEntities } from "../../constants"
|
||||
import { ConditionsOption } from "../../types"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
const PAGE_SIZE = 50
|
||||
|
||||
@@ -102,7 +102,7 @@ const ProductConditionsTable = ({ selected = [], onSave }: ConditionsProps) => {
|
||||
|
||||
if (added.length) {
|
||||
const addedProducts = (products?.filter((p) => added.includes(p.id!)) ??
|
||||
[]) as Product[]
|
||||
[]) as HttpTypes.AdminProduct[]
|
||||
|
||||
if (addedProducts.length > 0) {
|
||||
const newConditions = addedProducts.map((p) => ({
|
||||
@@ -322,7 +322,7 @@ const ProductTypeConditionsTable = ({
|
||||
|
||||
if (added.length) {
|
||||
const addedTypes = (product_types?.filter((p) => added.includes(p.id!)) ??
|
||||
[]) as ProductType[]
|
||||
[]) as HttpTypes.AdminProductType[]
|
||||
|
||||
if (addedTypes.length > 0) {
|
||||
const newConditions = addedTypes.map((p) => ({
|
||||
@@ -431,7 +431,7 @@ const ProductCollectionConditionsTable = ({
|
||||
if (added.length) {
|
||||
const addedCollections = (collections?.filter((p) =>
|
||||
added.includes(p.id!)
|
||||
) ?? []) as ProductCollectionDTO[]
|
||||
) ?? []) as HttpTypes.AdminCollection[]
|
||||
|
||||
if (addedCollections.length > 0) {
|
||||
const newConditions = addedCollections.map((p) => ({
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
import { ProductCollectionDTO } from "@medusajs/types"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import { Checkbox } from "@medusajs/ui"
|
||||
import { createColumnHelper } from "@tanstack/react-table"
|
||||
import { useMemo } from "react"
|
||||
import { useTranslation } from "react-i18next"
|
||||
|
||||
const columnHelper = createColumnHelper<ProductCollectionDTO>()
|
||||
const columnHelper = createColumnHelper<HttpTypes.AdminCollection>()
|
||||
|
||||
export const useProductCollectionConditionsTableColumns = () => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
import { Product } from "@medusajs/medusa"
|
||||
import { Checkbox } from "@medusajs/ui"
|
||||
import { createColumnHelper } from "@tanstack/react-table"
|
||||
import { useMemo } from "react"
|
||||
import { useProductTableColumns } from "../../../../../hooks/table/columns/use-product-table-columns"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
const columnHelper = createColumnHelper<Product>()
|
||||
const columnHelper = createColumnHelper<HttpTypes.AdminProduct>()
|
||||
|
||||
export const useProductConditionsTableColumns = () => {
|
||||
const base = useProductTableColumns()
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
import { ProductType } from "@medusajs/medusa"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import { Checkbox } from "@medusajs/ui"
|
||||
import { createColumnHelper } from "@tanstack/react-table"
|
||||
import { useMemo } from "react"
|
||||
import { useTranslation } from "react-i18next"
|
||||
|
||||
const columnHelper = createColumnHelper<ProductType>()
|
||||
const columnHelper = createColumnHelper<HttpTypes.AdminProductType>()
|
||||
|
||||
export const useProductTypeConditionsTableColumns = () => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
@@ -13,11 +13,6 @@ import {
|
||||
OrderDTO,
|
||||
PaymentProviderDTO,
|
||||
PriceListDTO,
|
||||
ProductCategoryDTO,
|
||||
ProductCollectionDTO,
|
||||
ProductDTO,
|
||||
ProductTypeDTO,
|
||||
ProductVariantDTO,
|
||||
PromotionDTO,
|
||||
PromotionRuleDTO,
|
||||
SalesChannelDTO,
|
||||
@@ -27,9 +22,9 @@ import {
|
||||
StockLocationDTO,
|
||||
StoreDTO,
|
||||
UserDTO,
|
||||
HttpTypes,
|
||||
} from "@medusajs/types"
|
||||
|
||||
import { ProductTagDTO } from "@medusajs/types/dist/product"
|
||||
import { WorkflowExecutionDTO } from "../routes/workflow-executions/types"
|
||||
|
||||
type ListRes = {
|
||||
@@ -105,29 +100,6 @@ export type InviteDeleteRes = DeleteRes
|
||||
export type OrderRes = { order: OrderDTO }
|
||||
export type OrderListRes = { orders: OrderDTO[] } & ListRes
|
||||
|
||||
// Products
|
||||
export type ExtendedProductDTO = ProductDTO & {
|
||||
variants: ProductVariantDTO[] | null
|
||||
sales_channels: SalesChannelDTO[] | null
|
||||
collections: ProductCollectionDTO[] | null
|
||||
categories: ProductCategoryDTO[] | null
|
||||
}
|
||||
export type ProductRes = { product: ExtendedProductDTO }
|
||||
export type ProductListRes = { products: ExtendedProductDTO[] } & ListRes
|
||||
export type ProductDeleteRes = DeleteRes
|
||||
|
||||
// Categories
|
||||
export type CategoryRes = { category: ProductCategoryDTO }
|
||||
export type CategoriesListRes = { categories: ProductCategoryDTO[] } & ListRes
|
||||
|
||||
// Tags
|
||||
export type TagRes = { tag: ProductTagDTO }
|
||||
export type TagsListRes = { tags: ProductTagDTO[] } & ListRes
|
||||
|
||||
// Product Types
|
||||
export type ProductTypeRes = { product_type: ProductTypeDTO }
|
||||
export type ProductTypeListRes = { product_types: ProductTypeDTO[] } & ListRes
|
||||
|
||||
// Payments
|
||||
|
||||
export type PaymentProvidersListRes = {
|
||||
|
||||
@@ -8,12 +8,27 @@ export class Product {
|
||||
this.client = client
|
||||
}
|
||||
|
||||
async batch(
|
||||
body: HttpTypes.AdminBatchProductRequest,
|
||||
query?: SelectParams,
|
||||
headers?: ClientHeaders
|
||||
) {
|
||||
return await this.client.fetch<HttpTypes.AdminBatchProductResponse>(
|
||||
`/admin/products/batch`,
|
||||
{
|
||||
method: "POST",
|
||||
headers,
|
||||
body,
|
||||
query,
|
||||
}
|
||||
)
|
||||
}
|
||||
async create(
|
||||
body: HttpTypes.AdminCreateProduct,
|
||||
query?: SelectParams,
|
||||
headers?: ClientHeaders
|
||||
) {
|
||||
return await this.client.fetch<{ product: HttpTypes.AdminProduct }>(
|
||||
return await this.client.fetch<HttpTypes.AdminProductResponse>(
|
||||
`/admin/products`,
|
||||
{
|
||||
method: "POST",
|
||||
@@ -23,4 +38,205 @@ export class Product {
|
||||
}
|
||||
)
|
||||
}
|
||||
async update(
|
||||
id: string,
|
||||
body: HttpTypes.AdminUpdateProduct,
|
||||
query?: SelectParams,
|
||||
headers?: ClientHeaders
|
||||
) {
|
||||
return await this.client.fetch<HttpTypes.AdminProductResponse>(
|
||||
`/admin/products/${id}`,
|
||||
{
|
||||
method: "POST",
|
||||
headers,
|
||||
body,
|
||||
query,
|
||||
}
|
||||
)
|
||||
}
|
||||
async list(
|
||||
queryParams?: HttpTypes.AdminProductParams,
|
||||
headers?: ClientHeaders
|
||||
) {
|
||||
return await this.client.fetch<HttpTypes.AdminProductListResponse>(
|
||||
`/admin/products`,
|
||||
{
|
||||
headers,
|
||||
query: queryParams,
|
||||
}
|
||||
)
|
||||
}
|
||||
async retrieve(id: string, query?: SelectParams, headers?: ClientHeaders) {
|
||||
return await this.client.fetch<HttpTypes.AdminProductResponse>(
|
||||
`/admin/products/${id}`,
|
||||
{
|
||||
query,
|
||||
headers,
|
||||
}
|
||||
)
|
||||
}
|
||||
async delete(id: string, headers?: ClientHeaders) {
|
||||
return await this.client.fetch<HttpTypes.AdminProductDeleteResponse>(
|
||||
`/admin/products/${id}`,
|
||||
{
|
||||
method: "DELETE",
|
||||
headers,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
async batchVariants(
|
||||
productId: string,
|
||||
body: HttpTypes.AdminBatchProductVariantRequest,
|
||||
query?: SelectParams,
|
||||
headers?: ClientHeaders
|
||||
) {
|
||||
return await this.client.fetch<HttpTypes.AdminBatchProductVariantResponse>(
|
||||
`/admin/products/${productId}/variants/batch`,
|
||||
{
|
||||
method: "POST",
|
||||
headers,
|
||||
body,
|
||||
query,
|
||||
}
|
||||
)
|
||||
}
|
||||
async createVariant(
|
||||
productId: string,
|
||||
body: HttpTypes.AdminCreateProductVariant,
|
||||
query?: SelectParams,
|
||||
headers?: ClientHeaders
|
||||
) {
|
||||
return await this.client.fetch<HttpTypes.AdminProductResponse>(
|
||||
`/admin/products/${productId}/variants`,
|
||||
{
|
||||
method: "POST",
|
||||
headers,
|
||||
body,
|
||||
query,
|
||||
}
|
||||
)
|
||||
}
|
||||
async updateVariant(
|
||||
productId: string,
|
||||
id: string,
|
||||
body: HttpTypes.AdminUpdateProductVariant,
|
||||
query?: SelectParams,
|
||||
headers?: ClientHeaders
|
||||
) {
|
||||
return await this.client.fetch<HttpTypes.AdminProductResponse>(
|
||||
`/admin/products/${productId}/variants/${id}`,
|
||||
{
|
||||
method: "POST",
|
||||
headers,
|
||||
body,
|
||||
query,
|
||||
}
|
||||
)
|
||||
}
|
||||
async listVariants(
|
||||
productId: string,
|
||||
queryParams?: HttpTypes.AdminProductVariantParams,
|
||||
headers?: ClientHeaders
|
||||
) {
|
||||
return await this.client.fetch<HttpTypes.AdminProductVariantListResponse>(
|
||||
`/admin/products/${productId}/variants`,
|
||||
{
|
||||
headers,
|
||||
query: queryParams,
|
||||
}
|
||||
)
|
||||
}
|
||||
async retrieveVariant(
|
||||
productId: string,
|
||||
id: string,
|
||||
query?: SelectParams,
|
||||
headers?: ClientHeaders
|
||||
) {
|
||||
return await this.client.fetch<HttpTypes.AdminProductVariantResponse>(
|
||||
`/admin/products/${productId}/variants/${id}`,
|
||||
{
|
||||
query,
|
||||
headers,
|
||||
}
|
||||
)
|
||||
}
|
||||
async deleteVariant(productId: string, id: string, headers?: ClientHeaders) {
|
||||
return await this.client.fetch<HttpTypes.AdminProductVariantDeleteResponse>(
|
||||
`/admin/products/${productId}/variants/${id}`,
|
||||
{
|
||||
method: "DELETE",
|
||||
headers,
|
||||
}
|
||||
)
|
||||
}
|
||||
async createOption(
|
||||
productId: string,
|
||||
body: HttpTypes.AdminCreateProductOption,
|
||||
query?: SelectParams,
|
||||
headers?: ClientHeaders
|
||||
) {
|
||||
return await this.client.fetch<HttpTypes.AdminProductResponse>(
|
||||
`/admin/products/${productId}/options`,
|
||||
{
|
||||
method: "POST",
|
||||
headers,
|
||||
body,
|
||||
query,
|
||||
}
|
||||
)
|
||||
}
|
||||
async updateOption(
|
||||
productId: string,
|
||||
id: string,
|
||||
body: HttpTypes.AdminUpdateProductOption,
|
||||
query?: SelectParams,
|
||||
headers?: ClientHeaders
|
||||
) {
|
||||
return await this.client.fetch<HttpTypes.AdminProductResponse>(
|
||||
`/admin/products/${productId}/variants/${id}`,
|
||||
{
|
||||
method: "POST",
|
||||
headers,
|
||||
body,
|
||||
query,
|
||||
}
|
||||
)
|
||||
}
|
||||
async listOptions(
|
||||
productId: string,
|
||||
queryParams?: HttpTypes.AdminProductOptionParams,
|
||||
headers?: ClientHeaders
|
||||
) {
|
||||
return await this.client.fetch<HttpTypes.AdminProductOptionListResponse>(
|
||||
`/admin/products/${productId}/options`,
|
||||
{
|
||||
headers,
|
||||
query: queryParams,
|
||||
}
|
||||
)
|
||||
}
|
||||
async retrieveOption(
|
||||
productId: string,
|
||||
id: string,
|
||||
query?: SelectParams,
|
||||
headers?: ClientHeaders
|
||||
) {
|
||||
return await this.client.fetch<HttpTypes.AdminProductOptionResponse>(
|
||||
`/admin/products/${productId}/options/${id}`,
|
||||
{
|
||||
query,
|
||||
headers,
|
||||
}
|
||||
)
|
||||
}
|
||||
async deleteOption(productId: string, id: string, headers?: ClientHeaders) {
|
||||
return await this.client.fetch<HttpTypes.AdminProductOptionDeleteResponse>(
|
||||
`/admin/products/${productId}/options/${id}`,
|
||||
{
|
||||
method: "DELETE",
|
||||
headers,
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ export class Store {
|
||||
|
||||
public category = {
|
||||
list: async (
|
||||
query?: FindParams & HttpTypes.StoreProductCategoryFilters,
|
||||
query?: HttpTypes.StoreProductCategoryParams,
|
||||
headers?: ClientHeaders
|
||||
) => {
|
||||
return this.client.fetch<
|
||||
@@ -99,22 +99,23 @@ export class Store {
|
||||
|
||||
public product = {
|
||||
list: async (
|
||||
query?: FindParams & HttpTypes.StoreProductFilters,
|
||||
query?: HttpTypes.StoreProductParams,
|
||||
headers?: ClientHeaders
|
||||
) => {
|
||||
return this.client.fetch<
|
||||
PaginatedResponse<{ products: HttpTypes.StoreProduct[] }>
|
||||
>(`/store/products`, {
|
||||
query,
|
||||
headers,
|
||||
})
|
||||
return this.client.fetch<HttpTypes.StoreProductListResponse>(
|
||||
`/store/products`,
|
||||
{
|
||||
query,
|
||||
headers,
|
||||
}
|
||||
)
|
||||
},
|
||||
retrieve: async (
|
||||
id: string,
|
||||
query?: SelectParams,
|
||||
headers?: ClientHeaders
|
||||
) => {
|
||||
return this.client.fetch<{ product: HttpTypes.StoreProduct }>(
|
||||
return this.client.fetch<HttpTypes.StoreProductResponse>(
|
||||
`/store/products/${id}`,
|
||||
{
|
||||
query,
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
import {
|
||||
BaseProduct,
|
||||
BaseProductCategory,
|
||||
BaseProductCategoryFilters,
|
||||
BaseProductFilters,
|
||||
BaseProductImage,
|
||||
BaseProductOption,
|
||||
BaseProductOptionFilters,
|
||||
BaseProductOptionValue,
|
||||
BaseProductTag,
|
||||
BaseProductTagFilters,
|
||||
BaseProductType,
|
||||
BaseProductTypeFilters,
|
||||
BaseProductVariant,
|
||||
BaseProductVariantFilters,
|
||||
} from "./common"
|
||||
|
||||
export interface AdminProduct extends Omit<BaseProduct, "categories"> {
|
||||
categories?: AdminProductCategory[]
|
||||
}
|
||||
|
||||
export interface AdminProductCategory extends BaseProductCategory {
|
||||
is_active?: boolean
|
||||
is_internal?: boolean
|
||||
}
|
||||
export interface AdminProductVariant extends BaseProductVariant {}
|
||||
export interface AdminProductTag extends BaseProductTag {}
|
||||
export interface AdminProductType extends BaseProductType {}
|
||||
export interface AdminProductOption extends BaseProductOption {}
|
||||
export interface AdminProductImage extends BaseProductImage {}
|
||||
export interface AdminProductOptionValue extends BaseProductOptionValue {}
|
||||
|
||||
export interface AdminProductFilters extends BaseProductFilters {}
|
||||
export interface AdminProductTagFilters extends BaseProductTagFilters {}
|
||||
export interface AdminProductTypeFilters extends BaseProductTypeFilters {}
|
||||
export interface AdminProductOptionFilters extends BaseProductOptionFilters {}
|
||||
export interface AdminProductVariantFilters extends BaseProductVariantFilters {}
|
||||
export interface AdminProductCategoryFilters
|
||||
extends BaseProductCategoryFilters {}
|
||||
|
||||
export interface AdminCreateProductVariantPrice {
|
||||
currency_code: string
|
||||
amount: number
|
||||
min_quantity?: number
|
||||
max_quantity?: number
|
||||
}
|
||||
|
||||
export interface AdminCreateProductVariant {
|
||||
title: string
|
||||
sku?: string
|
||||
ean?: string
|
||||
upc?: string
|
||||
barcode?: string
|
||||
hs_code?: string
|
||||
mid_code?: string
|
||||
allow_backorder?: boolean
|
||||
manage_inventory?: boolean
|
||||
variant_rank?: number
|
||||
weight?: number
|
||||
length?: number
|
||||
height?: number
|
||||
width?: number
|
||||
origin_country?: string
|
||||
material?: string
|
||||
metadata?: Record<string, any>
|
||||
prices: AdminCreateProductVariantPrice[]
|
||||
options?: Record<string, any>
|
||||
}
|
||||
|
||||
export interface AdminCreateProduct {
|
||||
title: string
|
||||
subtitle?: string
|
||||
description?: string
|
||||
is_giftcard?: boolean
|
||||
discountable?: boolean
|
||||
images?: { url: string }[]
|
||||
thumbnail?: string
|
||||
handle?: string
|
||||
status?: string
|
||||
type_id?: string | null
|
||||
collection_id?: string | null
|
||||
categories?: { id: string }[]
|
||||
tags?: { id?: string; value?: string }[]
|
||||
options?: { title?: string; values?: string[] }[]
|
||||
variants?: AdminCreateProductVariant[]
|
||||
sales_channels?: { id: string }[]
|
||||
weight?: number
|
||||
length?: number
|
||||
height?: number
|
||||
width?: number
|
||||
hs_code?: string
|
||||
mid_code?: string
|
||||
origin_country?: string
|
||||
material?: string
|
||||
metadata?: Record<string, any>
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import { AdminPrice } from "../../pricing"
|
||||
import { AdminSalesChannel } from "../../sales-channel"
|
||||
import {
|
||||
BaseProduct,
|
||||
BaseProductCategory,
|
||||
BaseProductImage,
|
||||
BaseProductOption,
|
||||
BaseProductOptionValue,
|
||||
BaseProductTag,
|
||||
BaseProductType,
|
||||
BaseProductVariant,
|
||||
ProductStatus,
|
||||
} from "../common"
|
||||
|
||||
export interface AdminProductCategory extends BaseProductCategory {
|
||||
is_active?: boolean
|
||||
is_internal?: boolean
|
||||
}
|
||||
export interface AdminProductVariant extends BaseProductVariant {
|
||||
prices: AdminPrice[] | null
|
||||
}
|
||||
export interface AdminProductTag extends BaseProductTag {}
|
||||
export interface AdminProductType extends BaseProductType {}
|
||||
export interface AdminProductOption extends BaseProductOption {}
|
||||
export interface AdminProductImage extends BaseProductImage {}
|
||||
export interface AdminProductOptionValue extends BaseProductOptionValue {}
|
||||
export interface AdminProduct
|
||||
extends Omit<BaseProduct, "categories" | "variants"> {
|
||||
categories?: AdminProductCategory[] | null
|
||||
sales_channels?: AdminSalesChannel[] | null
|
||||
variants?: AdminProductVariant[] | null
|
||||
}
|
||||
export type AdminProductStatus = ProductStatus
|
||||
@@ -0,0 +1,4 @@
|
||||
export * from "./entitites"
|
||||
export * from "./payloads"
|
||||
export * from "./responses"
|
||||
export * from "./queries"
|
||||
@@ -0,0 +1,127 @@
|
||||
import { BatchMethodRequest } from "../../../common"
|
||||
import { ProductStatus } from "../common"
|
||||
|
||||
export interface AdminBatchProductRequest
|
||||
extends BatchMethodRequest<AdminCreateProduct, AdminUpdateProduct> {}
|
||||
export interface AdminBatchProductVariantRequest
|
||||
extends BatchMethodRequest<
|
||||
AdminCreateProductVariant,
|
||||
AdminUpdateProductVariant
|
||||
> {}
|
||||
|
||||
export interface AdminCreateProductVariantPrice {
|
||||
currency_code: string
|
||||
amount: number
|
||||
min_quantity?: number | null
|
||||
max_quantity?: number | null
|
||||
}
|
||||
|
||||
export interface AdminCreateProductVariant {
|
||||
title: string
|
||||
sku?: string
|
||||
ean?: string
|
||||
upc?: string
|
||||
barcode?: string
|
||||
hs_code?: string
|
||||
mid_code?: string
|
||||
allow_backorder?: boolean
|
||||
manage_inventory?: boolean
|
||||
variant_rank?: number
|
||||
weight?: number
|
||||
length?: number
|
||||
height?: number
|
||||
width?: number
|
||||
origin_country?: string
|
||||
material?: string
|
||||
metadata?: Record<string, unknown>
|
||||
prices: AdminCreateProductVariantPrice[]
|
||||
options?: Record<string, string>
|
||||
}
|
||||
|
||||
export interface AdminCreateProduct {
|
||||
title: string
|
||||
subtitle?: string
|
||||
description?: string
|
||||
is_giftcard?: boolean
|
||||
discountable?: boolean
|
||||
images?: { url: string }[]
|
||||
thumbnail?: string
|
||||
handle?: string
|
||||
status?: ProductStatus
|
||||
type_id?: string
|
||||
collection_id?: string
|
||||
categories?: { id: string }[]
|
||||
tags?: { id?: string; value?: string }[]
|
||||
options?: AdminCreateProductOption[]
|
||||
variants?: AdminCreateProductVariant[]
|
||||
sales_channels?: { id: string }[]
|
||||
weight?: number
|
||||
length?: number
|
||||
height?: number
|
||||
width?: number
|
||||
hs_code?: string
|
||||
mid_code?: string
|
||||
origin_country?: string
|
||||
material?: string
|
||||
metadata?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export interface AdminUpdateProductVariant {
|
||||
title?: string
|
||||
sku?: string | null
|
||||
ean?: string | null
|
||||
upc?: string | null
|
||||
barcode?: string | null
|
||||
hs_code?: string | null
|
||||
mid_code?: string | null
|
||||
allow_backorder?: boolean
|
||||
manage_inventory?: boolean
|
||||
variant_rank?: number
|
||||
weight?: number | null
|
||||
length?: number | null
|
||||
height?: number | null
|
||||
width?: number | null
|
||||
origin_country?: string | null
|
||||
material?: string | null
|
||||
metadata?: Record<string, unknown> | null
|
||||
prices?: AdminCreateProductVariantPrice[]
|
||||
options?: Record<string, string>
|
||||
}
|
||||
|
||||
export interface AdminUpdateProduct {
|
||||
title?: string
|
||||
subtitle?: string | null
|
||||
description?: string | null
|
||||
is_giftcard?: boolean
|
||||
discountable?: boolean
|
||||
images?: { url: string }[]
|
||||
thumbnail?: string | null
|
||||
handle?: string
|
||||
status?: ProductStatus
|
||||
type_id?: string | null
|
||||
collection_id?: string | null
|
||||
categories?: { id: string }[]
|
||||
tags?: { id?: string; value?: string }[]
|
||||
options?: AdminUpdateProductOption[]
|
||||
variants?: AdminCreateProductVariant[]
|
||||
sales_channels?: { id: string }[]
|
||||
weight?: number | null
|
||||
length?: number | null
|
||||
height?: number | null
|
||||
width?: number | null
|
||||
hs_code?: string | null
|
||||
mid_code?: string | null
|
||||
origin_country?: string | null
|
||||
material?: string | null
|
||||
metadata?: Record<string, unknown> | null
|
||||
}
|
||||
|
||||
export interface AdminCreateProductOption {
|
||||
title: string
|
||||
values: string[]
|
||||
}
|
||||
|
||||
export interface AdminUpdateProductOption {
|
||||
title?: string
|
||||
values?: string[]
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import {
|
||||
BaseProductCategoryParams,
|
||||
BaseProductOptionParams,
|
||||
BaseProductParams,
|
||||
BaseProductTagParams,
|
||||
BaseProductTypeParams,
|
||||
BaseProductVariantParams,
|
||||
} from "../common"
|
||||
|
||||
export interface AdminProductTagParams extends BaseProductTagParams {}
|
||||
export interface AdminProductTypeParams extends BaseProductTypeParams {}
|
||||
export interface AdminProductOptionParams extends BaseProductOptionParams {}
|
||||
export interface AdminProductVariantParams extends BaseProductVariantParams {}
|
||||
export interface AdminProductParams extends BaseProductParams {
|
||||
price_list_id?: string | string[]
|
||||
variants?: AdminProductVariantParams
|
||||
}
|
||||
export interface AdminProductCategoryParams extends BaseProductCategoryParams {}
|
||||
@@ -0,0 +1,45 @@
|
||||
import { BatchMethodResponse } from "../../../common"
|
||||
import { DeleteResponse, PaginatedResponse } from "../../common"
|
||||
import {
|
||||
AdminProduct,
|
||||
AdminProductOption,
|
||||
AdminProductVariant,
|
||||
} from "./entitites"
|
||||
|
||||
export interface AdminProductResponse {
|
||||
product: AdminProduct
|
||||
}
|
||||
|
||||
export type AdminProductListResponse = PaginatedResponse<{
|
||||
products: AdminProduct[]
|
||||
}>
|
||||
|
||||
export interface AdminProductDeleteResponse extends DeleteResponse<"product"> {}
|
||||
|
||||
export interface AdminBatchProductResponse
|
||||
extends BatchMethodResponse<AdminProduct> {}
|
||||
|
||||
export interface AdminProductVariantResponse {
|
||||
variant: AdminProductVariant
|
||||
}
|
||||
|
||||
export type AdminProductVariantListResponse = PaginatedResponse<{
|
||||
variants: AdminProductVariant[]
|
||||
}>
|
||||
|
||||
export interface AdminProductVariantDeleteResponse
|
||||
extends DeleteResponse<"variant", AdminProduct> {}
|
||||
|
||||
export interface AdminBatchProductVariantResponse
|
||||
extends BatchMethodResponse<AdminProductVariant> {}
|
||||
|
||||
export interface AdminProductOptionResponse {
|
||||
product_option: AdminProductOption
|
||||
}
|
||||
|
||||
export type AdminProductOptionListResponse = PaginatedResponse<{
|
||||
product_options: AdminProductOption[]
|
||||
}>
|
||||
|
||||
export interface AdminProductOptionDeleteResponse
|
||||
extends DeleteResponse<"product_option", AdminProduct> {}
|
||||
@@ -1,94 +1,94 @@
|
||||
import { BaseFilterable, OperatorMap } from "../../dal"
|
||||
import { BaseCollection } from "../collection/common"
|
||||
import { FindParams } from "../common"
|
||||
|
||||
export type ProductStatus = "draft" | "proposed" | "published" | "rejected"
|
||||
|
||||
export interface BaseProduct {
|
||||
id?: string
|
||||
title?: string
|
||||
handle?: string
|
||||
subtitle?: string | null
|
||||
description?: string | null
|
||||
is_giftcard?: boolean
|
||||
status?: ProductStatus
|
||||
thumbnail?: string
|
||||
width?: number
|
||||
weight?: number
|
||||
length?: number
|
||||
height?: number
|
||||
origin_country?: string
|
||||
hs_code?: string
|
||||
mid_code?: string
|
||||
material?: string
|
||||
collection?: BaseCollection
|
||||
collection_id?: string | null
|
||||
categories?: BaseProductCategory[]
|
||||
type?: BaseProductType | null
|
||||
type_id?: string | null
|
||||
tags?: BaseProductTag[]
|
||||
variants?: BaseProductVariant[]
|
||||
options?: BaseProductOption[]
|
||||
images?: BaseProductImage[]
|
||||
discountable?: boolean
|
||||
external_id?: string | null
|
||||
created_at?: string
|
||||
updated_at?: string
|
||||
deleted_at?: string | null
|
||||
id: string
|
||||
title: string
|
||||
handle: string
|
||||
subtitle: string | null
|
||||
description: string | null
|
||||
is_giftcard: boolean
|
||||
status: ProductStatus
|
||||
thumbnail: string | null
|
||||
width: number | null
|
||||
weight: number | null
|
||||
length: number | null
|
||||
height: number | null
|
||||
origin_country: string | null
|
||||
hs_code: string | null
|
||||
mid_code: string | null
|
||||
material: string | null
|
||||
collection: BaseCollection | null
|
||||
collection_id: string | null
|
||||
categories?: BaseProductCategory[] | null
|
||||
type: BaseProductType | null
|
||||
type_id: string | null
|
||||
tags: BaseProductTag[] | null
|
||||
variants: BaseProductVariant[] | null
|
||||
options: BaseProductOption[] | null
|
||||
images: BaseProductImage[] | null
|
||||
discountable: boolean
|
||||
external_id: string | null
|
||||
created_at: string | null
|
||||
updated_at: string | null
|
||||
deleted_at: string | null
|
||||
metadata?: Record<string, unknown> | null
|
||||
}
|
||||
|
||||
export interface BaseProductVariant {
|
||||
id?: string
|
||||
title?: string
|
||||
sku?: string
|
||||
barcode?: string
|
||||
ean?: string
|
||||
upc?: string
|
||||
allow_backorder?: boolean
|
||||
manage_inventory?: boolean
|
||||
hs_code?: string
|
||||
origin_country?: string
|
||||
mid_code?: string
|
||||
material?: string
|
||||
weight?: number
|
||||
length?: number
|
||||
height?: number
|
||||
width?: number
|
||||
options?: BaseProductOptionValue[]
|
||||
product?: BaseProduct
|
||||
product_id?: string | null
|
||||
variant_rank?: number
|
||||
created_at?: string
|
||||
updated_at?: string
|
||||
deleted_at?: string | null
|
||||
id: string
|
||||
title: string | null
|
||||
sku: string | null
|
||||
barcode: string | null
|
||||
ean: string | null
|
||||
upc: string | null
|
||||
allow_backorder: boolean | null
|
||||
manage_inventory: boolean | null
|
||||
hs_code: string | null
|
||||
origin_country: string | null
|
||||
mid_code: string | null
|
||||
material: string | null
|
||||
weight: number | null
|
||||
length: number | null
|
||||
height: number | null
|
||||
width: number | null
|
||||
options: BaseProductOptionValue[] | null
|
||||
product?: BaseProduct | null
|
||||
product_id?: string
|
||||
variant_rank?: number | null
|
||||
created_at: string
|
||||
updated_at: string
|
||||
deleted_at: string | null
|
||||
metadata?: Record<string, unknown> | null
|
||||
}
|
||||
|
||||
export interface BaseProductCategory {
|
||||
id?: string
|
||||
name?: string
|
||||
description?: string | null
|
||||
handle?: string
|
||||
id: string
|
||||
name: string
|
||||
description: string | null
|
||||
handle: string
|
||||
rank?: number
|
||||
parent_category?: BaseProductCategory
|
||||
parent_category_id?: string
|
||||
parent_category?: BaseProductCategory | null
|
||||
parent_category_id?: string | null
|
||||
category_children?: BaseProductCategory[]
|
||||
products?: BaseProduct[]
|
||||
created_at?: string
|
||||
updated_at?: string
|
||||
metadata?: Record<string, unknown>
|
||||
metadata?: Record<string, unknown> | null
|
||||
}
|
||||
|
||||
export interface BaseProductTag {
|
||||
id?: string
|
||||
value?: string
|
||||
id: string
|
||||
value: string
|
||||
products?: BaseProduct[]
|
||||
metadata?: Record<string, unknown> | null
|
||||
}
|
||||
|
||||
export interface BaseProductType {
|
||||
id?: string
|
||||
value?: string
|
||||
id: string
|
||||
value: string
|
||||
created_at?: string
|
||||
updated_at?: string
|
||||
deleted_at?: string | null
|
||||
@@ -96,10 +96,10 @@ export interface BaseProductType {
|
||||
}
|
||||
|
||||
export interface BaseProductOption {
|
||||
id?: string
|
||||
title?: string
|
||||
product?: BaseProduct
|
||||
product_id?: string
|
||||
id: string
|
||||
title: string
|
||||
product?: BaseProduct | null
|
||||
product_id?: string | null
|
||||
values?: BaseProductOptionValue[]
|
||||
metadata?: Record<string, unknown> | null
|
||||
created_at?: string
|
||||
@@ -108,8 +108,8 @@ export interface BaseProductOption {
|
||||
}
|
||||
|
||||
export interface BaseProductImage {
|
||||
id?: string
|
||||
url?: string
|
||||
id: string
|
||||
url: string
|
||||
created_at?: string
|
||||
updated_at?: string
|
||||
deleted_at?: string | null
|
||||
@@ -117,19 +117,22 @@ export interface BaseProductImage {
|
||||
}
|
||||
|
||||
export interface BaseProductOptionValue {
|
||||
id?: string
|
||||
value?: string
|
||||
option?: BaseProductOption
|
||||
option_id?: string
|
||||
id: string
|
||||
value: string
|
||||
option?: BaseProductOption | null
|
||||
option_id?: string | null
|
||||
metadata?: Record<string, unknown> | null
|
||||
created_at?: string
|
||||
updated_at?: string
|
||||
deleted_at?: string | null
|
||||
}
|
||||
|
||||
export interface BaseProductFilters extends BaseFilterable<BaseProductFilters> {
|
||||
export interface BaseProductParams
|
||||
extends FindParams,
|
||||
BaseFilterable<BaseProductParams> {
|
||||
q?: string
|
||||
status?: ProductStatus | ProductStatus[]
|
||||
sales_channel_id?: string | string[]
|
||||
title?: string | string[]
|
||||
handle?: string | string[]
|
||||
id?: string | string[]
|
||||
@@ -146,30 +149,34 @@ export interface BaseProductFilters extends BaseFilterable<BaseProductFilters> {
|
||||
deleted_at?: OperatorMap<string>
|
||||
}
|
||||
|
||||
export interface BaseProductTagFilters
|
||||
extends BaseFilterable<BaseProductTagFilters> {
|
||||
export interface BaseProductTagParams
|
||||
extends FindParams,
|
||||
BaseFilterable<BaseProductTagParams> {
|
||||
q?: string
|
||||
id?: string | string[]
|
||||
value?: string | string[]
|
||||
}
|
||||
|
||||
export interface BaseProductTypeFilters
|
||||
extends BaseFilterable<BaseProductTypeFilters> {
|
||||
export interface BaseProductTypeParams
|
||||
extends FindParams,
|
||||
BaseFilterable<BaseProductTypeParams> {
|
||||
q?: string
|
||||
id?: string | string[]
|
||||
value?: string
|
||||
}
|
||||
|
||||
export interface BaseProductOptionFilters
|
||||
extends BaseFilterable<BaseProductOptionFilters> {
|
||||
export interface BaseProductOptionParams
|
||||
extends FindParams,
|
||||
BaseFilterable<BaseProductOptionParams> {
|
||||
q?: string
|
||||
id?: string | string[]
|
||||
title?: string | string[]
|
||||
product_id?: string | string[]
|
||||
}
|
||||
|
||||
export interface BaseProductVariantFilters
|
||||
extends BaseFilterable<BaseProductVariantFilters> {
|
||||
export interface BaseProductVariantParams
|
||||
extends FindParams,
|
||||
BaseFilterable<BaseProductVariantParams> {
|
||||
q?: string
|
||||
id?: string | string[]
|
||||
sku?: string | string[]
|
||||
@@ -177,8 +184,9 @@ export interface BaseProductVariantFilters
|
||||
options?: Record<string, string>
|
||||
}
|
||||
|
||||
export interface BaseProductCategoryFilters
|
||||
extends BaseFilterable<BaseProductCategoryFilters> {
|
||||
export interface BaseProductCategoryParams
|
||||
extends FindParams,
|
||||
BaseFilterable<BaseProductCategoryParams> {
|
||||
q?: string
|
||||
id?: string | string[]
|
||||
name?: string | string[]
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
import {
|
||||
BaseProduct,
|
||||
BaseProductCategory,
|
||||
BaseProductCategoryFilters,
|
||||
BaseProductFilters,
|
||||
BaseProductImage,
|
||||
BaseProductOption,
|
||||
BaseProductOptionFilters,
|
||||
BaseProductOptionValue,
|
||||
BaseProductTag,
|
||||
BaseProductTagFilters,
|
||||
BaseProductType,
|
||||
BaseProductTypeFilters,
|
||||
BaseProductVariant,
|
||||
BaseProductVariantFilters,
|
||||
} from "./common"
|
||||
|
||||
export interface StoreProduct extends BaseProduct {}
|
||||
export interface StoreProductCategory extends BaseProductCategory {}
|
||||
export interface StoreProductVariant extends BaseProductVariant {}
|
||||
export interface StoreProductTag extends BaseProductTag {}
|
||||
export interface StoreProductType extends BaseProductType {}
|
||||
export interface StoreProductOption extends BaseProductOption {}
|
||||
export interface StoreProductImage extends BaseProductImage {}
|
||||
export interface StoreProductOptionValue extends BaseProductOptionValue {}
|
||||
|
||||
export interface StoreProductTagFilters extends BaseProductTagFilters {}
|
||||
export interface StoreProductTypeFilters extends BaseProductTypeFilters {}
|
||||
export interface StoreProductOptionFilters extends BaseProductOptionFilters {}
|
||||
export interface StoreProductVariantFilters extends BaseProductVariantFilters {}
|
||||
export interface StoreProductFilters extends BaseProductFilters {
|
||||
// The region ID and currency_code are not filters, but are used for the pricing context. Maybe move to separate type definition.
|
||||
region_id?: string
|
||||
currency_code?: string
|
||||
variants?: StoreProductVariantFilters
|
||||
}
|
||||
export interface StoreProductCategoryFilters
|
||||
extends BaseProductCategoryFilters {}
|
||||
@@ -0,0 +1,21 @@
|
||||
import {
|
||||
BaseProduct,
|
||||
BaseProductCategory,
|
||||
BaseProductImage,
|
||||
BaseProductOption,
|
||||
BaseProductOptionValue,
|
||||
BaseProductTag,
|
||||
BaseProductType,
|
||||
BaseProductVariant,
|
||||
ProductStatus,
|
||||
} from "../common"
|
||||
|
||||
export interface StoreProduct extends BaseProduct {}
|
||||
export interface StoreProductCategory extends BaseProductCategory {}
|
||||
export interface StoreProductVariant extends BaseProductVariant {}
|
||||
export interface StoreProductTag extends BaseProductTag {}
|
||||
export interface StoreProductType extends BaseProductType {}
|
||||
export interface StoreProductOption extends BaseProductOption {}
|
||||
export interface StoreProductImage extends BaseProductImage {}
|
||||
export interface StoreProductOptionValue extends BaseProductOptionValue {}
|
||||
export type StoreProductStatus = ProductStatus
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from "./entitites"
|
||||
export * from "./responses"
|
||||
export * from "./queries"
|
||||
@@ -0,0 +1,20 @@
|
||||
import {
|
||||
BaseProductCategoryParams,
|
||||
BaseProductParams,
|
||||
BaseProductOptionParams,
|
||||
BaseProductTagParams,
|
||||
BaseProductTypeParams,
|
||||
BaseProductVariantParams,
|
||||
} from "../common"
|
||||
|
||||
export interface StoreProductTagParams extends BaseProductTagParams {}
|
||||
export interface StoreProductTypeParams extends BaseProductTypeParams {}
|
||||
export interface StoreProductOptionParams extends BaseProductOptionParams {}
|
||||
export interface StoreProductVariantParams extends BaseProductVariantParams {}
|
||||
export interface StoreProductParams extends BaseProductParams {
|
||||
// The region ID and currency_code are not params, but are used for the pricing context. Maybe move to separate type definition.
|
||||
region_id?: string
|
||||
currency_code?: string
|
||||
variants?: StoreProductVariantParams
|
||||
}
|
||||
export interface StoreProductCategoryParams extends BaseProductCategoryParams {}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { PaginatedResponse } from "../../common"
|
||||
import { StoreProduct } from "../store"
|
||||
|
||||
export interface StoreProductResponse {
|
||||
product: StoreProduct
|
||||
}
|
||||
|
||||
export type StoreProductListResponse = PaginatedResponse<{
|
||||
products: StoreProduct[]
|
||||
}>
|
||||
@@ -1,7 +1,9 @@
|
||||
import { OperatorMap } from "../../../dal"
|
||||
import { BaseFilterable, OperatorMap } from "../../../dal"
|
||||
import { FindParams } from "../../common"
|
||||
|
||||
export interface AdminSalesChannelListParams extends FindParams {
|
||||
export interface AdminSalesChannelListParams
|
||||
extends FindParams,
|
||||
BaseFilterable<AdminSalesChannelListParams> {
|
||||
id?: string | string[]
|
||||
q?: string
|
||||
name?: string | string[]
|
||||
@@ -12,6 +14,4 @@ export interface AdminSalesChannelListParams extends FindParams {
|
||||
created_at?: OperatorMap<string>
|
||||
updated_at?: OperatorMap<string>
|
||||
deleted_at?: OperatorMap<string>
|
||||
$and?: AdminSalesChannelListParams[]
|
||||
$or?: AdminSalesChannelListParams[]
|
||||
}
|
||||
|
||||
@@ -23,15 +23,15 @@ export interface ProductDTO {
|
||||
/**
|
||||
* The handle of the product. The handle can be used to create slug URL paths.
|
||||
*/
|
||||
handle?: string | null
|
||||
handle: string
|
||||
/**
|
||||
* The subttle of the product.
|
||||
*/
|
||||
subtitle?: string | null
|
||||
subtitle: string | null
|
||||
/**
|
||||
* The description of the product.
|
||||
*/
|
||||
description?: string | null
|
||||
description: string | null
|
||||
/**
|
||||
* Whether the product is a gift card.
|
||||
*/
|
||||
@@ -43,49 +43,49 @@ export interface ProductDTO {
|
||||
/**
|
||||
* The URL of the product's thumbnail.
|
||||
*/
|
||||
thumbnail?: string | null
|
||||
thumbnail: string | null
|
||||
/**
|
||||
* The width of the product.
|
||||
*/
|
||||
width?: number | null
|
||||
width: number | null
|
||||
/**
|
||||
* The weight of the product.
|
||||
*/
|
||||
weight?: number | null
|
||||
weight: number | null
|
||||
/**
|
||||
* The length of the product.
|
||||
*/
|
||||
length?: number | null
|
||||
length: number | null
|
||||
/**
|
||||
* The height of the product.
|
||||
*/
|
||||
height?: number | null
|
||||
height: number | null
|
||||
/**
|
||||
* The origin country of the product.
|
||||
*/
|
||||
origin_country?: string | null
|
||||
origin_country: string | null
|
||||
/**
|
||||
* The HS Code of the product.
|
||||
*/
|
||||
hs_code?: string | null
|
||||
hs_code: string | null
|
||||
/**
|
||||
* The MID Code of the product.
|
||||
*/
|
||||
mid_code?: string | null
|
||||
mid_code: string | null
|
||||
/**
|
||||
* The material of the product.
|
||||
*/
|
||||
material?: string | null
|
||||
material: string | null
|
||||
/**
|
||||
* The associated product collection.
|
||||
*
|
||||
* @expandable
|
||||
*/
|
||||
collection?: ProductCollectionDTO | null
|
||||
collection: ProductCollectionDTO | null
|
||||
/**
|
||||
* The associated product collection id.
|
||||
*/
|
||||
collection_id?: string | null
|
||||
collection_id: string | null
|
||||
/**
|
||||
* The associated product categories.
|
||||
*
|
||||
@@ -97,11 +97,11 @@ export interface ProductDTO {
|
||||
*
|
||||
* @expandable
|
||||
*/
|
||||
type?: ProductTypeDTO | null
|
||||
type: ProductTypeDTO | null
|
||||
/**
|
||||
* The associated product type id.
|
||||
*/
|
||||
type_id?: string | null
|
||||
type_id: string | null
|
||||
/**
|
||||
* The associated product tags.
|
||||
*
|
||||
@@ -134,19 +134,19 @@ export interface ProductDTO {
|
||||
* The ID of the product in an external system. This is useful if you're integrating the product with a third-party service and want to maintain
|
||||
* a reference to the ID in the integrated service.
|
||||
*/
|
||||
external_id?: string | null
|
||||
external_id: string | null
|
||||
/**
|
||||
* When the product was created.
|
||||
*/
|
||||
created_at?: string | Date
|
||||
created_at: string | Date
|
||||
/**
|
||||
* When the product was updated.
|
||||
*/
|
||||
updated_at?: string | Date
|
||||
updated_at: string | Date
|
||||
/**
|
||||
* When the product was deleted.
|
||||
*/
|
||||
deleted_at?: string | Date
|
||||
deleted_at: string | Date
|
||||
/**
|
||||
* Holds custom data in key-value pairs.
|
||||
*/
|
||||
@@ -170,59 +170,59 @@ export interface ProductVariantDTO {
|
||||
/**
|
||||
* The SKU of the product variant.
|
||||
*/
|
||||
sku?: string | null
|
||||
sku: string | null
|
||||
/**
|
||||
* The barcode of the product variant.
|
||||
*/
|
||||
barcode?: string | null
|
||||
barcode: string | null
|
||||
/**
|
||||
* The EAN of the product variant.
|
||||
*/
|
||||
ean?: string | null
|
||||
ean: string | null
|
||||
/**
|
||||
* The UPC of the product variant.
|
||||
*/
|
||||
upc?: string | null
|
||||
upc: string | null
|
||||
/**
|
||||
* Whether the product variant can be ordered when it's out of stock.
|
||||
*/
|
||||
allow_backorder?: boolean
|
||||
allow_backorder: boolean
|
||||
/**
|
||||
* Whether the product variant's inventory should be managed by the core system.
|
||||
*/
|
||||
manage_inventory?: boolean
|
||||
manage_inventory: boolean
|
||||
/**
|
||||
* The HS Code of the product variant.
|
||||
*/
|
||||
hs_code?: string | null
|
||||
hs_code: string | null
|
||||
/**
|
||||
* The origin country of the product variant.
|
||||
*/
|
||||
origin_country?: string | null
|
||||
origin_country: string | null
|
||||
/**
|
||||
* The MID Code of the product variant.
|
||||
*/
|
||||
mid_code?: string | null
|
||||
mid_code: string | null
|
||||
/**
|
||||
* The material of the product variant.
|
||||
*/
|
||||
material?: string | null
|
||||
material: string | null
|
||||
/**
|
||||
* The weight of the product variant.
|
||||
*/
|
||||
weight?: number | null
|
||||
weight: number | null
|
||||
/**
|
||||
* The length of the product variant.
|
||||
*/
|
||||
length?: number | null
|
||||
length: number | null
|
||||
/**
|
||||
* The height of the product variant.
|
||||
*/
|
||||
height?: number | null
|
||||
height: number | null
|
||||
/**
|
||||
* The width of the product variant.
|
||||
*/
|
||||
width?: number | null
|
||||
width: number | null
|
||||
/**
|
||||
* The associated product options.
|
||||
*
|
||||
@@ -232,7 +232,7 @@ export interface ProductVariantDTO {
|
||||
/**
|
||||
* Holds custom data in key-value pairs.
|
||||
*/
|
||||
metadata?: Record<string, unknown> | null
|
||||
metadata: Record<string, unknown> | null
|
||||
/**
|
||||
* The associated product.
|
||||
*
|
||||
@@ -242,7 +242,7 @@ export interface ProductVariantDTO {
|
||||
/**
|
||||
* The associated product id.
|
||||
*/
|
||||
product_id?: string | null
|
||||
product_id: string | null
|
||||
/**
|
||||
* he ranking of the variant among other variants associated with the product.
|
||||
*/
|
||||
@@ -1183,19 +1183,19 @@ export interface CreateProductVariantDTO {
|
||||
/**
|
||||
* The SKU of the product variant.
|
||||
*/
|
||||
sku?: string | null
|
||||
sku?: string
|
||||
/**
|
||||
* The barcode of the product variant.
|
||||
*/
|
||||
barcode?: string | null
|
||||
barcode?: string
|
||||
/**
|
||||
* The EAN of the product variant.
|
||||
*/
|
||||
ean?: string | null
|
||||
ean?: string
|
||||
/**
|
||||
* The UPC of the product variant.
|
||||
*/
|
||||
upc?: string | null
|
||||
upc?: string
|
||||
/**
|
||||
* Whether the product variant can be ordered when it's out of stock.
|
||||
*/
|
||||
@@ -1207,35 +1207,35 @@ export interface CreateProductVariantDTO {
|
||||
/**
|
||||
* The HS Code of the product variant.
|
||||
*/
|
||||
hs_code?: string | null
|
||||
hs_code?: string
|
||||
/**
|
||||
* The origin country of the product variant.
|
||||
*/
|
||||
origin_country?: string | null
|
||||
origin_country?: string
|
||||
/**
|
||||
* The MID Code of the product variant.
|
||||
*/
|
||||
mid_code?: string | null
|
||||
mid_code?: string
|
||||
/**
|
||||
* The material of the product variant.
|
||||
*/
|
||||
material?: string | null
|
||||
material?: string
|
||||
/**
|
||||
* The weight of the product variant.
|
||||
*/
|
||||
weight?: number | null
|
||||
weight?: number
|
||||
/**
|
||||
* The length of the product variant.
|
||||
*/
|
||||
length?: number | null
|
||||
length?: number
|
||||
/**
|
||||
* The height of the product variant.
|
||||
*/
|
||||
height?: number | null
|
||||
height?: number
|
||||
/**
|
||||
* The width of the product variant.
|
||||
*/
|
||||
width?: number | null
|
||||
width?: number
|
||||
/**
|
||||
* The options of the variant. Each key is an option's title, and value
|
||||
* is an option's value. If an option with the specified title doesn't exist,
|
||||
@@ -1340,7 +1340,7 @@ export interface UpdateProductVariantDTO {
|
||||
/**
|
||||
* Holds custom data in key-value pairs.
|
||||
*/
|
||||
metadata?: Record<string, unknown>
|
||||
metadata?: Record<string, unknown> | null
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1472,11 +1472,11 @@ export interface UpdateProductDTO {
|
||||
/**
|
||||
* The subttle of the product.
|
||||
*/
|
||||
subtitle?: string
|
||||
subtitle?: string | null
|
||||
/**
|
||||
* The description of the product.
|
||||
*/
|
||||
description?: string
|
||||
description?: string | null
|
||||
/**
|
||||
* Whether the product is a gift card.
|
||||
*/
|
||||
@@ -1488,7 +1488,7 @@ export interface UpdateProductDTO {
|
||||
/**
|
||||
* The URL of the product's thumbnail.
|
||||
*/
|
||||
thumbnail?: string
|
||||
thumbnail?: string | null
|
||||
/**
|
||||
* The handle of the product. The handle can be used to create slug URL paths.
|
||||
* If not supplied, the value of the `handle` attribute of the product is set to the slug version of the `title` attribute.
|
||||
@@ -1530,37 +1530,37 @@ export interface UpdateProductDTO {
|
||||
/**
|
||||
* The width of the product.
|
||||
*/
|
||||
width?: number
|
||||
width?: number | null
|
||||
/**
|
||||
* The height of the product.
|
||||
*/
|
||||
height?: number
|
||||
height?: number | null
|
||||
/**
|
||||
* The length of the product.
|
||||
*/
|
||||
length?: number
|
||||
length?: number | null
|
||||
/**
|
||||
* The weight of the product.
|
||||
*/
|
||||
weight?: number
|
||||
weight?: number | null
|
||||
/**
|
||||
* The origin country of the product.
|
||||
*/
|
||||
origin_country?: string
|
||||
origin_country?: string | null
|
||||
/**
|
||||
* The HS Code of the product.
|
||||
*/
|
||||
hs_code?: string
|
||||
hs_code?: string | null
|
||||
/**
|
||||
* The material of the product.
|
||||
*/
|
||||
material?: string
|
||||
material?: string | null
|
||||
/**
|
||||
* The MID Code of the product.
|
||||
*/
|
||||
mid_code?: string
|
||||
mid_code?: string | null
|
||||
/**
|
||||
* Holds custom data in key-value pairs.
|
||||
*/
|
||||
metadata?: Record<string, unknown>
|
||||
metadata?: Record<string, unknown> | null
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@ export type CreateProductVariantWorkflowInputDTO =
|
||||
}
|
||||
|
||||
export type UpdateProductVariantWorkflowInputDTO =
|
||||
(ProductTypes.UpsertProductVariantDTO & {
|
||||
ProductTypes.UpsertProductVariantDTO & {
|
||||
prices?: PricingTypes.CreateMoneyAmountDTO[]
|
||||
})[]
|
||||
}
|
||||
|
||||
export type CreateProductWorkflowInputDTO = Omit<
|
||||
ProductTypes.CreateProductDTO,
|
||||
|
||||
@@ -7,37 +7,29 @@ import {
|
||||
updateProductOptionsWorkflow,
|
||||
} from "@medusajs/core-flows"
|
||||
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import { refetchProduct, remapProductResponse } from "../../../helpers"
|
||||
import { AdminUpdateProductOptionType } from "../../../validators"
|
||||
import { remapKeysForProduct, remapProductResponse } from "../../../helpers"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import { refetchEntity } from "../../../../../utils/refetch-entity"
|
||||
|
||||
export const GET = async (
|
||||
req: AuthenticatedMedusaRequest,
|
||||
res: MedusaResponse
|
||||
res: MedusaResponse<HttpTypes.AdminProductOptionResponse>
|
||||
) => {
|
||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
|
||||
const productId = req.params.id
|
||||
const optionId = req.params.option_id
|
||||
const productOption = await refetchEntity(
|
||||
"product_option",
|
||||
{ id: optionId, product_id: productId },
|
||||
req.scope,
|
||||
req.remoteQueryConfig.fields
|
||||
)
|
||||
|
||||
const variables = { id: optionId, product_id: productId }
|
||||
|
||||
const queryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "product_option",
|
||||
variables,
|
||||
fields: req.remoteQueryConfig.fields,
|
||||
})
|
||||
|
||||
const [product_option] = await remoteQuery(queryObject)
|
||||
res.status(200).json({ product_option })
|
||||
res.status(200).json({ product_option: productOption })
|
||||
}
|
||||
|
||||
export const POST = async (
|
||||
req: AuthenticatedMedusaRequest<AdminUpdateProductOptionType>,
|
||||
res: MedusaResponse
|
||||
req: AuthenticatedMedusaRequest<HttpTypes.AdminUpdateProductOption>,
|
||||
res: MedusaResponse<HttpTypes.AdminProductResponse>
|
||||
) => {
|
||||
const productId = req.params.id
|
||||
const optionId = req.params.option_id
|
||||
@@ -49,17 +41,19 @@ export const POST = async (
|
||||
},
|
||||
})
|
||||
|
||||
const product = await refetchProduct(
|
||||
const product = await refetchEntity(
|
||||
"product",
|
||||
productId,
|
||||
req.scope,
|
||||
req.remoteQueryConfig.fields
|
||||
remapKeysForProduct(req.remoteQueryConfig.fields ?? [])
|
||||
)
|
||||
|
||||
res.status(200).json({ product: remapProductResponse(product) })
|
||||
}
|
||||
|
||||
export const DELETE = async (
|
||||
req: AuthenticatedMedusaRequest,
|
||||
res: MedusaResponse
|
||||
res: MedusaResponse<HttpTypes.AdminProductOptionDeleteResponse>
|
||||
) => {
|
||||
const productId = req.params.id
|
||||
const optionId = req.params.option_id
|
||||
@@ -69,10 +63,11 @@ export const DELETE = async (
|
||||
input: { ids: [optionId] /* product_id: productId */ },
|
||||
})
|
||||
|
||||
const product = await refetchProduct(
|
||||
const product = await refetchEntity(
|
||||
"product",
|
||||
productId,
|
||||
req.scope,
|
||||
req.remoteQueryConfig.fields
|
||||
remapKeysForProduct(req.remoteQueryConfig.fields ?? [])
|
||||
)
|
||||
|
||||
res.status(200).json({
|
||||
|
||||
@@ -4,30 +4,25 @@ import {
|
||||
} from "../../../../../types/routing"
|
||||
|
||||
import { createProductOptionsWorkflow } from "@medusajs/core-flows"
|
||||
import { remapKeysForProduct, remapProductResponse } from "../../helpers"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import { refetchProduct, remapProductResponse } from "../../helpers"
|
||||
import { AdminCreateProductOptionType } from "../../validators"
|
||||
refetchEntities,
|
||||
refetchEntity,
|
||||
} from "../../../../utils/refetch-entity"
|
||||
|
||||
export const GET = async (
|
||||
req: AuthenticatedMedusaRequest,
|
||||
res: MedusaResponse
|
||||
req: AuthenticatedMedusaRequest<HttpTypes.AdminProductOptionParams>,
|
||||
res: MedusaResponse<HttpTypes.AdminProductOptionListResponse>
|
||||
) => {
|
||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
const productId = req.params.id
|
||||
|
||||
const queryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "product_option",
|
||||
variables: {
|
||||
filters: { ...req.filterableFields, product_id: productId },
|
||||
...req.remoteQueryConfig.pagination,
|
||||
},
|
||||
fields: req.remoteQueryConfig.fields,
|
||||
})
|
||||
|
||||
const { rows: product_options, metadata } = await remoteQuery(queryObject)
|
||||
const { rows: product_options, metadata } = await refetchEntities(
|
||||
"product_option",
|
||||
{ ...req.filterableFields, product_id: productId },
|
||||
req.scope,
|
||||
req.remoteQueryConfig.fields,
|
||||
req.remoteQueryConfig.pagination
|
||||
)
|
||||
|
||||
res.json({
|
||||
product_options,
|
||||
@@ -38,25 +33,26 @@ export const GET = async (
|
||||
}
|
||||
|
||||
export const POST = async (
|
||||
req: AuthenticatedMedusaRequest<AdminCreateProductOptionType>,
|
||||
res: MedusaResponse
|
||||
req: AuthenticatedMedusaRequest<HttpTypes.AdminCreateProductOption>,
|
||||
res: MedusaResponse<HttpTypes.AdminProductResponse>
|
||||
) => {
|
||||
const productId = req.params.id
|
||||
const input = [
|
||||
{
|
||||
...req.validatedBody,
|
||||
product_id: productId,
|
||||
},
|
||||
]
|
||||
|
||||
await createProductOptionsWorkflow(req.scope).run({
|
||||
input: { product_options: input },
|
||||
input: {
|
||||
product_options: [
|
||||
{
|
||||
...req.validatedBody,
|
||||
product_id: productId,
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
const product = await refetchProduct(
|
||||
const product = await refetchEntity(
|
||||
"product",
|
||||
productId,
|
||||
req.scope,
|
||||
req.remoteQueryConfig.fields
|
||||
remapKeysForProduct(req.remoteQueryConfig.fields ?? [])
|
||||
)
|
||||
res.status(200).json({ product: remapProductResponse(product) })
|
||||
}
|
||||
|
||||
@@ -6,36 +6,23 @@ import {
|
||||
AuthenticatedMedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "../../../../types/routing"
|
||||
|
||||
import { UpdateProductDTO } from "@medusajs/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import {
|
||||
refetchProduct,
|
||||
remapKeysForProduct,
|
||||
remapProductResponse,
|
||||
} from "../helpers"
|
||||
import { AdminUpdateProductType } from "../validators"
|
||||
import { remapKeysForProduct, remapProductResponse } from "../helpers"
|
||||
import { MedusaError } from "@medusajs/utils"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import { refetchEntity } from "../../../utils/refetch-entity"
|
||||
|
||||
export const GET = async (
|
||||
req: AuthenticatedMedusaRequest,
|
||||
res: MedusaResponse
|
||||
res: MedusaResponse<HttpTypes.AdminProductResponse>
|
||||
) => {
|
||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
|
||||
const variables = { id: req.params.id }
|
||||
|
||||
const selectFields = remapKeysForProduct(req.remoteQueryConfig.fields ?? [])
|
||||
const queryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "product",
|
||||
variables,
|
||||
fields: selectFields,
|
||||
})
|
||||
const product = await refetchEntity(
|
||||
"product",
|
||||
req.params.id,
|
||||
req.scope,
|
||||
selectFields
|
||||
)
|
||||
|
||||
const [product] = await remoteQuery(queryObject)
|
||||
if (!product) {
|
||||
throw new MedusaError(MedusaError.Types.NOT_FOUND, "Product not found")
|
||||
}
|
||||
@@ -44,27 +31,29 @@ export const GET = async (
|
||||
}
|
||||
|
||||
export const POST = async (
|
||||
req: AuthenticatedMedusaRequest<AdminUpdateProductType>,
|
||||
res: MedusaResponse
|
||||
req: AuthenticatedMedusaRequest<HttpTypes.AdminUpdateProduct>,
|
||||
res: MedusaResponse<HttpTypes.AdminProductResponse>
|
||||
) => {
|
||||
const { result } = await updateProductsWorkflow(req.scope).run({
|
||||
input: {
|
||||
selector: { id: req.params.id },
|
||||
update: req.validatedBody as UpdateProductDTO,
|
||||
update: req.validatedBody,
|
||||
},
|
||||
})
|
||||
|
||||
const product = await refetchProduct(
|
||||
const product = await refetchEntity(
|
||||
"product",
|
||||
result[0].id,
|
||||
req.scope,
|
||||
req.remoteQueryConfig.fields
|
||||
remapKeysForProduct(req.remoteQueryConfig.fields ?? [])
|
||||
)
|
||||
|
||||
res.status(200).json({ product: remapProductResponse(product) })
|
||||
}
|
||||
|
||||
export const DELETE = async (
|
||||
req: AuthenticatedMedusaRequest,
|
||||
res: MedusaResponse
|
||||
res: MedusaResponse<HttpTypes.AdminProductDeleteResponse>
|
||||
) => {
|
||||
const id = req.params.id
|
||||
|
||||
|
||||
@@ -8,44 +8,36 @@ import {
|
||||
} from "@medusajs/core-flows"
|
||||
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import {
|
||||
refetchProduct,
|
||||
remapKeysForProduct,
|
||||
remapKeysForVariant,
|
||||
remapProductResponse,
|
||||
remapVariantResponse,
|
||||
} from "../../../helpers"
|
||||
import { AdminUpdateProductVariantType } from "../../../validators"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import { refetchEntity } from "../../../../../utils/refetch-entity"
|
||||
|
||||
export const GET = async (
|
||||
req: AuthenticatedMedusaRequest,
|
||||
res: MedusaResponse
|
||||
res: MedusaResponse<HttpTypes.AdminProductVariantResponse>
|
||||
) => {
|
||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
|
||||
// TODO: Should we allow fetching a variant without knowing the product ID? In such case we'll need to change the route to /admin/products/variants/:id
|
||||
const productId = req.params.id
|
||||
const variantId = req.params.variant_id
|
||||
|
||||
const variables = { id: variantId, product_id: productId }
|
||||
|
||||
const queryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "variant",
|
||||
const variant = await refetchEntity(
|
||||
"variant",
|
||||
variables,
|
||||
fields: remapKeysForVariant(req.remoteQueryConfig.fields ?? []),
|
||||
})
|
||||
req.scope,
|
||||
remapKeysForVariant(req.remoteQueryConfig.fields ?? [])
|
||||
)
|
||||
|
||||
const [variant] = await remoteQuery(queryObject)
|
||||
res.status(200).json({ variant: remapVariantResponse(variant) })
|
||||
}
|
||||
|
||||
export const POST = async (
|
||||
req: AuthenticatedMedusaRequest<AdminUpdateProductVariantType>,
|
||||
res: MedusaResponse
|
||||
req: AuthenticatedMedusaRequest<HttpTypes.AdminUpdateProductVariant>,
|
||||
res: MedusaResponse<HttpTypes.AdminProductResponse>
|
||||
) => {
|
||||
// TODO: Should we allow fetching a variant without knowing the product ID? In such case we'll need to change the route to /admin/products/variants/:id
|
||||
const productId = req.params.id
|
||||
const variantId = req.params.variant_id
|
||||
|
||||
@@ -56,19 +48,19 @@ export const POST = async (
|
||||
},
|
||||
})
|
||||
|
||||
const product = await refetchProduct(
|
||||
const product = await refetchEntity(
|
||||
"product",
|
||||
productId,
|
||||
req.scope,
|
||||
req.remoteQueryConfig.fields
|
||||
remapKeysForProduct(req.remoteQueryConfig.fields ?? [])
|
||||
)
|
||||
res.status(200).json({ product: remapProductResponse(product) })
|
||||
}
|
||||
|
||||
export const DELETE = async (
|
||||
req: AuthenticatedMedusaRequest,
|
||||
res: MedusaResponse
|
||||
res: MedusaResponse<HttpTypes.AdminProductVariantDeleteResponse>
|
||||
) => {
|
||||
// TODO: Should we allow fetching a variant without knowing the product ID? In such case we'll need to change the route to /admin/products/variants/:id
|
||||
const productId = req.params.id
|
||||
const variantId = req.params.variant_id
|
||||
|
||||
@@ -77,16 +69,17 @@ export const DELETE = async (
|
||||
input: { ids: [variantId] /* product_id: productId */ },
|
||||
})
|
||||
|
||||
const product = await refetchProduct(
|
||||
const product = await refetchEntity(
|
||||
"product",
|
||||
productId,
|
||||
req.scope,
|
||||
req.remoteQueryConfig.fields
|
||||
remapKeysForProduct(req.remoteQueryConfig.fields ?? [])
|
||||
)
|
||||
|
||||
res.status(200).json({
|
||||
id: variantId,
|
||||
object: "variant",
|
||||
deleted: true,
|
||||
parent: product,
|
||||
parent: remapProductResponse(product),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,21 +3,12 @@ import {
|
||||
AuthenticatedMedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "../../../../../../types/routing"
|
||||
import {
|
||||
AdminBatchUpdateProductVariantType,
|
||||
AdminCreateProductType,
|
||||
} from "../../../validators"
|
||||
import { BatchMethodRequest } from "@medusajs/types"
|
||||
import { refetchBatchVariants, remapVariantResponse } from "../../../helpers"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
export const POST = async (
|
||||
req: AuthenticatedMedusaRequest<
|
||||
BatchMethodRequest<
|
||||
AdminCreateProductType,
|
||||
AdminBatchUpdateProductVariantType
|
||||
>
|
||||
>,
|
||||
res: MedusaResponse
|
||||
req: AuthenticatedMedusaRequest<HttpTypes.AdminBatchProductVariantRequest>,
|
||||
res: MedusaResponse<HttpTypes.AdminBatchProductVariantResponse>
|
||||
) => {
|
||||
const productId = req.params.id
|
||||
|
||||
@@ -31,8 +22,7 @@ export const POST = async (
|
||||
product_id: productId,
|
||||
})),
|
||||
delete: req.validatedBody.delete,
|
||||
// TODO: Fix types
|
||||
} as any
|
||||
}
|
||||
|
||||
const { result } = await batchProductVariantsWorkflow(req.scope).run({
|
||||
input: normalizedInput,
|
||||
|
||||
@@ -5,36 +5,29 @@ import {
|
||||
|
||||
import { createProductVariantsWorkflow } from "@medusajs/core-flows"
|
||||
import {
|
||||
remoteQueryObjectFromString,
|
||||
ContainerRegistrationKeys,
|
||||
} from "@medusajs/utils"
|
||||
import {
|
||||
refetchProduct,
|
||||
remapKeysForProduct,
|
||||
remapKeysForVariant,
|
||||
remapProductResponse,
|
||||
remapVariantResponse,
|
||||
} from "../../helpers"
|
||||
import { AdminCreateProductVariantType } from "../../validators"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import {
|
||||
refetchEntities,
|
||||
refetchEntity,
|
||||
} from "../../../../utils/refetch-entity"
|
||||
|
||||
export const GET = async (
|
||||
req: AuthenticatedMedusaRequest,
|
||||
res: MedusaResponse
|
||||
res: MedusaResponse<HttpTypes.AdminProductVariantListResponse>
|
||||
) => {
|
||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
const productId = req.params.id
|
||||
|
||||
const queryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "variant",
|
||||
variables: {
|
||||
filters: { ...req.filterableFields, product_id: productId },
|
||||
order: req.listConfig.order,
|
||||
skip: req.listConfig.skip,
|
||||
take: req.listConfig.take,
|
||||
},
|
||||
fields: remapKeysForVariant(req.remoteQueryConfig.fields ?? []),
|
||||
})
|
||||
|
||||
const { rows: variants, metadata } = await remoteQuery(queryObject)
|
||||
const { rows: variants, metadata } = await refetchEntities(
|
||||
"variant",
|
||||
{ ...req.filterableFields, product_id: productId },
|
||||
req.scope,
|
||||
remapKeysForVariant(req.remoteQueryConfig.fields ?? []),
|
||||
req.remoteQueryConfig.pagination
|
||||
)
|
||||
|
||||
res.json({
|
||||
variants: variants.map(remapVariantResponse),
|
||||
@@ -45,8 +38,8 @@ export const GET = async (
|
||||
}
|
||||
|
||||
export const POST = async (
|
||||
req: AuthenticatedMedusaRequest<AdminCreateProductVariantType>,
|
||||
res: MedusaResponse
|
||||
req: AuthenticatedMedusaRequest<HttpTypes.AdminCreateProductVariant>,
|
||||
res: MedusaResponse<HttpTypes.AdminProductResponse>
|
||||
) => {
|
||||
const productId = req.params.id
|
||||
const input = [
|
||||
@@ -60,10 +53,12 @@ export const POST = async (
|
||||
input: { product_variants: input },
|
||||
})
|
||||
|
||||
const product = await refetchProduct(
|
||||
const product = await refetchEntity(
|
||||
"product",
|
||||
productId,
|
||||
req.scope,
|
||||
req.remoteQueryConfig.fields
|
||||
remapKeysForProduct(req.remoteQueryConfig.fields ?? [])
|
||||
)
|
||||
|
||||
res.status(200).json({ product: remapProductResponse(product) })
|
||||
}
|
||||
|
||||
@@ -3,24 +3,15 @@ import {
|
||||
AuthenticatedMedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "../../../../types/routing"
|
||||
import {
|
||||
AdminBatchUpdateProductType,
|
||||
AdminCreateProductType,
|
||||
} from "../validators"
|
||||
import { BatchMethodRequest } from "@medusajs/types"
|
||||
import { refetchBatchProducts, remapProductResponse } from "../helpers"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
export const POST = async (
|
||||
req: AuthenticatedMedusaRequest<
|
||||
BatchMethodRequest<AdminCreateProductType, AdminBatchUpdateProductType>
|
||||
>,
|
||||
res: MedusaResponse
|
||||
req: AuthenticatedMedusaRequest<HttpTypes.AdminBatchProductRequest>,
|
||||
res: MedusaResponse<HttpTypes.AdminBatchProductResponse>
|
||||
) => {
|
||||
// TODO: Fix types
|
||||
const input = req.validatedBody as any
|
||||
|
||||
const { result } = await batchProductsWorkflow(req.scope).run({
|
||||
input,
|
||||
input: req.validatedBody,
|
||||
})
|
||||
|
||||
const batchResults = await refetchBatchProducts(
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
MedusaContainer,
|
||||
ProductDTO,
|
||||
ProductVariantDTO,
|
||||
HttpTypes,
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
@@ -46,19 +47,24 @@ export const remapKeysForVariant = (selectFields: string[]) => {
|
||||
return [...variantFields, ...pricingFields]
|
||||
}
|
||||
|
||||
export const remapProductResponse = (product: ProductDTO) => {
|
||||
export const remapProductResponse = (
|
||||
product: ProductDTO
|
||||
): HttpTypes.AdminProduct => {
|
||||
return {
|
||||
...product,
|
||||
variants: product.variants?.map(remapVariantResponse),
|
||||
}
|
||||
// TODO: Remove any once all typings are cleaned up
|
||||
} as any
|
||||
}
|
||||
|
||||
export const remapVariantResponse = (variant: ProductVariantDTO) => {
|
||||
export const remapVariantResponse = (
|
||||
variant: ProductVariantDTO
|
||||
): HttpTypes.AdminProductVariant => {
|
||||
if (!variant) {
|
||||
return variant
|
||||
}
|
||||
|
||||
return {
|
||||
const resp = {
|
||||
...variant,
|
||||
prices: (variant as any).price_set?.prices?.map((price) => ({
|
||||
id: price.id,
|
||||
@@ -70,26 +76,11 @@ export const remapVariantResponse = (variant: ProductVariantDTO) => {
|
||||
created_at: price.created_at,
|
||||
updated_at: price.updated_at,
|
||||
})),
|
||||
price_set: undefined,
|
||||
}
|
||||
}
|
||||
|
||||
export const refetchProduct = async (
|
||||
productId: string,
|
||||
scope: MedusaContainer,
|
||||
fields: string[]
|
||||
) => {
|
||||
const remoteQuery = scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
const queryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "product",
|
||||
variables: {
|
||||
filters: { id: productId },
|
||||
},
|
||||
fields: remapKeysForProduct(fields ?? []),
|
||||
})
|
||||
|
||||
const products = await remoteQuery(queryObject)
|
||||
return products[0]
|
||||
delete (resp as any).price_set
|
||||
// TODO: Remove any once all typings are cleaned up
|
||||
return resp as any
|
||||
}
|
||||
|
||||
export const refetchVariant = async (
|
||||
|
||||
@@ -1,40 +1,25 @@
|
||||
import { createProductsWorkflow } from "@medusajs/core-flows"
|
||||
import { CreateProductDTO } from "@medusajs/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import {
|
||||
AuthenticatedMedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "../../../types/routing"
|
||||
import {
|
||||
refetchProduct,
|
||||
remapKeysForProduct,
|
||||
remapProductResponse,
|
||||
} from "./helpers"
|
||||
import {
|
||||
AdminCreateProductType,
|
||||
AdminGetProductsParamsType,
|
||||
} from "./validators"
|
||||
import { remapKeysForProduct, remapProductResponse } from "./helpers"
|
||||
import { refetchEntities, refetchEntity } from "../../utils/refetch-entity"
|
||||
|
||||
export const GET = async (
|
||||
req: AuthenticatedMedusaRequest<AdminGetProductsParamsType>,
|
||||
res: MedusaResponse
|
||||
req: AuthenticatedMedusaRequest<HttpTypes.AdminProductParams>,
|
||||
res: MedusaResponse<HttpTypes.AdminProductListResponse>
|
||||
) => {
|
||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
const selectFields = remapKeysForProduct(req.remoteQueryConfig.fields ?? [])
|
||||
|
||||
const queryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "product",
|
||||
variables: {
|
||||
filters: req.filterableFields,
|
||||
...req.remoteQueryConfig.pagination,
|
||||
},
|
||||
fields: selectFields,
|
||||
})
|
||||
|
||||
const { rows: products, metadata } = await remoteQuery(queryObject)
|
||||
const { rows: products, metadata } = await refetchEntities(
|
||||
"product",
|
||||
req.filterableFields,
|
||||
req.scope,
|
||||
selectFields,
|
||||
req.remoteQueryConfig.pagination
|
||||
)
|
||||
|
||||
res.json({
|
||||
products: products.map(remapProductResponse),
|
||||
@@ -45,19 +30,18 @@ export const GET = async (
|
||||
}
|
||||
|
||||
export const POST = async (
|
||||
req: AuthenticatedMedusaRequest<AdminCreateProductType>,
|
||||
res: MedusaResponse
|
||||
req: AuthenticatedMedusaRequest<HttpTypes.AdminCreateProduct>,
|
||||
res: MedusaResponse<HttpTypes.AdminProductResponse>
|
||||
) => {
|
||||
const input = [req.validatedBody as CreateProductDTO]
|
||||
|
||||
const { result } = await createProductsWorkflow(req.scope).run({
|
||||
input: { products: input },
|
||||
input: { products: [req.validatedBody] },
|
||||
})
|
||||
|
||||
const product = await refetchProduct(
|
||||
const product = await refetchEntity(
|
||||
"product",
|
||||
result[0].id,
|
||||
req.scope,
|
||||
req.remoteQueryConfig.fields
|
||||
remapKeysForProduct(req.remoteQueryConfig.fields ?? [])
|
||||
)
|
||||
|
||||
res.status(200).json({ product: remapProductResponse(product) })
|
||||
|
||||
@@ -4,11 +4,11 @@ import {
|
||||
} from "@medusajs/utils"
|
||||
import { NextFunction } from "express"
|
||||
import { MedusaRequest } from "../../../../types/routing"
|
||||
import { AdminGetProductsParamsType } from "../validators"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
export function maybeApplyPriceListsFilter() {
|
||||
return async (req: MedusaRequest, _, next: NextFunction) => {
|
||||
const filterableFields: AdminGetProductsParamsType = req.filterableFields
|
||||
const filterableFields: HttpTypes.AdminProductParams = req.filterableFields
|
||||
|
||||
if (!filterableFields.price_list_id) {
|
||||
return next()
|
||||
|
||||
@@ -163,13 +163,30 @@ export const AdminCreateProductVariant = z
|
||||
export type AdminUpdateProductVariantType = z.infer<
|
||||
typeof AdminUpdateProductVariant
|
||||
>
|
||||
export const AdminUpdateProductVariant = AdminCreateProductVariant.extend({
|
||||
id: z.string().optional(),
|
||||
title: z.string().optional(),
|
||||
prices: z.array(AdminUpdateVariantPrice).optional(),
|
||||
allow_backorder: z.boolean().optional(),
|
||||
manage_inventory: z.boolean().optional(),
|
||||
}).strict()
|
||||
export const AdminUpdateProductVariant = z
|
||||
.object({
|
||||
id: z.string().optional(),
|
||||
title: z.string().optional(),
|
||||
prices: z.array(AdminUpdateVariantPrice).optional(),
|
||||
sku: z.string().nullable().optional().nullable(),
|
||||
ean: z.string().nullable().optional().nullable(),
|
||||
upc: z.string().nullable().optional().nullable(),
|
||||
barcode: z.string().nullable().optional().nullable(),
|
||||
hs_code: z.string().nullable().optional().nullable(),
|
||||
mid_code: z.string().nullable().optional().nullable(),
|
||||
allow_backorder: z.boolean().optional(),
|
||||
manage_inventory: z.boolean().optional(),
|
||||
variant_rank: z.number().optional(),
|
||||
weight: z.number().nullable().optional().nullable(),
|
||||
length: z.number().nullable().optional().nullable(),
|
||||
height: z.number().nullable().optional().nullable(),
|
||||
width: z.number().nullable().optional().nullable(),
|
||||
origin_country: z.string().nullable().optional().nullable(),
|
||||
material: z.string().nullable().optional().nullable(),
|
||||
metadata: z.record(z.unknown()).optional().nullable(),
|
||||
options: z.record(z.string()).optional(),
|
||||
})
|
||||
.strict()
|
||||
|
||||
export type AdminBatchUpdateProductVariantType = z.infer<
|
||||
typeof AdminBatchUpdateProductVariant
|
||||
@@ -190,46 +207,57 @@ export const AdminCreateProduct = z
|
||||
description: z.string().nullable().optional(),
|
||||
is_giftcard: z.boolean().optional().default(false),
|
||||
discountable: z.boolean().optional().default(true),
|
||||
images: z
|
||||
.array(z.object({ url: z.string() }))
|
||||
.nullable()
|
||||
.optional(),
|
||||
thumbnail: z.string().nullable().optional(),
|
||||
images: z.array(z.object({ url: z.string() })).optional(),
|
||||
thumbnail: z.string().optional(),
|
||||
handle: z.string().optional(),
|
||||
status: statusEnum.optional().default(ProductStatus.DRAFT),
|
||||
type_id: z.string().nullable().optional(),
|
||||
collection_id: z.string().nullable().optional(),
|
||||
categories: z
|
||||
.array(AdminCreateProductProductCategory)
|
||||
.nullable()
|
||||
.optional(),
|
||||
tags: z.array(AdminUpdateProductTag).nullable().optional(),
|
||||
type_id: z.string().optional(),
|
||||
collection_id: z.string().optional(),
|
||||
categories: z.array(AdminCreateProductProductCategory).optional(),
|
||||
tags: z.array(AdminUpdateProductTag).optional(),
|
||||
options: z.array(AdminCreateProductOption).optional(),
|
||||
variants: z.array(AdminCreateProductVariant).optional(),
|
||||
sales_channels: z
|
||||
.array(z.object({ id: z.string() }))
|
||||
.nullable()
|
||||
.optional(),
|
||||
weight: z.number().nullable().optional(),
|
||||
length: z.number().nullable().optional(),
|
||||
height: z.number().nullable().optional(),
|
||||
width: z.number().nullable().optional(),
|
||||
hs_code: z.string().nullable().optional(),
|
||||
mid_code: z.string().nullable().optional(),
|
||||
origin_country: z.string().nullable().optional(),
|
||||
material: z.string().nullable().optional(),
|
||||
sales_channels: z.array(z.object({ id: z.string() })).optional(),
|
||||
weight: z.number().optional(),
|
||||
length: z.number().optional(),
|
||||
height: z.number().optional(),
|
||||
width: z.number().optional(),
|
||||
hs_code: z.string().optional(),
|
||||
mid_code: z.string().optional(),
|
||||
origin_country: z.string().optional(),
|
||||
material: z.string().optional(),
|
||||
metadata: z.record(z.unknown()).optional(),
|
||||
})
|
||||
.strict()
|
||||
|
||||
export type AdminUpdateProductType = z.infer<typeof AdminUpdateProduct>
|
||||
export const AdminUpdateProduct = AdminCreateProduct.omit({ is_giftcard: true })
|
||||
.extend({
|
||||
export const AdminUpdateProduct = z
|
||||
.object({
|
||||
title: z.string().optional(),
|
||||
discountable: z.boolean().optional(),
|
||||
is_giftcard: z.boolean().optional(),
|
||||
options: z.array(AdminUpdateProductOption).optional(),
|
||||
variants: z.array(AdminUpdateProductVariant).optional(),
|
||||
status: statusEnum.optional(),
|
||||
subtitle: z.string().optional().nullable(),
|
||||
description: z.string().optional().nullable(),
|
||||
images: z.array(z.object({ url: z.string() })).optional(),
|
||||
thumbnail: z.string().optional().nullable(),
|
||||
handle: z.string().optional(),
|
||||
type_id: z.string().optional().nullable(),
|
||||
collection_id: z.string().optional().nullable(),
|
||||
categories: z.array(AdminCreateProductProductCategory).optional(),
|
||||
tags: z.array(AdminUpdateProductTag).nullable().optional(),
|
||||
sales_channels: z.array(z.object({ id: z.string() })).optional(),
|
||||
weight: z.number().optional().nullable(),
|
||||
length: z.number().optional().nullable(),
|
||||
height: z.number().optional().nullable(),
|
||||
width: z.number().optional().nullable(),
|
||||
hs_code: z.string().optional().nullable(),
|
||||
mid_code: z.string().optional().nullable(),
|
||||
origin_country: z.string().optional().nullable(),
|
||||
material: z.string().optional().nullable(),
|
||||
metadata: z.record(z.unknown()).optional().nullable(),
|
||||
})
|
||||
.strict()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user