chore: Move several more endpoints to use zod for validation, unify APIs (#7086)
This commit is contained in:
1 parent
2a835cae13
commit
44829f296a
35 files changed
+701
-1028
No files matched your search
@@ -334,14 +334,14 @@ medusaIntegrationTestRunner({
|
|||||||
|
|
||||||
it("should delete an inventory location level and create a new one", async () => {
|
it("should delete an inventory location level and create a new one", async () => {
|
||||||
const result = await api.post(
|
const result = await api.post(
|
||||||
`/admin/inventory-items/${inventoryItem.id}/location-levels/batch/combi`,
|
`/admin/inventory-items/${inventoryItem.id}/location-levels/op/batch`,
|
||||||
{
|
{
|
||||||
creates: [
|
create: [
|
||||||
{
|
{
|
||||||
location_id: "location_2",
|
location_id: "location_2",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
deletes: [locationId],
|
delete: [locationId],
|
||||||
},
|
},
|
||||||
adminHeaders
|
adminHeaders
|
||||||
)
|
)
|
||||||
@@ -386,6 +386,7 @@ medusaIntegrationTestRunner({
|
|||||||
id: expect.any(String),
|
id: expect.any(String),
|
||||||
object: "inventory-level",
|
object: "inventory-level",
|
||||||
deleted: true,
|
deleted: true,
|
||||||
|
parent: expect.any(Object),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export const joinerConfig: ModuleJoinerConfig = {
|
|||||||
schema: moduleSchema,
|
schema: moduleSchema,
|
||||||
alias: [
|
alias: [
|
||||||
{
|
{
|
||||||
name: ["inventory_items", "inventory"],
|
name: ["inventory_items", "inventory_item", "inventory"],
|
||||||
args: {
|
args: {
|
||||||
entity: "InventoryItem",
|
entity: "InventoryItem",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
import {
|
import { AdminFulfillmentSetsDeleteResponse } from "@medusajs/types"
|
||||||
AdminFulfillmentSetsDeleteResponse,
|
|
||||||
IFulfillmentModuleService,
|
|
||||||
} from "@medusajs/types"
|
|
||||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
|
||||||
import { deleteFulfillmentSetsWorkflow } from "@medusajs/core-flows"
|
import { deleteFulfillmentSetsWorkflow } from "@medusajs/core-flows"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -16,13 +12,6 @@ export const DELETE = async (
|
|||||||
) => {
|
) => {
|
||||||
const { id } = req.params
|
const { id } = req.params
|
||||||
|
|
||||||
const fulfillmentModuleService = req.scope.resolve<IFulfillmentModuleService>(
|
|
||||||
ModuleRegistrationName.FULFILLMENT
|
|
||||||
)
|
|
||||||
|
|
||||||
// Test if exists
|
|
||||||
await fulfillmentModuleService.retrieve(id)
|
|
||||||
|
|
||||||
const { errors } = await deleteFulfillmentSetsWorkflow(req.scope).run({
|
const { errors } = await deleteFulfillmentSetsWorkflow(req.scope).run({
|
||||||
input: { ids: [id] },
|
input: { ids: [id] },
|
||||||
throwOnError: false,
|
throwOnError: false,
|
||||||
|
|||||||
@@ -1,17 +1,12 @@
|
|||||||
import { createServiceZonesWorkflow } from "@medusajs/core-flows"
|
import { createServiceZonesWorkflow } from "@medusajs/core-flows"
|
||||||
import {
|
|
||||||
ContainerRegistrationKeys,
|
|
||||||
remoteQueryObjectFromString,
|
|
||||||
} from "@medusajs/utils"
|
|
||||||
import { MedusaRequest, MedusaResponse } from "../../../../../types/routing"
|
import { MedusaRequest, MedusaResponse } from "../../../../../types/routing"
|
||||||
import { AdminCreateFulfillmentSetServiceZonesType } from "../../validators"
|
import { AdminCreateFulfillmentSetServiceZonesType } from "../../validators"
|
||||||
|
import { refetchFulfillmentSet } from "../../helpers"
|
||||||
|
|
||||||
export const POST = async (
|
export const POST = async (
|
||||||
req: MedusaRequest<AdminCreateFulfillmentSetServiceZonesType>,
|
req: MedusaRequest<AdminCreateFulfillmentSetServiceZonesType>,
|
||||||
res: MedusaResponse
|
res: MedusaResponse
|
||||||
) => {
|
) => {
|
||||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
|
||||||
|
|
||||||
const workflowInput = {
|
const workflowInput = {
|
||||||
data: [
|
data: [
|
||||||
{
|
{
|
||||||
@@ -31,15 +26,11 @@ export const POST = async (
|
|||||||
throw errors[0].error
|
throw errors[0].error
|
||||||
}
|
}
|
||||||
|
|
||||||
const [fulfillment_set] = await remoteQuery(
|
const fulfillmentSet = await refetchFulfillmentSet(
|
||||||
remoteQueryObjectFromString({
|
req.params.id,
|
||||||
entryPoint: "fulfillment_sets",
|
req.scope,
|
||||||
variables: {
|
req.remoteQueryConfig.fields
|
||||||
id: req.params.id,
|
|
||||||
},
|
|
||||||
fields: req.remoteQueryConfig.fields,
|
|
||||||
})
|
|
||||||
)
|
)
|
||||||
|
|
||||||
res.status(200).json({ fulfillment_set })
|
res.status(200).json({ fulfillment_set: fulfillmentSet })
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { MedusaContainer } from "@medusajs/types"
|
||||||
|
import {
|
||||||
|
ContainerRegistrationKeys,
|
||||||
|
remoteQueryObjectFromString,
|
||||||
|
} from "@medusajs/utils"
|
||||||
|
|
||||||
|
export const refetchFulfillmentSet = async (
|
||||||
|
fulfillmentSetId: string,
|
||||||
|
scope: MedusaContainer,
|
||||||
|
fields: string[]
|
||||||
|
) => {
|
||||||
|
const remoteQuery = scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||||
|
const queryObject = remoteQueryObjectFromString({
|
||||||
|
entryPoint: "fulfillment_set",
|
||||||
|
variables: {
|
||||||
|
filters: { id: fulfillmentSetId },
|
||||||
|
},
|
||||||
|
fields: fields,
|
||||||
|
})
|
||||||
|
|
||||||
|
const fulfillmentSets = await remoteQuery(queryObject)
|
||||||
|
return fulfillmentSets[0]
|
||||||
|
}
|
||||||
@@ -30,7 +30,12 @@ export const adminFulfillmentSetsRoutesMiddlewares: MiddlewareRoute[] = [
|
|||||||
{
|
{
|
||||||
method: ["DELETE"],
|
method: ["DELETE"],
|
||||||
matcher: "/admin/fulfillment-sets/:id/service-zones/:zone_id",
|
matcher: "/admin/fulfillment-sets/:id/service-zones/:zone_id",
|
||||||
middlewares: [],
|
middlewares: [
|
||||||
|
validateAndTransformQuery(
|
||||||
|
AdminFulfillmentSetParams,
|
||||||
|
QueryConfig.retrieveTransformQueryConfig
|
||||||
|
),
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: ["DELETE"],
|
method: ["DELETE"],
|
||||||
|
|||||||
+22
-17
@@ -5,15 +5,19 @@ import {
|
|||||||
} from "@medusajs/utils"
|
} from "@medusajs/utils"
|
||||||
import { MedusaRequest, MedusaResponse } from "../../../../../../types/routing"
|
import { MedusaRequest, MedusaResponse } from "../../../../../../types/routing"
|
||||||
|
|
||||||
import { AdminPostInventoryItemsItemLocationLevelsLevelReq } from "../../../validators"
|
import {
|
||||||
import { deleteInventoryLevelsWorkflow } from "@medusajs/core-flows"
|
deleteInventoryLevelsWorkflow,
|
||||||
import { updateInventoryLevelsWorkflow } from "@medusajs/core-flows"
|
updateInventoryLevelsWorkflow,
|
||||||
|
} from "@medusajs/core-flows"
|
||||||
|
import { refetchInventoryItem } from "../../../helpers"
|
||||||
|
import { AdminUpdateInventoryLocationLevelType } from "../../../validators"
|
||||||
|
|
||||||
export const DELETE = async (req: MedusaRequest, res: MedusaResponse) => {
|
export const DELETE = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||||
const { id, location_id } = req.params
|
const { id, location_id } = req.params
|
||||||
|
|
||||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||||
|
|
||||||
|
// TODO: We probably want to move this logic to the workflow
|
||||||
const [{ id: levelId, reserved_quantity: reservedQuantity }] =
|
const [{ id: levelId, reserved_quantity: reservedQuantity }] =
|
||||||
await remoteQuery(
|
await remoteQuery(
|
||||||
remoteQueryObjectFromString({
|
remoteQueryObjectFromString({
|
||||||
@@ -41,23 +45,28 @@ export const DELETE = async (req: MedusaRequest, res: MedusaResponse) => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const inventoryItem = await refetchInventoryItem(
|
||||||
|
id,
|
||||||
|
req.scope,
|
||||||
|
req.remoteQueryConfig.fields
|
||||||
|
)
|
||||||
|
|
||||||
res.status(200).json({
|
res.status(200).json({
|
||||||
id: levelId,
|
id: levelId,
|
||||||
object: "inventory-level",
|
object: "inventory-level",
|
||||||
deleted: true,
|
deleted: true,
|
||||||
|
parent: inventoryItem,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const POST = async (
|
export const POST = async (
|
||||||
req: MedusaRequest<AdminPostInventoryItemsItemLocationLevelsLevelReq>,
|
req: MedusaRequest<AdminUpdateInventoryLocationLevelType>,
|
||||||
res: MedusaResponse
|
res: MedusaResponse
|
||||||
) => {
|
) => {
|
||||||
const { id: inventory_item_id, location_id } = req.params
|
const { id, location_id } = req.params
|
||||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
|
||||||
|
|
||||||
const { errors } = await updateInventoryLevelsWorkflow(req.scope).run({
|
const { errors } = await updateInventoryLevelsWorkflow(req.scope).run({
|
||||||
input: {
|
input: {
|
||||||
updates: [{ inventory_item_id, location_id, ...req.validatedBody }],
|
updates: [{ ...req.validatedBody, inventory_item_id: id, location_id }],
|
||||||
},
|
},
|
||||||
throwOnError: false,
|
throwOnError: false,
|
||||||
})
|
})
|
||||||
@@ -66,17 +75,13 @@ export const POST = async (
|
|||||||
throw errors[0].error
|
throw errors[0].error
|
||||||
}
|
}
|
||||||
|
|
||||||
const [inventory_item] = await remoteQuery(
|
const inventoryItem = await refetchInventoryItem(
|
||||||
remoteQueryObjectFromString({
|
id,
|
||||||
entryPoint: "inventory",
|
req.scope,
|
||||||
variables: {
|
req.remoteQueryConfig.fields
|
||||||
id: inventory_item_id,
|
|
||||||
},
|
|
||||||
fields: req.remoteQueryConfig.fields,
|
|
||||||
})
|
|
||||||
)
|
)
|
||||||
|
|
||||||
res.status(200).json({
|
res.status(200).json({
|
||||||
inventory_item,
|
inventory_item: inventoryItem,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
-55
@@ -1,55 +0,0 @@
|
|||||||
import {
|
|
||||||
AdminPostInventoryItemsItemLocationLevelsBatchReq,
|
|
||||||
AdminPostInventoryItemsItemLocationLevelsReq,
|
|
||||||
} from "../../../../validators"
|
|
||||||
import {
|
|
||||||
ContainerRegistrationKeys,
|
|
||||||
remoteQueryObjectFromString,
|
|
||||||
} from "@medusajs/utils"
|
|
||||||
import {
|
|
||||||
MedusaRequest,
|
|
||||||
MedusaResponse,
|
|
||||||
} from "../../../../../../../types/routing"
|
|
||||||
|
|
||||||
import { bulkCreateDeleteLevelsWorkflow } from "@medusajs/core-flows"
|
|
||||||
import { defaultAdminInventoryItemFields } from "../../../../query-config"
|
|
||||||
|
|
||||||
export const POST = async (
|
|
||||||
req: MedusaRequest<AdminPostInventoryItemsItemLocationLevelsBatchReq>,
|
|
||||||
res: MedusaResponse
|
|
||||||
) => {
|
|
||||||
const { id } = req.params
|
|
||||||
|
|
||||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
|
||||||
|
|
||||||
const workflow = bulkCreateDeleteLevelsWorkflow(req.scope)
|
|
||||||
const { errors } = await workflow.run({
|
|
||||||
input: {
|
|
||||||
deletes: req.validatedBody.deletes.map((location_id) => ({
|
|
||||||
location_id,
|
|
||||||
inventory_item_id: id,
|
|
||||||
})),
|
|
||||||
creates: req.validatedBody.creates.map((c) => ({
|
|
||||||
...c,
|
|
||||||
inventory_item_id: id,
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
throwOnError: false,
|
|
||||||
})
|
|
||||||
|
|
||||||
if (Array.isArray(errors) && errors[0]) {
|
|
||||||
throw errors[0].error
|
|
||||||
}
|
|
||||||
|
|
||||||
const itemQuery = remoteQueryObjectFromString({
|
|
||||||
entryPoint: "inventory_items",
|
|
||||||
variables: {
|
|
||||||
id,
|
|
||||||
},
|
|
||||||
fields: defaultAdminInventoryItemFields,
|
|
||||||
})
|
|
||||||
|
|
||||||
const [inventory_item] = await remoteQuery(itemQuery)
|
|
||||||
|
|
||||||
res.status(200).json({ inventory_item })
|
|
||||||
}
|
|
||||||
+47
@@ -0,0 +1,47 @@
|
|||||||
|
import {
|
||||||
|
AdminCreateInventoryLocationLevelType,
|
||||||
|
AdminUpdateInventoryLocationLevelType,
|
||||||
|
} from "../../../../validators"
|
||||||
|
import {
|
||||||
|
MedusaRequest,
|
||||||
|
MedusaResponse,
|
||||||
|
} from "../../../../../../../types/routing"
|
||||||
|
|
||||||
|
import { bulkCreateDeleteLevelsWorkflow } from "@medusajs/core-flows"
|
||||||
|
import { BatchMethodRequest } from "@medusajs/types"
|
||||||
|
|
||||||
|
export const POST = async (
|
||||||
|
req: MedusaRequest<
|
||||||
|
BatchMethodRequest<
|
||||||
|
AdminCreateInventoryLocationLevelType,
|
||||||
|
AdminUpdateInventoryLocationLevelType
|
||||||
|
>
|
||||||
|
>,
|
||||||
|
res: MedusaResponse
|
||||||
|
) => {
|
||||||
|
const { id } = req.params
|
||||||
|
|
||||||
|
// TODO: Normalize workflow and response, and add support for updates
|
||||||
|
const workflow = bulkCreateDeleteLevelsWorkflow(req.scope)
|
||||||
|
const { errors } = await workflow.run({
|
||||||
|
input: {
|
||||||
|
deletes:
|
||||||
|
req.validatedBody.delete?.map((location_id) => ({
|
||||||
|
location_id,
|
||||||
|
inventory_item_id: id,
|
||||||
|
})) ?? [],
|
||||||
|
creates:
|
||||||
|
req.validatedBody.create?.map((c) => ({
|
||||||
|
...c,
|
||||||
|
inventory_item_id: id,
|
||||||
|
})) ?? [],
|
||||||
|
},
|
||||||
|
throwOnError: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (Array.isArray(errors) && errors[0]) {
|
||||||
|
throw errors[0].error
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).json({ inventory_item: {} })
|
||||||
|
}
|
||||||
@@ -4,26 +4,26 @@ import {
|
|||||||
} from "@medusajs/utils"
|
} from "@medusajs/utils"
|
||||||
import { MedusaRequest, MedusaResponse } from "../../../../../types/routing"
|
import { MedusaRequest, MedusaResponse } from "../../../../../types/routing"
|
||||||
|
|
||||||
import { AdminPostInventoryItemsItemLocationLevelsReq } from "../../validators"
|
|
||||||
import { MedusaError } from "@medusajs/utils"
|
|
||||||
import { createInventoryLevelsWorkflow } from "@medusajs/core-flows"
|
import { createInventoryLevelsWorkflow } from "@medusajs/core-flows"
|
||||||
import { defaultAdminInventoryItemFields } from "../../query-config"
|
import {
|
||||||
|
AdminCreateInventoryLocationLevelType,
|
||||||
|
AdminGetInventoryLocationLevelsParamsType,
|
||||||
|
} from "../../validators"
|
||||||
|
import { refetchInventoryItem } from "../../helpers"
|
||||||
|
|
||||||
export const POST = async (
|
export const POST = async (
|
||||||
req: MedusaRequest<AdminPostInventoryItemsItemLocationLevelsReq>,
|
req: MedusaRequest<AdminCreateInventoryLocationLevelType>,
|
||||||
res: MedusaResponse
|
res: MedusaResponse
|
||||||
) => {
|
) => {
|
||||||
const { id } = req.params
|
const { id } = req.params
|
||||||
|
|
||||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
|
||||||
|
|
||||||
const workflow = createInventoryLevelsWorkflow(req.scope)
|
const workflow = createInventoryLevelsWorkflow(req.scope)
|
||||||
const { errors } = await workflow.run({
|
const { errors } = await workflow.run({
|
||||||
input: {
|
input: {
|
||||||
inventory_levels: [
|
inventory_levels: [
|
||||||
{
|
{
|
||||||
inventory_item_id: id,
|
|
||||||
...req.validatedBody,
|
...req.validatedBody,
|
||||||
|
inventory_item_id: id,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -34,20 +34,18 @@ export const POST = async (
|
|||||||
throw errors[0].error
|
throw errors[0].error
|
||||||
}
|
}
|
||||||
|
|
||||||
const itemQuery = remoteQueryObjectFromString({
|
const inventoryItem = await refetchInventoryItem(
|
||||||
entryPoint: "inventory_items",
|
|
||||||
variables: {
|
|
||||||
id,
|
id,
|
||||||
},
|
req.scope,
|
||||||
fields: defaultAdminInventoryItemFields,
|
req.remoteQueryConfig.fields
|
||||||
})
|
)
|
||||||
|
res.status(200).json({ inventory_item: inventoryItem })
|
||||||
const [inventory_item] = await remoteQuery(itemQuery)
|
|
||||||
|
|
||||||
res.status(200).json({ inventory_item })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
export const GET = async (
|
||||||
|
req: MedusaRequest<AdminGetInventoryLocationLevelsParamsType>,
|
||||||
|
res: MedusaResponse
|
||||||
|
) => {
|
||||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||||
|
|
||||||
const query = remoteQueryObjectFromString({
|
const query = remoteQueryObjectFromString({
|
||||||
|
|||||||
@@ -1,36 +1,26 @@
|
|||||||
import {
|
import { MedusaError } from "@medusajs/utils"
|
||||||
ContainerRegistrationKeys,
|
|
||||||
MedusaError,
|
|
||||||
remoteQueryObjectFromString,
|
|
||||||
} from "@medusajs/utils"
|
|
||||||
import { MedusaRequest, MedusaResponse } from "../../../../types/routing"
|
import { MedusaRequest, MedusaResponse } from "../../../../types/routing"
|
||||||
import {
|
import {
|
||||||
deleteInventoryItemWorkflow,
|
deleteInventoryItemWorkflow,
|
||||||
updateInventoryItemsWorkflow,
|
updateInventoryItemsWorkflow,
|
||||||
} from "@medusajs/core-flows"
|
} from "@medusajs/core-flows"
|
||||||
|
import {
|
||||||
|
AdminGetInventoryItemParamsType,
|
||||||
|
AdminUpdateInventoryItemType,
|
||||||
|
} from "../validators"
|
||||||
|
import { refetchInventoryItem } from "../helpers"
|
||||||
|
|
||||||
import { AdminPostInventoryItemsInventoryItemReq } from "../validators"
|
export const GET = async (
|
||||||
|
req: MedusaRequest<AdminGetInventoryItemParamsType>,
|
||||||
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
res: MedusaResponse
|
||||||
|
) => {
|
||||||
const { id } = req.params
|
const { id } = req.params
|
||||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
const inventoryItem = await refetchInventoryItem(
|
||||||
|
id,
|
||||||
const query = remoteQueryObjectFromString({
|
req.scope,
|
||||||
entryPoint: "inventory",
|
req.remoteQueryConfig.fields
|
||||||
variables: {
|
)
|
||||||
filters: { id },
|
if (!inventoryItem) {
|
||||||
skip: 0,
|
|
||||||
take: 1,
|
|
||||||
},
|
|
||||||
|
|
||||||
fields: req.retrieveConfig.select as string[],
|
|
||||||
})
|
|
||||||
|
|
||||||
const { rows } = await remoteQuery(query)
|
|
||||||
|
|
||||||
const [inventory_item] = rows
|
|
||||||
|
|
||||||
if (!inventory_item) {
|
|
||||||
throw new MedusaError(
|
throw new MedusaError(
|
||||||
MedusaError.Types.NOT_FOUND,
|
MedusaError.Types.NOT_FOUND,
|
||||||
`Inventory item with id: ${id} was not found`
|
`Inventory item with id: ${id} was not found`
|
||||||
@@ -38,13 +28,13 @@ export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
res.status(200).json({
|
res.status(200).json({
|
||||||
inventory_item,
|
inventory_item: inventoryItem,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update inventory item
|
// Update inventory item
|
||||||
export const POST = async (
|
export const POST = async (
|
||||||
req: MedusaRequest<AdminPostInventoryItemsInventoryItemReq>,
|
req: MedusaRequest<AdminUpdateInventoryItemType>,
|
||||||
res: MedusaResponse
|
res: MedusaResponse
|
||||||
) => {
|
) => {
|
||||||
const { id } = req.params
|
const { id } = req.params
|
||||||
@@ -55,20 +45,14 @@ export const POST = async (
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
const inventoryItem = await refetchInventoryItem(
|
||||||
|
|
||||||
const [inventory_item] = await remoteQuery(
|
|
||||||
remoteQueryObjectFromString({
|
|
||||||
entryPoint: "inventory",
|
|
||||||
variables: {
|
|
||||||
id,
|
id,
|
||||||
},
|
req.scope,
|
||||||
fields: req.retrieveConfig.select as string[],
|
req.remoteQueryConfig.fields
|
||||||
})
|
|
||||||
)
|
)
|
||||||
|
|
||||||
res.status(200).json({
|
res.status(200).json({
|
||||||
inventory_item,
|
inventory_item: inventoryItem,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { MedusaContainer } from "@medusajs/types"
|
||||||
|
import {
|
||||||
|
ContainerRegistrationKeys,
|
||||||
|
remoteQueryObjectFromString,
|
||||||
|
} from "@medusajs/utils"
|
||||||
|
|
||||||
|
export const refetchInventoryItem = async (
|
||||||
|
inventoryItemId: string,
|
||||||
|
scope: MedusaContainer,
|
||||||
|
fields: string[]
|
||||||
|
) => {
|
||||||
|
const remoteQuery = scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||||
|
const queryObject = remoteQueryObjectFromString({
|
||||||
|
entryPoint: "inventory_item",
|
||||||
|
variables: {
|
||||||
|
filters: { id: inventoryItemId },
|
||||||
|
skip: 0,
|
||||||
|
take: 1,
|
||||||
|
},
|
||||||
|
fields: fields,
|
||||||
|
})
|
||||||
|
|
||||||
|
// TODO: Why does the response type change if you pass skip and take, vs not passing it?
|
||||||
|
// Also, why does the data change (in this case, not doing skip and take will not return the lazy fields of stockedQuantity and reserved_quantity)
|
||||||
|
const { rows } = await remoteQuery(queryObject)
|
||||||
|
|
||||||
|
return rows[0]
|
||||||
|
}
|
||||||
@@ -1,21 +1,19 @@
|
|||||||
import * as QueryConfig from "./query-config"
|
import * as QueryConfig from "./query-config"
|
||||||
|
|
||||||
import {
|
|
||||||
AdminGetInventoryItemsItemLocationLevelsParams,
|
|
||||||
AdminGetInventoryItemsItemParams,
|
|
||||||
AdminGetInventoryItemsParams,
|
|
||||||
AdminPostInventoryItemsInventoryItemParams,
|
|
||||||
AdminPostInventoryItemsInventoryItemReq,
|
|
||||||
AdminPostInventoryItemsItemLocationLevelsBatchReq,
|
|
||||||
AdminPostInventoryItemsItemLocationLevelsLevelParams,
|
|
||||||
AdminPostInventoryItemsItemLocationLevelsLevelReq,
|
|
||||||
AdminPostInventoryItemsItemLocationLevelsReq,
|
|
||||||
AdminPostInventoryItemsReq,
|
|
||||||
} from "./validators"
|
|
||||||
import { transformBody, transformQuery } from "../../../api/middlewares"
|
|
||||||
|
|
||||||
import { MiddlewareRoute } from "../../../types/middlewares"
|
import { MiddlewareRoute } from "../../../types/middlewares"
|
||||||
import { authenticate } from "../../../utils/authenticate-middleware"
|
import { authenticate } from "../../../utils/authenticate-middleware"
|
||||||
|
import { validateAndTransformQuery } from "../../utils/validate-query"
|
||||||
|
import {
|
||||||
|
AdminCreateInventoryItem,
|
||||||
|
AdminCreateInventoryLocationLevel,
|
||||||
|
AdminGetInventoryItemParams,
|
||||||
|
AdminGetInventoryItemsParams,
|
||||||
|
AdminGetInventoryLocationLevelParams,
|
||||||
|
AdminGetInventoryLocationLevelsParams,
|
||||||
|
AdminUpdateInventoryItem,
|
||||||
|
AdminUpdateInventoryLocationLevel,
|
||||||
|
} from "./validators"
|
||||||
|
import { validateAndTransformBody } from "../../utils/validate-body"
|
||||||
|
import { createBatchBody } from "../../utils/validators"
|
||||||
|
|
||||||
export const adminInventoryRoutesMiddlewares: MiddlewareRoute[] = [
|
export const adminInventoryRoutesMiddlewares: MiddlewareRoute[] = [
|
||||||
{
|
{
|
||||||
@@ -27,7 +25,7 @@ export const adminInventoryRoutesMiddlewares: MiddlewareRoute[] = [
|
|||||||
method: ["GET"],
|
method: ["GET"],
|
||||||
matcher: "/admin/inventory-items",
|
matcher: "/admin/inventory-items",
|
||||||
middlewares: [
|
middlewares: [
|
||||||
transformQuery(
|
validateAndTransformQuery(
|
||||||
AdminGetInventoryItemsParams,
|
AdminGetInventoryItemsParams,
|
||||||
QueryConfig.listTransformQueryConfig
|
QueryConfig.listTransformQueryConfig
|
||||||
),
|
),
|
||||||
@@ -37,8 +35,8 @@ export const adminInventoryRoutesMiddlewares: MiddlewareRoute[] = [
|
|||||||
method: ["GET"],
|
method: ["GET"],
|
||||||
matcher: "/admin/inventory-items/:id",
|
matcher: "/admin/inventory-items/:id",
|
||||||
middlewares: [
|
middlewares: [
|
||||||
transformQuery(
|
validateAndTransformQuery(
|
||||||
AdminGetInventoryItemsItemParams,
|
AdminGetInventoryItemParams,
|
||||||
QueryConfig.retrieveTransformQueryConfig
|
QueryConfig.retrieveTransformQueryConfig
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -47,47 +45,9 @@ export const adminInventoryRoutesMiddlewares: MiddlewareRoute[] = [
|
|||||||
method: ["POST"],
|
method: ["POST"],
|
||||||
matcher: "/admin/inventory-items",
|
matcher: "/admin/inventory-items",
|
||||||
middlewares: [
|
middlewares: [
|
||||||
transformBody(AdminPostInventoryItemsReq),
|
validateAndTransformBody(AdminCreateInventoryItem),
|
||||||
transformQuery(
|
validateAndTransformQuery(
|
||||||
AdminGetInventoryItemsItemParams,
|
AdminGetInventoryItemParams,
|
||||||
QueryConfig.retrieveTransformQueryConfig
|
|
||||||
),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
method: ["POST"],
|
|
||||||
matcher: "/admin/inventory-items/:id/location-levels/batch/combi",
|
|
||||||
middlewares: [
|
|
||||||
transformBody(AdminPostInventoryItemsItemLocationLevelsBatchReq),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
method: ["GET"],
|
|
||||||
matcher: "/admin/inventory-items/:id/location-levels",
|
|
||||||
middlewares: [
|
|
||||||
transformQuery(
|
|
||||||
AdminGetInventoryItemsItemLocationLevelsParams,
|
|
||||||
QueryConfig.listLocationLevelsTransformQueryConfig
|
|
||||||
),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
method: ["POST"],
|
|
||||||
matcher: "/admin/inventory-items/:id/location-levels",
|
|
||||||
middlewares: [transformBody(AdminPostInventoryItemsItemLocationLevelsReq)],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
method: ["POST"],
|
|
||||||
matcher: "/admin/inventory-items/:id/location-levels",
|
|
||||||
middlewares: [transformBody(AdminPostInventoryItemsItemLocationLevelsReq)],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
method: ["POST"],
|
|
||||||
matcher: "/admin/inventory-items/:id/location-levels/:location_id",
|
|
||||||
middlewares: [
|
|
||||||
transformBody(AdminPostInventoryItemsItemLocationLevelsLevelReq),
|
|
||||||
transformQuery(
|
|
||||||
AdminPostInventoryItemsItemLocationLevelsLevelParams,
|
|
||||||
QueryConfig.retrieveTransformQueryConfig
|
QueryConfig.retrieveTransformQueryConfig
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -96,11 +56,69 @@ export const adminInventoryRoutesMiddlewares: MiddlewareRoute[] = [
|
|||||||
method: ["POST"],
|
method: ["POST"],
|
||||||
matcher: "/admin/inventory-items/:id",
|
matcher: "/admin/inventory-items/:id",
|
||||||
middlewares: [
|
middlewares: [
|
||||||
transformBody(AdminPostInventoryItemsInventoryItemReq),
|
validateAndTransformBody(AdminUpdateInventoryItem),
|
||||||
transformQuery(
|
validateAndTransformQuery(
|
||||||
AdminPostInventoryItemsInventoryItemParams,
|
AdminGetInventoryItemParams,
|
||||||
QueryConfig.retrieveTransformQueryConfig
|
QueryConfig.retrieveTransformQueryConfig
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
method: ["GET"],
|
||||||
|
matcher: "/admin/inventory-items/:id/location-levels",
|
||||||
|
middlewares: [
|
||||||
|
validateAndTransformQuery(
|
||||||
|
AdminGetInventoryLocationLevelsParams,
|
||||||
|
QueryConfig.listLocationLevelsTransformQueryConfig
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: ["POST"],
|
||||||
|
matcher: "/admin/inventory-items/:id/location-levels",
|
||||||
|
middlewares: [
|
||||||
|
validateAndTransformBody(AdminCreateInventoryLocationLevel),
|
||||||
|
validateAndTransformQuery(
|
||||||
|
AdminGetInventoryItemParams,
|
||||||
|
QueryConfig.retrieveTransformQueryConfig
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: ["DELETE"],
|
||||||
|
matcher: "/admin/inventory-items/:id/location-levels/:location_id",
|
||||||
|
middlewares: [
|
||||||
|
validateAndTransformQuery(
|
||||||
|
AdminGetInventoryItemParams,
|
||||||
|
QueryConfig.retrieveTransformQueryConfig
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: ["POST"],
|
||||||
|
matcher: "/admin/inventory-items/:id/location-levels/:location_id",
|
||||||
|
middlewares: [
|
||||||
|
validateAndTransformBody(AdminUpdateInventoryLocationLevel),
|
||||||
|
validateAndTransformQuery(
|
||||||
|
AdminGetInventoryItemParams,
|
||||||
|
QueryConfig.retrieveTransformQueryConfig
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: ["POST"],
|
||||||
|
matcher: "/admin/inventory-items/:id/location-levels/op/batch",
|
||||||
|
middlewares: [
|
||||||
|
validateAndTransformBody(
|
||||||
|
createBatchBody(
|
||||||
|
AdminCreateInventoryLocationLevel,
|
||||||
|
AdminUpdateInventoryLocationLevel
|
||||||
|
)
|
||||||
|
),
|
||||||
|
validateAndTransformQuery(
|
||||||
|
AdminGetInventoryLocationLevelParams,
|
||||||
|
QueryConfig.retrieveLocationLevelsTransformQueryConfig
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
]
|
]
|
||||||
@@ -1,6 +1,3 @@
|
|||||||
import { InventoryNext } from "@medusajs/types"
|
|
||||||
import { defaultAdminProductsVariantFields } from "../products/query-config"
|
|
||||||
|
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
export const defaultAdminLocationLevelFields = [
|
export const defaultAdminLocationLevelFields = [
|
||||||
"id",
|
"id",
|
||||||
@@ -35,12 +32,7 @@ export const defaultAdminInventoryItemFields = [
|
|||||||
"stocked_quantity",
|
"stocked_quantity",
|
||||||
"created_at",
|
"created_at",
|
||||||
"updated_at",
|
"updated_at",
|
||||||
...defaultAdminLocationLevelFields.map(
|
"*location_levels",
|
||||||
(field) => `location_levels.${field.toString()}`
|
|
||||||
),
|
|
||||||
...defaultAdminProductsVariantFields
|
|
||||||
.filter((field) => !field.startsWith("*"))
|
|
||||||
.map((field) => `variant.${field}`),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
export const retrieveTransformQueryConfig = {
|
export const retrieveTransformQueryConfig = {
|
||||||
|
|||||||
@@ -7,36 +7,32 @@ import {
|
|||||||
remoteQueryObjectFromString,
|
remoteQueryObjectFromString,
|
||||||
} from "@medusajs/utils"
|
} from "@medusajs/utils"
|
||||||
|
|
||||||
import { AdminPostInventoryItemsReq } from "./validators"
|
|
||||||
import { createInventoryItemsWorkflow } from "@medusajs/core-flows"
|
import { createInventoryItemsWorkflow } from "@medusajs/core-flows"
|
||||||
|
import {
|
||||||
|
AdminCreateInventoryItemType,
|
||||||
|
AdminGetInventoryItemsParamsType,
|
||||||
|
} from "./validators"
|
||||||
|
import { refetchInventoryItem } from "./helpers"
|
||||||
|
|
||||||
// Create inventory-item
|
|
||||||
export const POST = async (
|
export const POST = async (
|
||||||
req: AuthenticatedMedusaRequest<AdminPostInventoryItemsReq>,
|
req: AuthenticatedMedusaRequest<AdminCreateInventoryItemType>,
|
||||||
res: MedusaResponse
|
res: MedusaResponse
|
||||||
) => {
|
) => {
|
||||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
|
||||||
|
|
||||||
const { result } = await createInventoryItemsWorkflow(req.scope).run({
|
const { result } = await createInventoryItemsWorkflow(req.scope).run({
|
||||||
input: { items: [req.validatedBody] },
|
input: { items: [req.validatedBody] },
|
||||||
})
|
})
|
||||||
|
|
||||||
const [inventory_item] = await remoteQuery(
|
const inventoryItem = await refetchInventoryItem(
|
||||||
remoteQueryObjectFromString({
|
result[0].id,
|
||||||
entryPoint: "inventory_items",
|
req.scope,
|
||||||
variables: {
|
req.remoteQueryConfig.fields
|
||||||
id: result[0].id,
|
|
||||||
},
|
|
||||||
fields: req.remoteQueryConfig.fields,
|
|
||||||
})
|
|
||||||
)
|
)
|
||||||
|
|
||||||
res.status(200).json({ inventory_item })
|
res.status(200).json({ inventory_item: inventoryItem })
|
||||||
}
|
}
|
||||||
|
|
||||||
// List inventory-items
|
|
||||||
export const GET = async (
|
export const GET = async (
|
||||||
req: AuthenticatedMedusaRequest,
|
req: AuthenticatedMedusaRequest<AdminGetInventoryItemsParamsType>,
|
||||||
res: MedusaResponse
|
res: MedusaResponse
|
||||||
) => {
|
) => {
|
||||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||||
|
|||||||
@@ -1,408 +1,129 @@
|
|||||||
|
import { z } from "zod"
|
||||||
import {
|
import {
|
||||||
DateComparisonOperator,
|
createFindParams,
|
||||||
FindParams,
|
createOperatorMap,
|
||||||
NumericalComparisonOperator,
|
createSelectParams,
|
||||||
StringComparisonOperator,
|
} from "../../utils/validators"
|
||||||
extendedFindParamsMixin,
|
import { optionalBooleanMapper } from "../../../utils/validators/is-boolean"
|
||||||
} from "../../../types/common"
|
|
||||||
import {
|
|
||||||
IsBoolean,
|
|
||||||
IsEmail,
|
|
||||||
IsNotEmpty,
|
|
||||||
IsNumber,
|
|
||||||
IsObject,
|
|
||||||
IsOptional,
|
|
||||||
IsString,
|
|
||||||
Min,
|
|
||||||
ValidateNested,
|
|
||||||
} from "class-validator"
|
|
||||||
import { Transform, Type } from "class-transformer"
|
|
||||||
|
|
||||||
import { IsType } from "../../../utils"
|
export type AdminGetInventoryItemParamsType = z.infer<
|
||||||
|
typeof AdminGetInventoryItemParams
|
||||||
|
>
|
||||||
|
export const AdminGetInventoryItemParams = createSelectParams()
|
||||||
|
|
||||||
export class AdminGetInventoryItemsItemParams extends FindParams {}
|
export type AdminGetInventoryItemsParamsType = z.infer<
|
||||||
|
typeof AdminGetInventoryItemsParams
|
||||||
/**
|
>
|
||||||
* Parameters used to filter and configure the pagination of the retrieved inventory items.
|
export const AdminGetInventoryItemsParams = createFindParams({
|
||||||
*/
|
|
||||||
export class AdminGetInventoryItemsParams extends extendedFindParamsMixin({
|
|
||||||
limit: 20,
|
limit: 20,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
}) {
|
}).merge(
|
||||||
/**
|
z.object({
|
||||||
* IDs to filter inventory items by.
|
q: z.string().optional(),
|
||||||
*/
|
id: z.union([z.string(), z.array(z.string())]).optional(),
|
||||||
@IsOptional()
|
location_id: z.union([z.string(), z.array(z.string())]).optional(),
|
||||||
@IsType([String, [String]])
|
sku: z.union([z.string(), z.array(z.string())]).optional(),
|
||||||
id?: string | string[]
|
origin_country: z.union([z.string(), z.array(z.string())]).optional(),
|
||||||
|
mid_code: z.union([z.string(), z.array(z.string())]).optional(),
|
||||||
|
hs_code: z.union([z.string(), z.array(z.string())]).optional(),
|
||||||
|
material: z.union([z.string(), z.array(z.string())]).optional(),
|
||||||
|
requires_shipping: z
|
||||||
|
.preprocess(
|
||||||
|
(val: any) => optionalBooleanMapper.get(val?.toLowerCase()),
|
||||||
|
z.boolean().optional()
|
||||||
|
)
|
||||||
|
.optional(),
|
||||||
|
weight: createOperatorMap(z.number(), parseFloat).optional(),
|
||||||
|
length: createOperatorMap(z.number(), parseFloat).optional(),
|
||||||
|
height: createOperatorMap(z.number(), parseFloat).optional(),
|
||||||
|
width: createOperatorMap(z.number(), parseFloat).optional(),
|
||||||
|
$and: z.lazy(() => AdminGetInventoryItemsParams.array()).optional(),
|
||||||
|
$or: z.lazy(() => AdminGetInventoryItemsParams.array()).optional(),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
export type AdminGetInventoryLocationLevelParamsType = z.infer<
|
||||||
* Search terms to search inventory items' sku, title, and description.
|
typeof AdminGetInventoryLocationLevelParams
|
||||||
*/
|
>
|
||||||
@IsOptional()
|
export const AdminGetInventoryLocationLevelParams = createSelectParams()
|
||||||
@IsString()
|
|
||||||
q?: string
|
|
||||||
|
|
||||||
/**
|
export type AdminGetInventoryLocationLevelsParamsType = z.infer<
|
||||||
* Location IDs to filter inventory items by.
|
typeof AdminGetInventoryLocationLevelsParams
|
||||||
*/
|
>
|
||||||
@IsOptional()
|
export const AdminGetInventoryLocationLevelsParams = createFindParams({
|
||||||
@IsType([String, [String]])
|
|
||||||
location_id?: string | string[]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SKUs to filter inventory items by.
|
|
||||||
*/
|
|
||||||
@IsOptional()
|
|
||||||
@IsType([String, [String]])
|
|
||||||
sku?: string | string[]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Origin countries to filter inventory items by.
|
|
||||||
*/
|
|
||||||
@IsOptional()
|
|
||||||
@IsType([String, [String]])
|
|
||||||
origin_country?: string | string[]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MID codes to filter inventory items by.
|
|
||||||
*/
|
|
||||||
@IsOptional()
|
|
||||||
@IsType([String, [String]])
|
|
||||||
mid_code?: string | string[]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Materials to filter inventory items by.
|
|
||||||
*/
|
|
||||||
@IsOptional()
|
|
||||||
@IsType([String, [String]])
|
|
||||||
material?: string | string[]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* String filters to apply to inventory items' `hs_code` field.
|
|
||||||
*/
|
|
||||||
@IsOptional()
|
|
||||||
@IsType([String, [String], StringComparisonOperator])
|
|
||||||
hs_code?: string | string[] | StringComparisonOperator
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Number filters to apply to inventory items' `weight` field.
|
|
||||||
*/
|
|
||||||
@IsOptional()
|
|
||||||
@IsType([Number, NumericalComparisonOperator])
|
|
||||||
weight?: number | NumericalComparisonOperator
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Number filters to apply to inventory items' `length` field.
|
|
||||||
*/
|
|
||||||
@IsOptional()
|
|
||||||
@IsType([Number, NumericalComparisonOperator])
|
|
||||||
length?: number | NumericalComparisonOperator
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Number filters to apply to inventory items' `height` field.
|
|
||||||
*/
|
|
||||||
@IsOptional()
|
|
||||||
@IsType([Number, NumericalComparisonOperator])
|
|
||||||
height?: number | NumericalComparisonOperator
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Number filters to apply to inventory items' `width` field.
|
|
||||||
*/
|
|
||||||
@IsOptional()
|
|
||||||
@IsType([Number, NumericalComparisonOperator])
|
|
||||||
width?: number | NumericalComparisonOperator
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filter inventory items by whether they require shipping.
|
|
||||||
*/
|
|
||||||
@IsBoolean()
|
|
||||||
@IsOptional()
|
|
||||||
@Transform(({ value }) => value === "true")
|
|
||||||
requires_shipping?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export class AdminPostInventoryItemsItemLocationLevelsReq {
|
|
||||||
@IsString()
|
|
||||||
location_id: string
|
|
||||||
|
|
||||||
@IsNumber()
|
|
||||||
@IsOptional()
|
|
||||||
stocked_quantity?: number
|
|
||||||
|
|
||||||
@IsOptional()
|
|
||||||
@IsNumber()
|
|
||||||
incoming_quantity?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export class AdminPostInventoryItemsItemLocationLevelsBatchReq {
|
|
||||||
@ValidateNested({ each: true })
|
|
||||||
@Type(() => AdminPostInventoryItemsItemLocationLevelsReq)
|
|
||||||
creates: AdminPostInventoryItemsItemLocationLevelsReq[]
|
|
||||||
|
|
||||||
@IsString({ each: true })
|
|
||||||
deletes: string[]
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line
|
|
||||||
export class AdminPostInventoryItemsItemLocationLevelsParams extends FindParams {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @schema AdminPostInventoryItemsReq
|
|
||||||
* type: object
|
|
||||||
* description: "The details of the inventory item to create."
|
|
||||||
* properties:
|
|
||||||
* sku:
|
|
||||||
* description: The unique SKU of the associated Product Variant.
|
|
||||||
* type: string
|
|
||||||
* ean:
|
|
||||||
* description: The EAN number of the item.
|
|
||||||
* type: string
|
|
||||||
* upc:
|
|
||||||
* description: The UPC number of the item.
|
|
||||||
* type: string
|
|
||||||
* barcode:
|
|
||||||
* description: A generic GTIN field for the Product Variant.
|
|
||||||
* type: string
|
|
||||||
* hs_code:
|
|
||||||
* description: The Harmonized System code of the Inventory Item. May be used by Fulfillment Providers to pass customs information to shipping carriers.
|
|
||||||
* type: string
|
|
||||||
* inventory_quantity:
|
|
||||||
* description: The amount of stock kept of the associated Product Variant.
|
|
||||||
* type: integer
|
|
||||||
* default: 0
|
|
||||||
* allow_backorder:
|
|
||||||
* description: Whether the associated Product Variant can be purchased when out of stock.
|
|
||||||
* type: boolean
|
|
||||||
* manage_inventory:
|
|
||||||
* description: Whether Medusa should keep track of the inventory for the associated Product Variant.
|
|
||||||
* type: boolean
|
|
||||||
* default: true
|
|
||||||
* weight:
|
|
||||||
* description: The weight of the Inventory Item. May be used in shipping rate calculations.
|
|
||||||
* type: number
|
|
||||||
* length:
|
|
||||||
* description: The length of the Inventory Item. May be used in shipping rate calculations.
|
|
||||||
* type: number
|
|
||||||
* height:
|
|
||||||
* description: The height of the Inventory Item. May be used in shipping rate calculations.
|
|
||||||
* type: number
|
|
||||||
* width:
|
|
||||||
* description: The width of the Inventory Item. May be used in shipping rate calculations.
|
|
||||||
* type: number
|
|
||||||
* origin_country:
|
|
||||||
* description: The country in which the Inventory Item was produced. May be used by Fulfillment Providers to pass customs information to shipping carriers.
|
|
||||||
* type: string
|
|
||||||
* mid_code:
|
|
||||||
* description: The Manufacturers Identification code that identifies the manufacturer of the Inventory Item. May be used by Fulfillment Providers to pass customs information to shipping carriers.
|
|
||||||
* type: string
|
|
||||||
* material:
|
|
||||||
* description: The material and composition that the Inventory Item is made of, May be used by Fulfillment Providers to pass customs information to shipping carriers.
|
|
||||||
* type: string
|
|
||||||
* title:
|
|
||||||
* description: The inventory item's title.
|
|
||||||
* type: string
|
|
||||||
* description:
|
|
||||||
* description: The inventory item's description.
|
|
||||||
* type: string
|
|
||||||
* thumbnail:
|
|
||||||
* description: The inventory item's thumbnail.
|
|
||||||
* type: string
|
|
||||||
* metadata:
|
|
||||||
* description: An optional set of key-value pairs with additional information.
|
|
||||||
* type: object
|
|
||||||
* externalDocs:
|
|
||||||
* description: "Learn about the metadata attribute, and how to delete and update it."
|
|
||||||
* url: "https://docs.medusajs.com/development/entities/overview#metadata-attribute"
|
|
||||||
*/
|
|
||||||
export class AdminPostInventoryItemsReq {
|
|
||||||
@IsString()
|
|
||||||
@IsOptional()
|
|
||||||
sku?: string
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@IsOptional()
|
|
||||||
hs_code?: string
|
|
||||||
|
|
||||||
@IsNumber()
|
|
||||||
@IsOptional()
|
|
||||||
weight?: number
|
|
||||||
|
|
||||||
@IsNumber()
|
|
||||||
@IsOptional()
|
|
||||||
length?: number
|
|
||||||
|
|
||||||
@IsNumber()
|
|
||||||
@IsOptional()
|
|
||||||
height?: number
|
|
||||||
|
|
||||||
@IsNumber()
|
|
||||||
@IsOptional()
|
|
||||||
width?: number
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@IsOptional()
|
|
||||||
origin_country?: string
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@IsOptional()
|
|
||||||
mid_code?: string
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@IsOptional()
|
|
||||||
material?: string
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@IsOptional()
|
|
||||||
title?: string
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@IsOptional()
|
|
||||||
description?: string
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@IsOptional()
|
|
||||||
thumbnail?: string
|
|
||||||
|
|
||||||
@IsObject()
|
|
||||||
@IsOptional()
|
|
||||||
metadata?: Record<string, unknown>
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line max-len
|
|
||||||
export class AdminGetInventoryItemsItemLocationLevelsParams extends extendedFindParamsMixin(
|
|
||||||
{
|
|
||||||
limit: 50,
|
limit: 50,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
}
|
}).merge(
|
||||||
) {
|
z.object({
|
||||||
/**
|
location_id: z.union([z.string(), z.array(z.string())]).optional(),
|
||||||
* Location IDs to filter location levels.
|
$and: z
|
||||||
*/
|
.lazy(() => AdminGetInventoryLocationLevelsParams.array())
|
||||||
@IsOptional()
|
.optional(),
|
||||||
@IsString({ each: true })
|
$or: z.lazy(() => AdminGetInventoryLocationLevelsParams.array()).optional(),
|
||||||
location_id?: string[]
|
})
|
||||||
}
|
)
|
||||||
/**
|
|
||||||
* @schema AdminPostInventoryItemsItemLocationLevelsLevelReq
|
|
||||||
* type: object
|
|
||||||
* properties:
|
|
||||||
* stocked_quantity:
|
|
||||||
* description: the total stock quantity of an inventory item at the given location ID
|
|
||||||
* type: number
|
|
||||||
* incoming_quantity:
|
|
||||||
* description: the incoming stock quantity of an inventory item at the given location ID
|
|
||||||
* type: number
|
|
||||||
*/
|
|
||||||
export class AdminPostInventoryItemsItemLocationLevelsLevelReq {
|
|
||||||
@IsOptional()
|
|
||||||
@IsNumber()
|
|
||||||
@Min(0)
|
|
||||||
incoming_quantity?: number
|
|
||||||
|
|
||||||
@IsOptional()
|
export type AdminCreateInventoryLocationLevelType = z.infer<
|
||||||
@IsNumber()
|
typeof AdminCreateInventoryLocationLevel
|
||||||
@Min(0)
|
>
|
||||||
stocked_quantity?: number
|
export const AdminCreateInventoryLocationLevel = z
|
||||||
}
|
.object({
|
||||||
|
location_id: z.string(),
|
||||||
|
stocked_quantity: z.number().min(0).optional(),
|
||||||
|
incoming_quantity: z.number().min(0).optional(),
|
||||||
|
})
|
||||||
|
.strict()
|
||||||
|
|
||||||
// eslint-disable-next-line
|
export type AdminUpdateInventoryLocationLevelType = z.infer<
|
||||||
export class AdminPostInventoryItemsItemLocationLevelsLevelParams extends FindParams {}
|
typeof AdminUpdateInventoryLocationLevel
|
||||||
/**
|
>
|
||||||
* @schema AdminPostInventoryItemsInventoryItemReq
|
export const AdminUpdateInventoryLocationLevel = z
|
||||||
* type: object
|
.object({
|
||||||
* description: "The attributes to update in an inventory item."
|
stocked_quantity: z.number().min(0).optional(),
|
||||||
* properties:
|
incoming_quantity: z.number().min(0).optional(),
|
||||||
* hs_code:
|
})
|
||||||
* description: The Harmonized System code of the Inventory Item. May be used by Fulfillment Providers to pass customs information to shipping carriers.
|
.strict()
|
||||||
* type: string
|
|
||||||
* origin_country:
|
|
||||||
* description: The country in which the Inventory Item was produced. May be used by Fulfillment Providers to pass customs information to shipping carriers.
|
|
||||||
* type: string
|
|
||||||
* mid_code:
|
|
||||||
* description: The Manufacturers Identification code that identifies the manufacturer of the Inventory Item. May be used by Fulfillment Providers to pass customs information to shipping carriers.
|
|
||||||
* type: string
|
|
||||||
* material:
|
|
||||||
* description: The material and composition that the Inventory Item is made of, May be used by Fulfillment Providers to pass customs information to shipping carriers.
|
|
||||||
* type: string
|
|
||||||
* weight:
|
|
||||||
* description: The weight of the Inventory Item. May be used in shipping rate calculations.
|
|
||||||
* type: number
|
|
||||||
* height:
|
|
||||||
* description: The height of the Inventory Item. May be used in shipping rate calculations.
|
|
||||||
* type: number
|
|
||||||
* width:
|
|
||||||
* description: The width of the Inventory Item. May be used in shipping rate calculations.
|
|
||||||
* type: number
|
|
||||||
* length:
|
|
||||||
* description: The length of the Inventory Item. May be used in shipping rate calculations.
|
|
||||||
* type: number
|
|
||||||
* title:
|
|
||||||
* description: The inventory item's title.
|
|
||||||
* type: string
|
|
||||||
* description:
|
|
||||||
* description: The inventory item's description.
|
|
||||||
* type: string
|
|
||||||
* thumbnail:
|
|
||||||
* description: The inventory item's thumbnail.
|
|
||||||
* type: string
|
|
||||||
* requires_shipping:
|
|
||||||
* description: Whether the item requires shipping.
|
|
||||||
* type: boolean
|
|
||||||
*/
|
|
||||||
|
|
||||||
export class AdminPostInventoryItemsInventoryItemReq {
|
export type AdminCreateInventoryItemType = z.infer<
|
||||||
@IsString()
|
typeof AdminCreateInventoryItem
|
||||||
@IsOptional()
|
>
|
||||||
sku?: string
|
export const AdminCreateInventoryItem = z
|
||||||
|
.object({
|
||||||
|
sku: z.string().optional(),
|
||||||
|
hs_code: z.string().optional(),
|
||||||
|
weight: z.number().optional(),
|
||||||
|
length: z.number().optional(),
|
||||||
|
height: z.number().optional(),
|
||||||
|
width: z.number().optional(),
|
||||||
|
origin_country: z.string().optional(),
|
||||||
|
mid_code: z.string().optional(),
|
||||||
|
material: z.string().optional(),
|
||||||
|
title: z.string().optional(),
|
||||||
|
description: z.string().optional(),
|
||||||
|
requires_shipping: z.boolean().optional(),
|
||||||
|
thumbnail: z.string().optional(),
|
||||||
|
metadata: z.record(z.string(), z.unknown()).optional(),
|
||||||
|
})
|
||||||
|
.strict()
|
||||||
|
|
||||||
@IsOptional()
|
export type AdminUpdateInventoryItemType = z.infer<
|
||||||
@IsString()
|
typeof AdminUpdateInventoryItem
|
||||||
origin_country?: string
|
>
|
||||||
|
export const AdminUpdateInventoryItem = z
|
||||||
@IsOptional()
|
.object({
|
||||||
@IsString()
|
sku: z.string().optional(),
|
||||||
hs_code?: string
|
hs_code: z.string().optional(),
|
||||||
|
weight: z.number().optional(),
|
||||||
@IsOptional()
|
length: z.number().optional(),
|
||||||
@IsString()
|
height: z.number().optional(),
|
||||||
mid_code?: string
|
width: z.number().optional(),
|
||||||
|
origin_country: z.string().optional(),
|
||||||
@IsOptional()
|
mid_code: z.string().optional(),
|
||||||
@IsString()
|
material: z.string().optional(),
|
||||||
material?: string
|
title: z.string().optional(),
|
||||||
|
description: z.string().optional(),
|
||||||
@IsOptional()
|
requires_shipping: z.boolean().optional(),
|
||||||
@IsNumber()
|
thumbnail: z.string().optional(),
|
||||||
weight?: number
|
metadata: z.record(z.string(), z.unknown()).optional(),
|
||||||
|
})
|
||||||
@IsOptional()
|
.strict()
|
||||||
@IsNumber()
|
|
||||||
height?: number
|
|
||||||
|
|
||||||
@IsOptional()
|
|
||||||
@IsNumber()
|
|
||||||
length?: number
|
|
||||||
|
|
||||||
@IsOptional()
|
|
||||||
@IsNumber()
|
|
||||||
width?: number
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@IsOptional()
|
|
||||||
title?: string
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@IsOptional()
|
|
||||||
description?: string
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@IsOptional()
|
|
||||||
thumbnail?: string
|
|
||||||
|
|
||||||
@IsBoolean()
|
|
||||||
@IsOptional()
|
|
||||||
requires_shipping?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export class AdminPostInventoryItemsInventoryItemParams extends FindParams {}
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { MedusaRequest, MedusaResponse } from "../../../../../types/routing"
|
import { MedusaRequest, MedusaResponse } from "../../../../../types/routing"
|
||||||
|
|
||||||
import { refreshInviteTokensWorkflow } from "@medusajs/core-flows"
|
import { refreshInviteTokensWorkflow } from "@medusajs/core-flows"
|
||||||
|
import { refetchInvite } from "../../helpers"
|
||||||
|
|
||||||
export const POST = async (req: MedusaRequest, res: MedusaResponse) => {
|
export const POST = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||||
const workflow = refreshInviteTokensWorkflow(req.scope)
|
const workflow = refreshInviteTokensWorkflow(req.scope)
|
||||||
@@ -9,7 +10,12 @@ export const POST = async (req: MedusaRequest, res: MedusaResponse) => {
|
|||||||
invite_ids: [req.params.id],
|
invite_ids: [req.params.id],
|
||||||
}
|
}
|
||||||
|
|
||||||
const { result: invites } = await workflow.run({ input })
|
const { result } = await workflow.run({ input })
|
||||||
|
const invite = await refetchInvite(
|
||||||
|
result[0].id,
|
||||||
|
req.scope,
|
||||||
|
req.remoteQueryConfig.fields
|
||||||
|
)
|
||||||
|
|
||||||
res.status(200).json({ invite: invites[0] })
|
res.status(200).json({ invite })
|
||||||
}
|
}
|
||||||
@@ -2,31 +2,21 @@ import {
|
|||||||
AuthenticatedMedusaRequest,
|
AuthenticatedMedusaRequest,
|
||||||
MedusaResponse,
|
MedusaResponse,
|
||||||
} from "../../../../types/routing"
|
} from "../../../../types/routing"
|
||||||
import {
|
import { MedusaError } from "@medusajs/utils"
|
||||||
ContainerRegistrationKeys,
|
|
||||||
MedusaError,
|
|
||||||
remoteQueryObjectFromString,
|
|
||||||
} from "@medusajs/utils"
|
|
||||||
|
|
||||||
import { deleteInvitesWorkflow } from "@medusajs/core-flows"
|
import { deleteInvitesWorkflow } from "@medusajs/core-flows"
|
||||||
|
import { refetchInvite } from "../helpers"
|
||||||
|
|
||||||
// Get invite
|
|
||||||
export const GET = async (
|
export const GET = async (
|
||||||
req: AuthenticatedMedusaRequest,
|
req: AuthenticatedMedusaRequest,
|
||||||
res: MedusaResponse
|
res: MedusaResponse
|
||||||
) => {
|
) => {
|
||||||
const { id } = req.params
|
const { id } = req.params
|
||||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
const invite = await refetchInvite(
|
||||||
|
|
||||||
const query = remoteQueryObjectFromString({
|
|
||||||
entryPoint: "invite",
|
|
||||||
variables: {
|
|
||||||
id,
|
id,
|
||||||
},
|
req.scope,
|
||||||
fields: req.retrieveConfig.select as string[],
|
req.remoteQueryConfig.fields
|
||||||
})
|
)
|
||||||
|
|
||||||
const [invite] = await remoteQuery(query)
|
|
||||||
|
|
||||||
if (!invite) {
|
if (!invite) {
|
||||||
throw new MedusaError(
|
throw new MedusaError(
|
||||||
@@ -38,7 +28,6 @@ export const GET = async (
|
|||||||
res.status(200).json({ invite })
|
res.status(200).json({ invite })
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete invite
|
|
||||||
export const DELETE = async (
|
export const DELETE = async (
|
||||||
req: AuthenticatedMedusaRequest,
|
req: AuthenticatedMedusaRequest,
|
||||||
res: MedusaResponse
|
res: MedusaResponse
|
||||||
|
|||||||
@@ -5,11 +5,10 @@ import {
|
|||||||
AuthenticatedMedusaRequest,
|
AuthenticatedMedusaRequest,
|
||||||
MedusaResponse,
|
MedusaResponse,
|
||||||
} from "../../../../types/routing"
|
} from "../../../../types/routing"
|
||||||
|
import { AdminInviteAcceptType } from "../validators"
|
||||||
import { AdminPostInvitesInviteAcceptReq } from "../validators"
|
|
||||||
|
|
||||||
export const POST = async (
|
export const POST = async (
|
||||||
req: AuthenticatedMedusaRequest<AdminPostInvitesInviteAcceptReq>,
|
req: AuthenticatedMedusaRequest<AdminInviteAcceptType>,
|
||||||
res: MedusaResponse
|
res: MedusaResponse
|
||||||
) => {
|
) => {
|
||||||
if (req.auth.actor_id) {
|
if (req.auth.actor_id) {
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { MedusaContainer } from "@medusajs/types"
|
||||||
|
import {
|
||||||
|
ContainerRegistrationKeys,
|
||||||
|
remoteQueryObjectFromString,
|
||||||
|
} from "@medusajs/utils"
|
||||||
|
|
||||||
|
export const refetchInvite = async (
|
||||||
|
inviteId: string,
|
||||||
|
scope: MedusaContainer,
|
||||||
|
fields: string[]
|
||||||
|
) => {
|
||||||
|
const remoteQuery = scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||||
|
const queryObject = remoteQueryObjectFromString({
|
||||||
|
entryPoint: "invite",
|
||||||
|
variables: {
|
||||||
|
filters: { id: inviteId },
|
||||||
|
},
|
||||||
|
fields: fields,
|
||||||
|
})
|
||||||
|
|
||||||
|
const invites = await remoteQuery(queryObject)
|
||||||
|
return invites[0]
|
||||||
|
}
|
||||||
@@ -1,42 +1,25 @@
|
|||||||
import * as QueryConfig from "./query-config"
|
import * as QueryConfig from "./query-config"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
AdminCreateInviteRequest,
|
AdminCreateInvite,
|
||||||
AdminGetInvitesInviteParams,
|
AdminGetInviteAcceptParams,
|
||||||
|
AdminGetInviteParams,
|
||||||
AdminGetInvitesParams,
|
AdminGetInvitesParams,
|
||||||
AdminPostInvitesInviteAcceptParams,
|
AdminInviteAccept,
|
||||||
AdminPostInvitesInviteAcceptReq,
|
|
||||||
} from "./validators"
|
} from "./validators"
|
||||||
import { transformBody, transformQuery } from "../../../api/middlewares"
|
|
||||||
|
|
||||||
import { MiddlewareRoute } from "../../../types/middlewares"
|
import { MiddlewareRoute } from "../../../types/middlewares"
|
||||||
import { authenticate } from "../../../utils/authenticate-middleware"
|
import { authenticate } from "../../../utils/authenticate-middleware"
|
||||||
|
import { validateAndTransformQuery } from "../../utils/validate-query"
|
||||||
|
import { validateAndTransformBody } from "../../utils/validate-body"
|
||||||
|
|
||||||
export const adminInviteRoutesMiddlewares: MiddlewareRoute[] = [
|
export const adminInviteRoutesMiddlewares: MiddlewareRoute[] = [
|
||||||
{
|
|
||||||
method: "ALL",
|
|
||||||
matcher: "/admin/invites",
|
|
||||||
middlewares: [authenticate("admin", ["session", "bearer"])],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
method: "POST",
|
|
||||||
matcher: "/admin/invites/accept",
|
|
||||||
middlewares: [
|
|
||||||
authenticate("admin", ["session", "bearer"], {
|
|
||||||
allowUnregistered: true,
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
method: ["GET", "DELETE"],
|
|
||||||
matcher: "/admin/invites/:id",
|
|
||||||
middlewares: [authenticate("admin", ["session", "bearer"])],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
method: ["GET"],
|
method: ["GET"],
|
||||||
matcher: "/admin/invites",
|
matcher: "/admin/invites",
|
||||||
middlewares: [
|
middlewares: [
|
||||||
transformQuery(
|
authenticate("admin", ["session", "bearer", "api-key"]),
|
||||||
|
validateAndTransformQuery(
|
||||||
AdminGetInvitesParams,
|
AdminGetInvitesParams,
|
||||||
QueryConfig.listTransformQueryConfig
|
QueryConfig.listTransformQueryConfig
|
||||||
),
|
),
|
||||||
@@ -45,22 +28,52 @@ export const adminInviteRoutesMiddlewares: MiddlewareRoute[] = [
|
|||||||
{
|
{
|
||||||
method: ["POST"],
|
method: ["POST"],
|
||||||
matcher: "/admin/invites",
|
matcher: "/admin/invites",
|
||||||
middlewares: [transformBody(AdminCreateInviteRequest)],
|
middlewares: [
|
||||||
|
authenticate("admin", ["session", "bearer", "api-key"]),
|
||||||
|
validateAndTransformBody(AdminCreateInvite),
|
||||||
|
validateAndTransformQuery(
|
||||||
|
AdminGetInviteParams,
|
||||||
|
QueryConfig.retrieveTransformQueryConfig
|
||||||
|
),
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
matcher: "/admin/invites/accept",
|
matcher: "/admin/invites/accept",
|
||||||
middlewares: [
|
middlewares: [
|
||||||
transformBody(AdminPostInvitesInviteAcceptReq),
|
authenticate("admin", ["session", "bearer"], {
|
||||||
transformQuery(AdminPostInvitesInviteAcceptParams),
|
allowUnregistered: true,
|
||||||
|
}),
|
||||||
|
validateAndTransformBody(AdminInviteAccept),
|
||||||
|
validateAndTransformQuery(
|
||||||
|
AdminGetInviteAcceptParams,
|
||||||
|
QueryConfig.retrieveTransformQueryConfig
|
||||||
|
),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: ["GET"],
|
method: ["GET"],
|
||||||
matcher: "/admin/invites/:id",
|
matcher: "/admin/invites/:id",
|
||||||
middlewares: [
|
middlewares: [
|
||||||
transformQuery(
|
authenticate("admin", ["session", "bearer", "api-key"]),
|
||||||
AdminGetInvitesInviteParams,
|
validateAndTransformQuery(
|
||||||
|
AdminGetInviteParams,
|
||||||
|
QueryConfig.retrieveTransformQueryConfig
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: ["DELETE"],
|
||||||
|
matcher: "/admin/invites/:id",
|
||||||
|
middlewares: [authenticate("admin", ["session", "bearer", "api-key"])],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
matcher: "/admin/invites/:id/resend",
|
||||||
|
middlewares: [
|
||||||
|
authenticate("admin", ["session", "bearer", "api-key"]),
|
||||||
|
validateAndTransformQuery(
|
||||||
|
AdminGetInviteParams,
|
||||||
QueryConfig.retrieveTransformQueryConfig
|
QueryConfig.retrieveTransformQueryConfig
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
export const defaultAdminInviteRelations = []
|
|
||||||
export const allowedAdminInviteRelations = []
|
|
||||||
export const defaultAdminInviteFields = [
|
export const defaultAdminInviteFields = [
|
||||||
"id",
|
"id",
|
||||||
"email",
|
"email",
|
||||||
@@ -13,9 +11,7 @@ export const defaultAdminInviteFields = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
export const retrieveTransformQueryConfig = {
|
export const retrieveTransformQueryConfig = {
|
||||||
defaultFields: defaultAdminInviteFields,
|
defaults: defaultAdminInviteFields,
|
||||||
defaultRelations: defaultAdminInviteRelations,
|
|
||||||
allowedRelations: allowedAdminInviteRelations,
|
|
||||||
isList: false,
|
isList: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,32 +7,27 @@ import {
|
|||||||
remoteQueryObjectFromString,
|
remoteQueryObjectFromString,
|
||||||
} from "@medusajs/utils"
|
} from "@medusajs/utils"
|
||||||
|
|
||||||
import { CreateInviteDTO } from "@medusajs/types"
|
|
||||||
import { createInvitesWorkflow } from "@medusajs/core-flows"
|
import { createInvitesWorkflow } from "@medusajs/core-flows"
|
||||||
|
import { AdminCreateInviteType, AdminGetInvitesParamsType } from "./validators"
|
||||||
|
import { refetchInvite } from "./helpers"
|
||||||
|
|
||||||
// List invites
|
|
||||||
export const GET = async (
|
export const GET = async (
|
||||||
req: AuthenticatedMedusaRequest,
|
req: AuthenticatedMedusaRequest<AdminGetInvitesParamsType>,
|
||||||
res: MedusaResponse
|
res: MedusaResponse
|
||||||
) => {
|
) => {
|
||||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||||
|
const queryObject = remoteQueryObjectFromString({
|
||||||
const query = remoteQueryObjectFromString({
|
|
||||||
entryPoint: "invite",
|
entryPoint: "invite",
|
||||||
variables: {
|
variables: {
|
||||||
filters: req.filterableFields,
|
filters: req.filterableFields,
|
||||||
order: req.listConfig.order,
|
...req.remoteQueryConfig.pagination,
|
||||||
skip: req.listConfig.skip,
|
|
||||||
take: req.listConfig.take,
|
|
||||||
},
|
},
|
||||||
fields: req.listConfig.select as string[],
|
fields: req.remoteQueryConfig.fields,
|
||||||
})
|
})
|
||||||
|
|
||||||
const { rows: invites, metadata } = await remoteQuery({
|
const { rows: invites, metadata } = await remoteQuery(queryObject)
|
||||||
...query,
|
|
||||||
})
|
|
||||||
|
|
||||||
res.status(200).json({
|
res.json({
|
||||||
invites,
|
invites,
|
||||||
count: metadata.count,
|
count: metadata.count,
|
||||||
offset: metadata.skip,
|
offset: metadata.skip,
|
||||||
@@ -40,9 +35,8 @@ export const GET = async (
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create invite
|
|
||||||
export const POST = async (
|
export const POST = async (
|
||||||
req: AuthenticatedMedusaRequest<CreateInviteDTO>,
|
req: AuthenticatedMedusaRequest<AdminCreateInviteType>,
|
||||||
res: MedusaResponse
|
res: MedusaResponse
|
||||||
) => {
|
) => {
|
||||||
const workflow = createInvitesWorkflow(req.scope)
|
const workflow = createInvitesWorkflow(req.scope)
|
||||||
@@ -54,7 +48,11 @@ export const POST = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { result } = await workflow.run(input)
|
const { result } = await workflow.run(input)
|
||||||
|
const invite = await refetchInvite(
|
||||||
|
result[0].id,
|
||||||
|
req.scope,
|
||||||
|
req.remoteQueryConfig.fields
|
||||||
|
)
|
||||||
|
|
||||||
const [invite] = result
|
|
||||||
res.status(200).json({ invite })
|
res.status(200).json({ invite })
|
||||||
}
|
}
|
||||||
@@ -1,146 +1,51 @@
|
|||||||
import { Type } from "class-transformer"
|
import { z } from "zod"
|
||||||
import {
|
import {
|
||||||
IsEmail,
|
createFindParams,
|
||||||
IsNotEmpty,
|
createOperatorMap,
|
||||||
IsOptional,
|
createSelectParams,
|
||||||
IsString,
|
} from "../../utils/validators"
|
||||||
ValidateNested,
|
|
||||||
} from "class-validator"
|
|
||||||
import {
|
|
||||||
DateComparisonOperator,
|
|
||||||
FindParams,
|
|
||||||
extendedFindParamsMixin,
|
|
||||||
} from "../../../types/common"
|
|
||||||
import { IsType } from "../../../utils"
|
|
||||||
|
|
||||||
export class AdminGetInvitesInviteParams extends FindParams {}
|
export type AdminGetInviteParamsType = z.infer<typeof AdminGetInviteParams>
|
||||||
|
export const AdminGetInviteParams = createSelectParams()
|
||||||
|
|
||||||
export class AdminGetInvitesParams extends extendedFindParamsMixin({
|
export type AdminGetInvitesParamsType = z.infer<typeof AdminGetInvitesParams>
|
||||||
|
export const AdminGetInvitesParams = createFindParams({
|
||||||
limit: 50,
|
limit: 50,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
}) {
|
}).merge(
|
||||||
/**
|
z.object({
|
||||||
* IDs to filter invites by.
|
q: z.string().optional(),
|
||||||
*/
|
id: z.union([z.string(), z.array(z.string())]).optional(),
|
||||||
@IsOptional()
|
email: z.union([z.string(), z.array(z.string())]).optional(),
|
||||||
@IsType([String, [String]])
|
created_at: createOperatorMap().optional(),
|
||||||
id?: string | string[]
|
updated_at: createOperatorMap().optional(),
|
||||||
|
deleted_at: createOperatorMap().optional(),
|
||||||
|
$and: z.lazy(() => AdminGetInvitesParams.array()).optional(),
|
||||||
|
$or: z.lazy(() => AdminGetInvitesParams.array()).optional(),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
export type AdminGetInviteAcceptParamsType = z.infer<
|
||||||
* The field to sort the data by. By default, the sort order is ascending. To change the order to descending, prefix the field name with `-`.
|
typeof AdminGetInviteAcceptParams
|
||||||
*/
|
>
|
||||||
@IsString()
|
export const AdminGetInviteAcceptParams = createSelectParams().merge(
|
||||||
@IsOptional()
|
z.object({
|
||||||
order?: string
|
token: z.string(),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
export type AdminCreateInviteType = z.infer<typeof AdminCreateInvite>
|
||||||
* Date filters to apply on the invites' `update_at` date.
|
export const AdminCreateInvite = z
|
||||||
*/
|
.object({
|
||||||
@IsOptional()
|
email: z.string(),
|
||||||
@ValidateNested()
|
})
|
||||||
@Type(() => DateComparisonOperator)
|
.strict()
|
||||||
updated_at?: DateComparisonOperator
|
|
||||||
|
|
||||||
/**
|
export type AdminInviteAcceptType = z.infer<typeof AdminInviteAccept>
|
||||||
* Date filters to apply on the customer invites' `created_at` date.
|
export const AdminInviteAccept = z
|
||||||
*/
|
.object({
|
||||||
@IsOptional()
|
email: z.string().optional(),
|
||||||
@ValidateNested()
|
first_name: z.string().optional(),
|
||||||
@Type(() => DateComparisonOperator)
|
last_name: z.string().optional(),
|
||||||
created_at?: DateComparisonOperator
|
})
|
||||||
|
.strict()
|
||||||
/**
|
|
||||||
* Date filters to apply on the invites' `deleted_at` date.
|
|
||||||
*/
|
|
||||||
@IsOptional()
|
|
||||||
@ValidateNested()
|
|
||||||
@Type(() => DateComparisonOperator)
|
|
||||||
deleted_at?: DateComparisonOperator
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filter to apply on the invites' `email` field.
|
|
||||||
*/
|
|
||||||
@IsOptional()
|
|
||||||
@IsString()
|
|
||||||
email?: string
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Comma-separated fields that should be included in the returned invites.
|
|
||||||
*/
|
|
||||||
@IsOptional()
|
|
||||||
@IsString()
|
|
||||||
fields?: string
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The term to search invites emails.
|
|
||||||
*/
|
|
||||||
@IsString()
|
|
||||||
@IsOptional()
|
|
||||||
q?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export class AdminCreateInviteRequest {
|
|
||||||
@IsEmail()
|
|
||||||
email: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @schema AdminPostInvitesInviteAcceptReq
|
|
||||||
* type: object
|
|
||||||
* description: "The details of the invite to be accepted."
|
|
||||||
* required:
|
|
||||||
* - token
|
|
||||||
* - user
|
|
||||||
* properties:
|
|
||||||
* token:
|
|
||||||
* description: "The token of the invite to accept. This is a unique token generated when the invite was created or resent."
|
|
||||||
* type: string
|
|
||||||
* user:
|
|
||||||
* description: "The details of the user to create."
|
|
||||||
* type: object
|
|
||||||
* required:
|
|
||||||
* - first_name
|
|
||||||
* - last_name
|
|
||||||
* - password
|
|
||||||
* properties:
|
|
||||||
* first_name:
|
|
||||||
* type: string
|
|
||||||
* description: the first name of the User
|
|
||||||
* last_name:
|
|
||||||
* type: string
|
|
||||||
* description: the last name of the User
|
|
||||||
* password:
|
|
||||||
* description: The password for the User
|
|
||||||
* type: string
|
|
||||||
* format: password
|
|
||||||
*/
|
|
||||||
export class AdminPostInvitesInviteAcceptReq {
|
|
||||||
/**
|
|
||||||
* If email is not passed, we default to using the email of the invite.
|
|
||||||
*/
|
|
||||||
@IsString()
|
|
||||||
@IsOptional()
|
|
||||||
email: string
|
|
||||||
/**
|
|
||||||
* The invite's first name.
|
|
||||||
*/
|
|
||||||
@IsString()
|
|
||||||
@IsOptional()
|
|
||||||
first_name: string
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The invite's last name.
|
|
||||||
*/
|
|
||||||
@IsString()
|
|
||||||
@IsOptional()
|
|
||||||
last_name: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export class AdminPostInvitesInviteAcceptParams {
|
|
||||||
@IsString()
|
|
||||||
@IsNotEmpty()
|
|
||||||
token: string
|
|
||||||
|
|
||||||
@IsOptional()
|
|
||||||
expand = undefined
|
|
||||||
}
|
|
||||||
@@ -1,21 +1,15 @@
|
|||||||
import { capturePaymentWorkflow } from "@medusajs/core-flows"
|
import { capturePaymentWorkflow } from "@medusajs/core-flows"
|
||||||
import {
|
|
||||||
ContainerRegistrationKeys,
|
|
||||||
remoteQueryObjectFromString,
|
|
||||||
} from "@medusajs/utils"
|
|
||||||
import {
|
import {
|
||||||
AuthenticatedMedusaRequest,
|
AuthenticatedMedusaRequest,
|
||||||
MedusaResponse,
|
MedusaResponse,
|
||||||
} from "../../../../../types/routing"
|
} from "../../../../../types/routing"
|
||||||
import { defaultAdminPaymentFields } from "../../query-config"
|
import { refetchPayment } from "../../helpers"
|
||||||
import { AdminPostPaymentsCapturesReq } from "../../validators"
|
import { AdminCreatePaymentCaptureType } from "../../validators"
|
||||||
|
|
||||||
export const POST = async (
|
export const POST = async (
|
||||||
req: AuthenticatedMedusaRequest<AdminPostPaymentsCapturesReq>,
|
req: AuthenticatedMedusaRequest<AdminCreatePaymentCaptureType>,
|
||||||
res: MedusaResponse
|
res: MedusaResponse
|
||||||
) => {
|
) => {
|
||||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
|
||||||
|
|
||||||
const { id } = req.params
|
const { id } = req.params
|
||||||
|
|
||||||
const { errors } = await capturePaymentWorkflow(req.scope).run({
|
const { errors } = await capturePaymentWorkflow(req.scope).run({
|
||||||
@@ -31,13 +25,11 @@ export const POST = async (
|
|||||||
throw errors[0].error
|
throw errors[0].error
|
||||||
}
|
}
|
||||||
|
|
||||||
const query = remoteQueryObjectFromString({
|
const payment = await refetchPayment(
|
||||||
entryPoint: "payments",
|
id,
|
||||||
variables: { id },
|
req.scope,
|
||||||
fields: defaultAdminPaymentFields,
|
req.remoteQueryConfig.fields
|
||||||
})
|
)
|
||||||
|
|
||||||
const [payment] = await remoteQuery(query)
|
|
||||||
|
|
||||||
res.status(200).json({ payment })
|
res.status(200).json({ payment })
|
||||||
}
|
}
|
||||||
@@ -1,23 +1,16 @@
|
|||||||
import { refundPaymentWorkflow } from "@medusajs/core-flows"
|
import { refundPaymentWorkflow } from "@medusajs/core-flows"
|
||||||
import {
|
|
||||||
ContainerRegistrationKeys,
|
|
||||||
remoteQueryObjectFromString,
|
|
||||||
} from "@medusajs/utils"
|
|
||||||
import {
|
import {
|
||||||
AuthenticatedMedusaRequest,
|
AuthenticatedMedusaRequest,
|
||||||
MedusaResponse,
|
MedusaResponse,
|
||||||
} from "../../../../../types/routing"
|
} from "../../../../../types/routing"
|
||||||
import { defaultAdminPaymentFields } from "../../query-config"
|
import { refetchPayment } from "../../helpers"
|
||||||
import { AdminPostPaymentsRefundsReq } from "../../validators"
|
import { AdminCreatePaymentRefundType } from "../../validators"
|
||||||
|
|
||||||
export const POST = async (
|
export const POST = async (
|
||||||
req: AuthenticatedMedusaRequest<AdminPostPaymentsRefundsReq>,
|
req: AuthenticatedMedusaRequest<AdminCreatePaymentRefundType>,
|
||||||
res: MedusaResponse
|
res: MedusaResponse
|
||||||
) => {
|
) => {
|
||||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
|
||||||
|
|
||||||
const { id } = req.params
|
const { id } = req.params
|
||||||
|
|
||||||
const { errors } = await refundPaymentWorkflow(req.scope).run({
|
const { errors } = await refundPaymentWorkflow(req.scope).run({
|
||||||
input: {
|
input: {
|
||||||
payment_id: id,
|
payment_id: id,
|
||||||
@@ -31,13 +24,11 @@ export const POST = async (
|
|||||||
throw errors[0].error
|
throw errors[0].error
|
||||||
}
|
}
|
||||||
|
|
||||||
const query = remoteQueryObjectFromString({
|
const payment = await refetchPayment(
|
||||||
entryPoint: "payments",
|
id,
|
||||||
variables: { id },
|
req.scope,
|
||||||
fields: defaultAdminPaymentFields,
|
req.remoteQueryConfig.fields
|
||||||
})
|
)
|
||||||
|
|
||||||
const [payment] = await remoteQuery(query)
|
|
||||||
|
|
||||||
res.status(200).json({ payment })
|
res.status(200).json({ payment })
|
||||||
}
|
}
|
||||||
@@ -1,28 +1,19 @@
|
|||||||
import { Modules } from "@medusajs/modules-sdk"
|
|
||||||
import {
|
|
||||||
ContainerRegistrationKeys,
|
|
||||||
remoteQueryObjectFromString,
|
|
||||||
} from "@medusajs/utils"
|
|
||||||
import {
|
import {
|
||||||
AuthenticatedMedusaRequest,
|
AuthenticatedMedusaRequest,
|
||||||
MedusaResponse,
|
MedusaResponse,
|
||||||
} from "../../../../types/routing"
|
} from "../../../../types/routing"
|
||||||
|
import { AdminGetPaymentParamsType } from "../validators"
|
||||||
|
import { refetchPayment } from "../helpers"
|
||||||
|
|
||||||
export const GET = async (
|
export const GET = async (
|
||||||
req: AuthenticatedMedusaRequest,
|
req: AuthenticatedMedusaRequest<AdminGetPaymentParamsType>,
|
||||||
res: MedusaResponse
|
res: MedusaResponse
|
||||||
) => {
|
) => {
|
||||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
const payment = await refetchPayment(
|
||||||
|
req.params.id,
|
||||||
const { id } = req.params
|
req.scope,
|
||||||
|
req.remoteQueryConfig.fields
|
||||||
const query = remoteQueryObjectFromString({
|
)
|
||||||
entryPoint: Modules.PAYMENT,
|
|
||||||
variables: { id },
|
|
||||||
fields: req.retrieveConfig.select as string[],
|
|
||||||
})
|
|
||||||
|
|
||||||
const [payment] = await remoteQuery(query)
|
|
||||||
|
|
||||||
res.status(200).json({ payment })
|
res.status(200).json({ payment })
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { MedusaContainer } from "@medusajs/types"
|
||||||
|
import {
|
||||||
|
ContainerRegistrationKeys,
|
||||||
|
remoteQueryObjectFromString,
|
||||||
|
} from "@medusajs/utils"
|
||||||
|
|
||||||
|
export const refetchPayment = async (
|
||||||
|
paymentId: string,
|
||||||
|
scope: MedusaContainer,
|
||||||
|
fields: string[]
|
||||||
|
) => {
|
||||||
|
const remoteQuery = scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||||
|
const queryObject = remoteQueryObjectFromString({
|
||||||
|
entryPoint: "payment",
|
||||||
|
variables: {
|
||||||
|
filters: { id: paymentId },
|
||||||
|
},
|
||||||
|
fields: fields,
|
||||||
|
})
|
||||||
|
|
||||||
|
const payments = await remoteQuery(queryObject)
|
||||||
|
return payments[0]
|
||||||
|
}
|
||||||
@@ -1,25 +1,28 @@
|
|||||||
import { transformBody, transformQuery } from "../../../api/middlewares"
|
|
||||||
import { MiddlewareRoute } from "../../../types/middlewares"
|
import { MiddlewareRoute } from "../../../types/middlewares"
|
||||||
import { authenticate } from "../../../utils/authenticate-middleware"
|
import { authenticate } from "../../../utils/authenticate-middleware"
|
||||||
|
import { unlessPath } from "../../utils/unless-path"
|
||||||
|
import { validateAndTransformBody } from "../../utils/validate-body"
|
||||||
|
import { validateAndTransformQuery } from "../../utils/validate-query"
|
||||||
import * as queryConfig from "./query-config"
|
import * as queryConfig from "./query-config"
|
||||||
import {
|
import {
|
||||||
|
AdminCreatePaymentCapture,
|
||||||
|
AdminCreatePaymentRefund,
|
||||||
|
AdminGetPaymentParams,
|
||||||
|
AdminGetPaymentProvidersParams,
|
||||||
AdminGetPaymentsParams,
|
AdminGetPaymentsParams,
|
||||||
AdminGetPaymentsPaymentProvidersParams,
|
|
||||||
AdminPostPaymentsCapturesReq,
|
|
||||||
AdminPostPaymentsRefundsReq,
|
|
||||||
} from "./validators"
|
} from "./validators"
|
||||||
|
|
||||||
export const adminPaymentRoutesMiddlewares: MiddlewareRoute[] = [
|
export const adminPaymentRoutesMiddlewares: MiddlewareRoute[] = [
|
||||||
{
|
{
|
||||||
method: "ALL",
|
method: "ALL",
|
||||||
matcher: "/admin/payments",
|
matcher: "/admin/payments",
|
||||||
middlewares: [authenticate("admin", ["session", "bearer"])],
|
middlewares: [authenticate("admin", ["session", "bearer", "api-key"])],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: ["GET"],
|
method: ["GET"],
|
||||||
matcher: "/admin/payments",
|
matcher: "/admin/payments",
|
||||||
middlewares: [
|
middlewares: [
|
||||||
transformQuery(
|
validateAndTransformQuery(
|
||||||
AdminGetPaymentsParams,
|
AdminGetPaymentsParams,
|
||||||
queryConfig.listTransformQueryConfig
|
queryConfig.listTransformQueryConfig
|
||||||
),
|
),
|
||||||
@@ -29,8 +32,8 @@ export const adminPaymentRoutesMiddlewares: MiddlewareRoute[] = [
|
|||||||
method: ["GET"],
|
method: ["GET"],
|
||||||
matcher: "/admin/payments/payment-providers",
|
matcher: "/admin/payments/payment-providers",
|
||||||
middlewares: [
|
middlewares: [
|
||||||
transformQuery(
|
validateAndTransformQuery(
|
||||||
AdminGetPaymentsPaymentProvidersParams,
|
AdminGetPaymentProvidersParams,
|
||||||
queryConfig.listTransformPaymentProvidersQueryConfig
|
queryConfig.listTransformPaymentProvidersQueryConfig
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -39,20 +42,35 @@ export const adminPaymentRoutesMiddlewares: MiddlewareRoute[] = [
|
|||||||
method: ["GET"],
|
method: ["GET"],
|
||||||
matcher: "/admin/payments/:id",
|
matcher: "/admin/payments/:id",
|
||||||
middlewares: [
|
middlewares: [
|
||||||
transformQuery(
|
unlessPath(
|
||||||
AdminGetPaymentsParams,
|
new RegExp("/admin/payments/payment-providers"),
|
||||||
|
validateAndTransformQuery(
|
||||||
|
AdminGetPaymentParams,
|
||||||
queryConfig.retrieveTransformQueryConfig
|
queryConfig.retrieveTransformQueryConfig
|
||||||
|
)
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: ["POST"],
|
method: ["POST"],
|
||||||
matcher: "/admin/payments/:id/capture",
|
matcher: "/admin/payments/:id/capture",
|
||||||
middlewares: [transformBody(AdminPostPaymentsCapturesReq)],
|
middlewares: [
|
||||||
|
validateAndTransformBody(AdminCreatePaymentCapture),
|
||||||
|
validateAndTransformQuery(
|
||||||
|
AdminGetPaymentParams,
|
||||||
|
queryConfig.retrieveTransformQueryConfig
|
||||||
|
),
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: ["POST"],
|
method: ["POST"],
|
||||||
matcher: "/admin/payments/:id/refund",
|
matcher: "/admin/payments/:id/refund",
|
||||||
middlewares: [transformBody(AdminPostPaymentsRefundsReq)],
|
middlewares: [
|
||||||
|
validateAndTransformBody(AdminCreatePaymentRefund),
|
||||||
|
validateAndTransformQuery(
|
||||||
|
AdminGetPaymentParams,
|
||||||
|
queryConfig.retrieveTransformQueryConfig
|
||||||
|
),
|
||||||
|
],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@@ -1,30 +1,33 @@
|
|||||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
|
||||||
|
|
||||||
import { IPaymentModuleService } from "@medusajs/types"
|
|
||||||
import {
|
import {
|
||||||
AuthenticatedMedusaRequest,
|
AuthenticatedMedusaRequest,
|
||||||
MedusaResponse,
|
MedusaResponse,
|
||||||
} from "../../../../types/routing"
|
} from "../../../../types/routing"
|
||||||
import { AdminGetPaymentsPaymentProvidersParams } from "../validators"
|
import { AdminGetPaymentProvidersParamsType } from "../validators"
|
||||||
|
import {
|
||||||
|
ContainerRegistrationKeys,
|
||||||
|
remoteQueryObjectFromString,
|
||||||
|
} from "@medusajs/utils"
|
||||||
|
|
||||||
export const GET = async (
|
export const GET = async (
|
||||||
req: AuthenticatedMedusaRequest<AdminGetPaymentsPaymentProvidersParams>,
|
req: AuthenticatedMedusaRequest<AdminGetPaymentProvidersParamsType>,
|
||||||
res: MedusaResponse
|
res: MedusaResponse
|
||||||
) => {
|
) => {
|
||||||
const paymentModule = req.scope.resolve<IPaymentModuleService>(
|
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||||
ModuleRegistrationName.PAYMENT
|
const queryObject = remoteQueryObjectFromString({
|
||||||
)
|
entryPoint: "payment_provider",
|
||||||
|
variables: {
|
||||||
const [payment_providers, count] =
|
filters: req.filterableFields,
|
||||||
await paymentModule.listAndCountPaymentProviders(req.filterableFields, {
|
...req.remoteQueryConfig.pagination,
|
||||||
skip: req.listConfig.skip,
|
},
|
||||||
take: req.listConfig.take,
|
fields: req.remoteQueryConfig.fields,
|
||||||
})
|
})
|
||||||
|
|
||||||
res.status(200).json({
|
const { rows: payment_providers, metadata } = await remoteQuery(queryObject)
|
||||||
count,
|
|
||||||
|
res.json({
|
||||||
payment_providers,
|
payment_providers,
|
||||||
offset: req.listConfig.skip,
|
count: metadata.count,
|
||||||
limit: req.listConfig.take,
|
offset: metadata.skip,
|
||||||
|
limit: metadata.take,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -11,29 +11,19 @@ export const defaultAdminPaymentFields = [
|
|||||||
"refunds.amount",
|
"refunds.amount",
|
||||||
]
|
]
|
||||||
|
|
||||||
export const defaultAdminPaymentRelations = ["captures", "refunds"]
|
|
||||||
|
|
||||||
export const allowedAdminPaymentRelations = ["captures", "refunds"]
|
|
||||||
|
|
||||||
export const listTransformQueryConfig = {
|
export const listTransformQueryConfig = {
|
||||||
defaultFields: defaultAdminPaymentFields,
|
defaults: defaultAdminPaymentFields,
|
||||||
defaultRelations: defaultAdminPaymentRelations,
|
|
||||||
allowedRelations: allowedAdminPaymentRelations,
|
|
||||||
isList: true,
|
isList: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const retrieveTransformQueryConfig = {
|
export const retrieveTransformQueryConfig = {
|
||||||
defaultFields: defaultAdminPaymentFields,
|
defaults: defaultAdminPaymentFields,
|
||||||
defaultRelations: defaultAdminPaymentRelations,
|
|
||||||
allowedRelations: allowedAdminPaymentRelations,
|
|
||||||
isList: false,
|
isList: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const defaultAdminPaymentPaymentProviderFields = ["id", "is_enabled"]
|
export const defaultAdminPaymentPaymentProviderFields = ["id", "is_enabled"]
|
||||||
|
|
||||||
export const listTransformPaymentProvidersQueryConfig = {
|
export const listTransformPaymentProvidersQueryConfig = {
|
||||||
defaultFields: defaultAdminPaymentPaymentProviderFields,
|
defaults: defaultAdminPaymentPaymentProviderFields,
|
||||||
defaultRelations: [],
|
|
||||||
allowedRelations: [],
|
|
||||||
isList: true,
|
isList: true,
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import { Modules } from "@medusajs/modules-sdk"
|
|
||||||
import {
|
import {
|
||||||
ContainerRegistrationKeys,
|
ContainerRegistrationKeys,
|
||||||
remoteQueryObjectFromString,
|
remoteQueryObjectFromString,
|
||||||
@@ -7,27 +6,25 @@ import {
|
|||||||
AuthenticatedMedusaRequest,
|
AuthenticatedMedusaRequest,
|
||||||
MedusaResponse,
|
MedusaResponse,
|
||||||
} from "../../../types/routing"
|
} from "../../../types/routing"
|
||||||
|
import { AdminGetPaymentsParamsType } from "./validators"
|
||||||
|
|
||||||
export const GET = async (
|
export const GET = async (
|
||||||
req: AuthenticatedMedusaRequest,
|
req: AuthenticatedMedusaRequest<AdminGetPaymentsParamsType>,
|
||||||
res: MedusaResponse
|
res: MedusaResponse
|
||||||
) => {
|
) => {
|
||||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||||
|
const queryObject = remoteQueryObjectFromString({
|
||||||
const query = remoteQueryObjectFromString({
|
entryPoint: "payment",
|
||||||
entryPoint: Modules.PAYMENT,
|
|
||||||
variables: {
|
variables: {
|
||||||
filters: req.filterableFields,
|
filters: req.filterableFields,
|
||||||
order: req.listConfig.order,
|
...req.remoteQueryConfig.pagination,
|
||||||
skip: req.listConfig.skip,
|
|
||||||
take: req.listConfig.take,
|
|
||||||
},
|
},
|
||||||
fields: req.listConfig.select as string[],
|
fields: req.remoteQueryConfig.fields,
|
||||||
})
|
})
|
||||||
|
|
||||||
const { rows: payments, metadata } = await remoteQuery(query)
|
const { rows: payments, metadata } = await remoteQuery(queryObject)
|
||||||
|
|
||||||
res.status(200).json({
|
res.json({
|
||||||
payments,
|
payments,
|
||||||
count: metadata.count,
|
count: metadata.count,
|
||||||
offset: metadata.skip,
|
offset: metadata.skip,
|
||||||
|
|||||||
@@ -1,79 +1,57 @@
|
|||||||
import { Type } from "class-transformer"
|
import { z } from "zod"
|
||||||
import { IsBoolean, IsInt, IsOptional, ValidateNested } from "class-validator"
|
|
||||||
import {
|
import {
|
||||||
DateComparisonOperator,
|
createFindParams,
|
||||||
FindParams,
|
createOperatorMap,
|
||||||
extendedFindParamsMixin,
|
createSelectParams,
|
||||||
} from "../../../types/common"
|
} from "../../utils/validators"
|
||||||
import { IsType } from "../../../utils"
|
|
||||||
|
|
||||||
export class AdminGetPaymentsPaymentParams extends FindParams {}
|
export type AdminGetPaymentParamsType = z.infer<typeof AdminGetPaymentParams>
|
||||||
|
export const AdminGetPaymentParams = createSelectParams()
|
||||||
|
|
||||||
export class AdminGetPaymentsParams extends extendedFindParamsMixin({
|
export type AdminGetPaymentsParamsType = z.infer<typeof AdminGetPaymentsParams>
|
||||||
|
export const AdminGetPaymentsParams = createFindParams({
|
||||||
limit: 20,
|
limit: 20,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
}) {
|
}).merge(
|
||||||
/**
|
z.object({
|
||||||
* IDs to filter users by.
|
id: z.union([z.string(), z.array(z.string())]).optional(),
|
||||||
*/
|
created_at: createOperatorMap().optional(),
|
||||||
@IsOptional()
|
updated_at: createOperatorMap().optional(),
|
||||||
@IsType([String, [String]])
|
deleted_at: createOperatorMap().optional(),
|
||||||
id?: string | string[]
|
$and: z.lazy(() => AdminGetPaymentsParams.array()).optional(),
|
||||||
|
$or: z.lazy(() => AdminGetPaymentsParams.array()).optional(),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
export type AdminGetPaymentProvidersParamsType = z.infer<
|
||||||
* Date filters to apply on the users' `update_at` date.
|
typeof AdminGetPaymentProvidersParams
|
||||||
*/
|
>
|
||||||
@IsOptional()
|
export const AdminGetPaymentProvidersParams = createFindParams({
|
||||||
@ValidateNested()
|
|
||||||
@Type(() => DateComparisonOperator)
|
|
||||||
updated_at?: DateComparisonOperator
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Date filters to apply on the customer users' `created_at` date.
|
|
||||||
*/
|
|
||||||
@IsOptional()
|
|
||||||
@ValidateNested()
|
|
||||||
@Type(() => DateComparisonOperator)
|
|
||||||
created_at?: DateComparisonOperator
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Date filters to apply on the users' `deleted_at` date.
|
|
||||||
*/
|
|
||||||
@IsOptional()
|
|
||||||
@ValidateNested()
|
|
||||||
@Type(() => DateComparisonOperator)
|
|
||||||
deleted_at?: DateComparisonOperator
|
|
||||||
}
|
|
||||||
|
|
||||||
export class AdminPostPaymentsCapturesReq {
|
|
||||||
@IsInt()
|
|
||||||
@IsOptional()
|
|
||||||
amount?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export class AdminPostPaymentsRefundsReq {
|
|
||||||
@IsInt()
|
|
||||||
@IsOptional()
|
|
||||||
amount?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export class AdminGetPaymentsPaymentProvidersParams extends extendedFindParamsMixin(
|
|
||||||
{
|
|
||||||
limit: 20,
|
limit: 20,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
}
|
}).merge(
|
||||||
) {
|
z.object({
|
||||||
/**
|
id: z.union([z.string(), z.array(z.string())]).optional(),
|
||||||
* IDs to filter users by.
|
is_enabled: z.boolean().optional(),
|
||||||
*/
|
$and: z.lazy(() => AdminGetPaymentProvidersParams.array()).optional(),
|
||||||
@IsOptional()
|
$or: z.lazy(() => AdminGetPaymentProvidersParams.array()).optional(),
|
||||||
@IsType([String, [String]])
|
})
|
||||||
id?: string | string[]
|
)
|
||||||
|
|
||||||
/**
|
export type AdminCreatePaymentCaptureType = z.infer<
|
||||||
* Filter providers by `enabled` flag
|
typeof AdminCreatePaymentCapture
|
||||||
*/
|
>
|
||||||
@IsBoolean()
|
export const AdminCreatePaymentCapture = z
|
||||||
@IsOptional()
|
.object({
|
||||||
is_enabled?: boolean
|
amount: z.number().optional(),
|
||||||
}
|
})
|
||||||
|
.strict()
|
||||||
|
|
||||||
|
export type AdminCreatePaymentRefundType = z.infer<
|
||||||
|
typeof AdminCreatePaymentRefund
|
||||||
|
>
|
||||||
|
export const AdminCreatePaymentRefund = z
|
||||||
|
.object({
|
||||||
|
amount: z.number().optional(),
|
||||||
|
})
|
||||||
|
.strict()
|
||||||
@@ -1,12 +1,15 @@
|
|||||||
import { MedusaContainer } from "@medusajs/types"
|
import { MedusaContainer } from "@medusajs/types"
|
||||||
import { remoteQueryObjectFromString } from "@medusajs/utils"
|
import {
|
||||||
|
ContainerRegistrationKeys,
|
||||||
|
remoteQueryObjectFromString,
|
||||||
|
} from "@medusajs/utils"
|
||||||
|
|
||||||
export const refetchProductType = async (
|
export const refetchProductType = async (
|
||||||
productTypeId: string,
|
productTypeId: string,
|
||||||
scope: MedusaContainer,
|
scope: MedusaContainer,
|
||||||
fields: string[]
|
fields: string[]
|
||||||
) => {
|
) => {
|
||||||
const remoteQuery = scope.resolve("remoteQuery")
|
const remoteQuery = scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||||
const queryObject = remoteQueryObjectFromString({
|
const queryObject = remoteQueryObjectFromString({
|
||||||
entryPoint: "product_type",
|
entryPoint: "product_type",
|
||||||
variables: {
|
variables: {
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { NextFunction } from "express"
|
||||||
|
import { MedusaRequest, MedusaResponse } from "../../types/routing"
|
||||||
|
import { MiddlewareFunction } from "../../types/middlewares"
|
||||||
|
|
||||||
|
// Due to how our route loader works, where we load all middlewares before routes, ambiguous routes end up having all middlewares on different routes executed before the route handler is.
|
||||||
|
// This function allows us to skip middlewares for particular routes, so we can temporarily solve this without completely breaking the route loader for everyone.
|
||||||
|
export const unlessPath =
|
||||||
|
(onPath: RegExp, middleware: MiddlewareFunction) =>
|
||||||
|
(req: MedusaRequest, res: MedusaResponse, next: NextFunction) => {
|
||||||
|
if (onPath.test(req.path)) {
|
||||||
|
return next()
|
||||||
|
} else {
|
||||||
|
return middleware(req, res, next)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user