feat: Clean up shipping options management (#6977)

**What**
- cleanup existing route on some aspects but not all
- add new create shipping options end point and types
- add set of integration tests
- cleanup existing fulfillment routes
- align existing integration tests
- transform old type to zod types and validators
- fix stock location route
This commit is contained in:
Adrien de Peretti
2024-04-06 18:52:05 +02:00
committed by GitHub
parent 5724d80286
commit bc06ad2db4
22 changed files with 556 additions and 205 deletions

View File

@@ -0,0 +1,6 @@
---
"@medusajs/medusa": patch
"@medusajs/types": patch
---
Feat/shipping options api 3

View File

@@ -63,11 +63,11 @@ medusaIntegrationTestRunner({
})
})
describe("POST /admin/fulfillment/shipping-options/:id/rules/batch/add", () => {
describe("POST /admin/shipping-options/:id/rules/batch/add", () => {
it("should throw error when required params are missing", async () => {
const { response } = await api
.post(
`/admin/fulfillment/shipping-options/${shippingOption.id}/rules/batch/add`,
`/admin/shipping-options/${shippingOption.id}/rules/batch/add`,
{
rules: [{ operator: RuleOperator.EQ, value: "new_value" }],
},
@@ -86,7 +86,7 @@ medusaIntegrationTestRunner({
it.only("should throw error when shipping option does not exist", async () => {
const { response } = await api
.post(
`/admin/fulfillment/shipping-options/does-not-exist/rules/batch/add`,
`/admin/shipping-options/does-not-exist/rules/batch/add`,
{
rules: [
{ attribute: "new_attr", operator: "eq", value: "new value" },
@@ -106,7 +106,7 @@ medusaIntegrationTestRunner({
it("should add rules to a shipping option successfully", async () => {
const response = await api.post(
`/admin/fulfillment/shipping-options/${shippingOption.id}/rules/batch/add`,
`/admin/shipping-options/${shippingOption.id}/rules/batch/add`,
{
rules: [
{ operator: "eq", attribute: "new_attr", value: "new value" },
@@ -140,11 +140,11 @@ medusaIntegrationTestRunner({
})
})
describe("POST /admin/fulfillment/shipping-options/:id/rules/batch/remove", () => {
describe("POST /admin/shipping-options/:id/rules/batch/remove", () => {
it("should throw error when required params are missing", async () => {
const { response } = await api
.post(
`/admin/fulfillment/shipping-options/${shippingOption.id}/rules/batch/remove`,
`/admin/shipping-options/${shippingOption.id}/rules/batch/remove`,
{},
adminHeaders
)
@@ -161,7 +161,7 @@ medusaIntegrationTestRunner({
it("should throw error when shipping option does not exist", async () => {
const { response } = await api
.post(
`/admin/fulfillment/shipping-options/does-not-exist/rules/batch/remove`,
`/admin/shipping-options/does-not-exist/rules/batch/remove`,
{ rule_ids: ["test"] },
adminHeaders
)
@@ -176,7 +176,7 @@ medusaIntegrationTestRunner({
it("should add rules to a shipping option successfully", async () => {
const response = await api.post(
`/admin/fulfillment/shipping-options/${shippingOption.id}/rules/batch/remove`,
`/admin/shipping-options/${shippingOption.id}/rules/batch/remove`,
{
rule_ids: [shippingOption.rules[0].id],
},

View File

@@ -0,0 +1,207 @@
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import {
IFulfillmentModuleService,
IRegionModuleService,
} from "@medusajs/types"
import { RuleOperator } from "@medusajs/utils"
import { medusaIntegrationTestRunner } from "medusa-test-utils"
import { createAdminUser } from "../../../../helpers/create-admin-user"
jest.setTimeout(50000)
const env = { MEDUSA_FF_MEDUSA_V2: true }
const adminHeaders = { headers: { "x-medusa-access-token": "test_token" } }
medusaIntegrationTestRunner({
env,
testSuite: ({ dbConnection, getContainer, api }) => {
describe("Admin: Shipping Option API", () => {
let appContainer
let fulfillmentModule: IFulfillmentModuleService
let regionService: IRegionModuleService
let shippingProfile
let fulfillmentSet
let region
const shippingOptionRule = {
operator: RuleOperator.EQ,
attribute: "old_attr",
value: "old value",
}
beforeAll(async () => {
appContainer = getContainer()
fulfillmentModule = appContainer.resolve(
ModuleRegistrationName.FULFILLMENT
)
regionService = appContainer.resolve(ModuleRegistrationName.REGION)
})
beforeEach(async () => {
await createAdminUser(dbConnection, adminHeaders, appContainer)
shippingProfile = await fulfillmentModule.createShippingProfiles({
name: "Test",
type: "default",
})
fulfillmentSet = await fulfillmentModule.create({
name: "Test",
type: "test-type",
service_zones: [
{
name: "Test",
geo_zones: [{ type: "country", country_code: "us" }],
},
],
})
region = await regionService.create({
name: "Test region",
countries: ["FR"],
currency_code: "eur",
})
})
describe("POST /admin/shipping-options", () => {
it("should throw error when required params are missing", async () => {
const shippingOptionPayload = {
name: "Test shipping option",
}
let err = await api
.post(
`/admin/shipping-options`,
shippingOptionPayload,
adminHeaders
)
.catch((e) => e.response)
const errorsFields = [
{
code: "invalid_type",
expected: "string",
received: "undefined",
path: ["service_zone_id"],
message: "Required",
},
{
code: "invalid_type",
expected: "string",
received: "undefined",
path: ["shipping_profile_id"],
message: "Required",
},
{
expected: "'calculated' | 'flat'",
received: "undefined",
code: "invalid_type",
path: ["price_type"],
message: "Required",
},
{
code: "invalid_type",
expected: "string",
received: "undefined",
path: ["provider_id"],
message: "Required",
},
{
code: "invalid_type",
expected: "object",
received: "undefined",
path: ["type"],
message: "Required",
},
{
code: "invalid_type",
expected: "array",
received: "undefined",
path: ["prices"],
message: "Required",
},
]
expect(err.status).toEqual(400)
expect(err.data).toEqual({
type: "invalid_data",
message: `Invalid request body: ${JSON.stringify(errorsFields)}`,
})
})
it("should create a shipping option successfully", async () => {
const shippingOptionPayload = {
name: "Test shipping option",
service_zone_id: fulfillmentSet.service_zones[0].id,
shipping_profile_id: shippingProfile.id,
provider_id: "manual_test-provider",
price_type: "flat",
type: {
label: "Test type",
description: "Test description",
code: "test-code",
},
prices: [
{
currency_code: "usd",
amount: 1000,
},
{
region_id: region.id,
amount: 1000,
},
],
rules: [shippingOptionRule],
}
const response = await api.post(
`/admin/shipping-options`,
shippingOptionPayload,
adminHeaders
)
expect(response.status).toEqual(200)
expect(response.data.shipping_option).toEqual(
expect.objectContaining({
id: expect.any(String),
name: shippingOptionPayload.name,
provider: expect.objectContaining({
id: shippingOptionPayload.provider_id,
}),
price_type: shippingOptionPayload.price_type,
type: expect.objectContaining({
id: expect.any(String),
label: shippingOptionPayload.type.label,
description: shippingOptionPayload.type.description,
code: shippingOptionPayload.type.code,
}),
service_zone_id: fulfillmentSet.service_zones[0].id,
shipping_profile_id: shippingProfile.id,
prices: expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
currency_code: "usd",
amount: 1000,
}),
expect.objectContaining({
id: expect.any(String),
currency_code: "eur",
amount: 1000,
}),
]),
rules: expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
operator: "eq",
attribute: "old_attr",
value: "old value",
}),
]),
})
)
})
})
})
},
})

View File

@@ -1,29 +0,0 @@
import { transformBody } from "../../../api/middlewares"
import { MiddlewareRoute } from "../../../loaders/helpers/routing/types"
import { authenticate } from "../../../utils/authenticate-middleware"
import {
AdminPostFulfillmentShippingOptionsRulesBatchAddReq,
AdminPostFulfillmentShippingOptionsRulesBatchRemoveReq,
} from "./validators"
export const adminFulfillmentRoutesMiddlewares: MiddlewareRoute[] = [
{
matcher: "/admin/fulfillment*",
middlewares: [authenticate("admin", ["bearer", "session"])],
},
{
method: ["POST"],
matcher: "/admin/fulfillment/shipping-options/:id/rules/batch/add",
middlewares: [
transformBody(AdminPostFulfillmentShippingOptionsRulesBatchAddReq),
],
},
{
method: ["POST"],
matcher: "/admin/fulfillment/shipping-options/:id/rules/batch/remove",
middlewares: [
transformBody(AdminPostFulfillmentShippingOptionsRulesBatchRemoveReq),
],
},
]

View File

@@ -1,29 +0,0 @@
export const defaultAdminShippingOptionRelations = ["rules"]
export const allowedAdminShippingOptionRelations = [
...defaultAdminShippingOptionRelations,
]
export const defaultAdminShippingOptionFields = [
"id",
"name",
"price_type",
"data",
"metadata",
"created_at",
"updated_at",
"rules.id",
"rules.attribute",
"rules.operator",
"rules.value",
]
export const retrieveTransformQueryConfig = {
defaultFields: defaultAdminShippingOptionFields,
defaultRelations: defaultAdminShippingOptionRelations,
allowedRelations: allowedAdminShippingOptionRelations,
isList: false,
}
export const listTransformQueryConfig = {
...retrieveTransformQueryConfig,
isList: true,
}

View File

@@ -1,45 +0,0 @@
import { addRulesToFulfillmentShippingOptionWorkflow } from "@medusajs/core-flows"
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { IFulfillmentModuleService } from "@medusajs/types"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../../../../../../types/routing"
import {
defaultAdminShippingOptionFields,
defaultAdminShippingOptionRelations,
} from "../../../../../query-config"
import { AdminPostFulfillmentShippingOptionsRulesBatchAddReq } from "../../../../../validators"
export const POST = async (
req: AuthenticatedMedusaRequest<AdminPostFulfillmentShippingOptionsRulesBatchAddReq>,
res: MedusaResponse
) => {
const id = req.params.id
const workflow = addRulesToFulfillmentShippingOptionWorkflow(req.scope)
const { errors } = await workflow.run({
input: {
data: req.validatedBody.rules.map((rule) => ({
...rule,
shipping_option_id: id,
})),
},
throwOnError: false,
})
if (Array.isArray(errors) && errors[0]) {
throw errors[0].error
}
const fulfillmentService: IFulfillmentModuleService = req.scope.resolve(
ModuleRegistrationName.FULFILLMENT
)
const shippingOption = await fulfillmentService.retrieveShippingOption(id, {
select: defaultAdminShippingOptionFields,
relations: defaultAdminShippingOptionRelations,
})
res.status(200).json({ shipping_option: shippingOption })
}

View File

@@ -1,40 +0,0 @@
import { removeRulesFromFulfillmentShippingOptionWorkflow } from "@medusajs/core-flows"
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { IFulfillmentModuleService } from "@medusajs/types"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../../../../../../types/routing"
import {
defaultAdminShippingOptionFields,
defaultAdminShippingOptionRelations,
} from "../../../../../query-config"
import { AdminPostFulfillmentShippingOptionsRulesBatchRemoveReq } from "../../../../../validators"
export const POST = async (
req: AuthenticatedMedusaRequest<AdminPostFulfillmentShippingOptionsRulesBatchRemoveReq>,
res: MedusaResponse
) => {
const id = req.params.id
const workflow = removeRulesFromFulfillmentShippingOptionWorkflow(req.scope)
const { errors } = await workflow.run({
input: { ids: req.validatedBody.rule_ids },
throwOnError: false,
})
if (Array.isArray(errors) && errors[0]) {
throw errors[0].error
}
const fulfillmentService: IFulfillmentModuleService = req.scope.resolve(
ModuleRegistrationName.FULFILLMENT
)
const shippingOption = await fulfillmentService.retrieveShippingOption(id, {
select: defaultAdminShippingOptionFields,
relations: defaultAdminShippingOptionRelations,
})
res.status(200).json({ shipping_option: shippingOption })
}

View File

@@ -1,36 +0,0 @@
import { RuleOperator } from "@medusajs/utils"
import { Type } from "class-transformer"
import {
ArrayNotEmpty,
IsArray,
IsEnum,
IsNotEmpty,
IsString,
ValidateNested,
} from "class-validator"
import { IsType } from "../../../utils"
export class AdminPostFulfillmentShippingOptionsRulesBatchAddReq {
@IsArray()
@ValidateNested({ each: true })
@Type(() => FulfillmentRuleCreate)
rules: FulfillmentRuleCreate[]
}
export class AdminPostFulfillmentShippingOptionsRulesBatchRemoveReq {
@ArrayNotEmpty()
@IsString({ each: true })
rule_ids: string[]
}
export class FulfillmentRuleCreate {
@IsEnum(RuleOperator)
operator: RuleOperator
@IsNotEmpty()
@IsString()
attribute: string
@IsType([String, [String]])
value: string | string[]
}

View File

@@ -27,7 +27,7 @@ export const POST = async (
variables: {
id: result[0].id,
},
fields: req.retrieveConfig.select as string[],
fields: req.remoteQueryConfig.fields,
})
)
@@ -45,11 +45,9 @@ export const GET = async (
entryPoint: "inventory_items",
variables: {
filters: req.filterableFields,
order: req.listConfig.order,
skip: req.listConfig.skip,
take: req.listConfig.take,
...req.remoteQueryConfig.pagination,
},
fields: [...(req.listConfig.select as string[])],
fields: req.remoteQueryConfig.fields,
})
const { rows: inventory_items, metadata } = await remoteQuery({

View File

@@ -0,0 +1,48 @@
import { addRulesToFulfillmentShippingOptionWorkflow } from "@medusajs/core-flows"
import {
ContainerRegistrationKeys,
remoteQueryObjectFromString,
} from "@medusajs/utils"
import { AdminShippingOptionRetrieveResponse } from "@medusajs/types"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../../../../../types/routing"
import { AdminShippingOptionRulesBatchAddType } from "../../../../validators"
export const POST = async (
req: AuthenticatedMedusaRequest<
AdminShippingOptionRulesBatchAddType
>,
res: MedusaResponse<AdminShippingOptionRetrieveResponse>
) => {
const id = req.params.id
const workflow = addRulesToFulfillmentShippingOptionWorkflow(req.scope)
const { errors } = await workflow.run({
input: {
data: req.validatedBody.rules.map((rule) => ({
...rule,
shipping_option_id: id,
})),
},
throwOnError: false,
})
if (Array.isArray(errors) && errors[0]) {
throw errors[0].error
}
const query = remoteQueryObjectFromString({
entryPoint: "shipping_options",
variables: {
id: req.params.id,
},
fields: req.remoteQueryConfig.fields,
})
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
const [shippingOption] = await remoteQuery(query)
res.status(200).json({ shipping_option: shippingOption })
}

View File

@@ -0,0 +1,40 @@
import { removeRulesFromFulfillmentShippingOptionWorkflow } from "@medusajs/core-flows"
import {
ContainerRegistrationKeys,
remoteQueryObjectFromString,
} from "@medusajs/utils"
import { AdminShippingOptionRetrieveResponse } from "@medusajs/types"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../../../../../types/routing"
import { AdminShippingOptionRulesBatchRemoveType } from "../../../../validators"
export const POST = async (
req: AuthenticatedMedusaRequest<AdminShippingOptionRulesBatchRemoveType>,
res: MedusaResponse<AdminShippingOptionRetrieveResponse>
) => {
const workflow = removeRulesFromFulfillmentShippingOptionWorkflow(req.scope)
const { errors } = await workflow.run({
input: { ids: req.validatedBody.rule_ids },
throwOnError: false,
})
if (Array.isArray(errors) && errors[0]) {
throw errors[0].error
}
const query = remoteQueryObjectFromString({
entryPoint: "shipping_options",
variables: {
id: req.params.id,
},
fields: req.remoteQueryConfig.fields,
})
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
const [shippingOption] = await remoteQuery(query)
res.status(200).json({ shipping_option: shippingOption })
}

View File

@@ -0,0 +1,54 @@
import { MiddlewareRoute } from "../../../loaders/helpers/routing/types"
import { authenticate } from "../../../utils/authenticate-middleware"
import {
AdminCreateShippingOption,
AdminGetShippingOptionParams,
AdminShippingOptionRulesBatchAdd,
AdminShippingOptionRulesBatchRemove,
} from "./validators"
import { retrieveTransformQueryConfig } from "./query-config"
import { validateAndTransformBody } from "../../utils/validate-body"
import { validateAndTransformQuery } from "../../utils/validate-query"
export const adminShippingOptionRoutesMiddlewares: MiddlewareRoute[] = [
{
matcher: "/admin/shipping-options*",
middlewares: [authenticate("admin", ["bearer", "session"])],
},
{
method: ["POST"],
matcher: "/admin/shipping-options",
middlewares: [
validateAndTransformQuery(
AdminGetShippingOptionParams,
retrieveTransformQueryConfig
),
validateAndTransformBody(AdminCreateShippingOption),
],
},
{
method: ["POST"],
matcher: "/admin/shipping-options/:id/rules/batch/add",
middlewares: [
validateAndTransformQuery(
AdminGetShippingOptionParams,
retrieveTransformQueryConfig
),
validateAndTransformBody(AdminShippingOptionRulesBatchAdd),
],
},
{
method: ["POST"],
matcher: "/admin/shipping-options/:id/rules/batch/remove",
middlewares: [
validateAndTransformQuery(
AdminGetShippingOptionParams,
retrieveTransformQueryConfig
),
validateAndTransformBody(AdminShippingOptionRulesBatchRemove),
],
},
]

View File

@@ -0,0 +1,25 @@
export const defaultAdminShippingOptionFields = [
"id",
"name",
"price_type",
"data",
"metadata",
"created_at",
"updated_at",
"*rules",
"*type",
"*prices",
"*service_zone",
"*shipping_profile",
"*provider",
]
export const retrieveTransformQueryConfig = {
defaults: defaultAdminShippingOptionFields,
isList: false,
}
export const listTransformQueryConfig = {
...retrieveTransformQueryConfig,
isList: true,
}

View File

@@ -0,0 +1,44 @@
import { createShippingOptionsWorkflow } from "@medusajs/core-flows"
import {
ContainerRegistrationKeys,
remoteQueryObjectFromString,
} from "@medusajs/utils"
import { AdminShippingOptionRetrieveResponse } from "@medusajs/types"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../types/routing"
import { AdminCreateShippingOptionType } from "./validators"
export const POST = async (
req: AuthenticatedMedusaRequest<AdminCreateShippingOptionType>,
res: MedusaResponse<AdminShippingOptionRetrieveResponse>
) => {
const shippingOptionPayload = req.validatedBody
const workflow = createShippingOptionsWorkflow(req.scope)
const { result, errors } = await workflow.run({
input: [shippingOptionPayload],
throwOnError: false,
})
if (Array.isArray(errors) && errors[0]) {
throw errors[0].error
}
const shippingOptionId = result[0].id
const query = remoteQueryObjectFromString({
entryPoint: "shipping_options",
variables: {
id: shippingOptionId,
},
fields: req.remoteQueryConfig.fields,
})
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
const [shippingOption] = await remoteQuery(query)
res.status(200).json({ shipping_option: shippingOption })
}

View File

@@ -0,0 +1,87 @@
import {
RuleOperator,
ShippingOptionPriceType as ShippingOptionPriceTypeEnum,
} from "@medusajs/utils"
import { z } from "zod"
import { createSelectParams } from "../../utils/validators"
export const AdminGetShippingOptionParams = createSelectParams()
/**
* SHIPPING OPTIONS RULES
*/
export const AdminCreateShippingOptionRule = z
.object({
operator: z.nativeEnum(RuleOperator),
attribute: z.string(),
value: z.string().or(z.array(z.string())),
})
.strict()
export const AdminShippingOptionRulesBatchAdd = z
.object({
rules: AdminCreateShippingOptionRule.array(),
})
.strict()
export type AdminShippingOptionRulesBatchAddType = z.infer<
typeof AdminShippingOptionRulesBatchAdd
>
export const AdminShippingOptionRulesBatchRemove = z
.object({
rule_ids: z.array(z.string()),
})
.strict()
export type AdminShippingOptionRulesBatchRemoveType = z.infer<
typeof AdminShippingOptionRulesBatchRemove
>
/**
* SHIPPING OPTIONS
*/
export const AdminCreateShippingOptionType = z
.object({
label: z.string(),
description: z.string(),
code: z.string(),
})
.strict()
// eslint-disable-next-line max-len
export const AdminCreateShippingOptionPriceWithCurrency = z
.object({
currency_code: z.string(),
amount: z.number(),
})
.strict()
export const AdminCreateShippingOptionPriceWithRegion = z
.object({
region_id: z.string(),
amount: z.number(),
})
.strict()
export const AdminCreateShippingOption = z
.object({
name: z.string(),
service_zone_id: z.string(),
shipping_profile_id: z.string(),
data: z.record(z.unknown()).optional(),
price_type: z.nativeEnum(ShippingOptionPriceTypeEnum),
provider_id: z.string(),
type: AdminCreateShippingOptionType,
prices: AdminCreateShippingOptionPriceWithCurrency.or(
AdminCreateShippingOptionPriceWithRegion
).array(),
rules: AdminCreateShippingOptionRule.array().optional(),
})
.strict()
export type AdminCreateShippingOptionType = z.infer<
typeof AdminCreateShippingOption
>

View File

@@ -5,8 +5,8 @@ import { adminCollectionRoutesMiddlewares } from "./admin/collections/middleware
import { adminCurrencyRoutesMiddlewares } from "./admin/currencies/middlewares"
import { adminCustomerGroupRoutesMiddlewares } from "./admin/customer-groups/middlewares"
import { adminCustomerRoutesMiddlewares } from "./admin/customers/middlewares"
import { adminShippingOptionRoutesMiddlewares } from "./admin/shipping-options/middlewares"
import { adminDraftOrderRoutesMiddlewares } from "./admin/draft-orders/middlewares"
import { adminFulfillmentRoutesMiddlewares } from "./admin/fulfillment/middlewares"
import { adminInventoryRoutesMiddlewares } from "./admin/inventory-items/middlewares"
import { adminInviteRoutesMiddlewares } from "./admin/invites/middlewares"
import { adminPaymentRoutesMiddlewares } from "./admin/payments/middlewares"
@@ -59,7 +59,7 @@ export const config: MiddlewaresConfig = {
...adminInventoryRoutesMiddlewares,
...adminCollectionRoutesMiddlewares,
...adminPricingRoutesMiddlewares,
...adminFulfillmentRoutesMiddlewares,
...adminShippingOptionRoutesMiddlewares,
...adminDraftOrderRoutesMiddlewares,
...adminSalesChannelRoutesMiddlewares,
...adminStockLocationRoutesMiddlewares,

View File

@@ -12,7 +12,7 @@ export const POST = async (
res: MedusaResponse
) => {
const { id } = req.params
const { context, provider_id, data } = req.body
const { context = {}, provider_id, data } = req.body
// If the customer is logged in, we auto-assign them to the payment collection
if (req.auth?.actor_id) {

View File

@@ -3,8 +3,10 @@ import type { Customer, User } from "../models"
import { MedusaContainer, RequestQueryFields } from "@medusajs/types"
import { FindConfig } from "./common"
import * as core from "express-serve-static-core"
export interface MedusaRequest<Body = unknown> extends Request {
export interface MedusaRequest<Body = unknown>
extends Request<core.ParamsDictionary, any, Body> {
validatedBody: Body
validatedQuery: RequestQueryFields & Record<string, unknown>
/**
@@ -22,7 +24,10 @@ export interface MedusaRequest<Body = unknown> extends Request {
/**
* An object containing fields and variables to be used with the remoteQuery
*/
remoteQueryConfig: { fields: string[]; pagination: { order?: Record<string, string>, skip?: number, take?: number } }
remoteQueryConfig: {
fields: string[]
pagination: { order?: Record<string, string>; skip?: number; take?: number }
}
/**
* An object containing the fields that are filterable e.g `{ id: Any<String> }`
*/
@@ -58,12 +63,12 @@ export interface AuthenticatedMedusaRequest<Body = never>
}
}
export type MedusaResponse = Response
export type MedusaResponse<Body = unknown> = Response<Body>
export type MedusaNextFunction = NextFunction
export type MedusaRequestHandler = (
req: MedusaRequest<unknown>,
res: MedusaResponse,
export type MedusaRequestHandler<Body = unknown, Res = unknown> = (
req: MedusaRequest<Body>,
res: MedusaResponse<Res>,
next: MedusaNextFunction
) => Promise<void> | void

View File

@@ -4,12 +4,12 @@ import { AdminShippingOptionTypeResponse } from "./shipping-option-type"
import { AdminShippingOptionRuleResponse } from "./shipping-option-rule"
import { AdminShippingProfileResponse } from "./shipping-profile"
import { AdminFulfillmentProviderResponse } from "./fulfillment-provider"
import { AdminFulfillmentResponse } from "./fulfillment"
import { AdminPriceSetPriceResponse } from "../../pricing"
/**
* @experimental
*/
export interface AdminShippingOptionResponse {
interface AdminShippingOptionResponse {
id: string
name: string
price_type: ShippingOptionPriceType
@@ -21,11 +21,18 @@ export interface AdminShippingOptionResponse {
metadata: Record<string, unknown> | null
service_zone: AdminServiceZoneResponse
shipping_profile: AdminShippingProfileResponse
fulfillment_provider: AdminFulfillmentProviderResponse
provider: AdminFulfillmentProviderResponse
type: AdminShippingOptionTypeResponse
rules: AdminShippingOptionRuleResponse[]
fulfillments: AdminFulfillmentResponse[]
prices: AdminPriceSetPriceResponse[]
created_at: Date
updated_at: Date
deleted_at: Date | null
}
/**
* @experimental
*/
export interface AdminShippingOptionRetrieveResponse {
shipping_option: AdminShippingOptionResponse[]
}

View File

@@ -1,4 +1,5 @@
export * from "./api-key"
export * from "./fulfillment"
export * from "./pricing"
export * from "./sales-channel"
export * from "./stock-locations"

View File

@@ -0,0 +1 @@
export * from "./price"

View File

@@ -0,0 +1,7 @@
export interface AdminPriceSetPriceResponse {
id: string
amount: number
currency_code: string
created_at: string
updated_at: string
}