docs: document InferTypeOf (#9321)
- Add documentation on how to use InferTypeOf - Use InferTypeOf in recipes and examples
This commit is contained in:
@@ -58,7 +58,7 @@ const { data: products } = await query.graph({
|
||||
region_id: "region_123",
|
||||
currency_code: "usd",
|
||||
}),
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
@@ -1575,12 +1575,13 @@ You’ll only implement the `3.a` step of the workflow.
|
||||
Create the file `src/workflows/create-digital-product-order/steps/create-digital-product-order.ts` with the following content:
|
||||
|
||||
export const createDpoHighlights = [
|
||||
["18", "InferTypeOf", "Infer the type of the `DigitalProduct` data model since it's a variable."],
|
||||
["33", "createDigitalProductOrders", "Create the digital product order."],
|
||||
["41", "digital_product_order", "Pass the created digital product order to the compensation function."],
|
||||
["48", "deleteDigitalProductOrders", "Delete the digital product order if an error occurs in the workflow."]
|
||||
]
|
||||
|
||||
```ts title="src/workflows/create-digital-product-order/steps/create-digital-product-order.ts" highlights={createDpoHighlights} collapsibleLines="1-15" expandMoreLabel="Show Imports"
|
||||
```ts title="src/workflows/create-digital-product-order/steps/create-digital-product-order.ts" highlights={createDpoHighlights} collapsibleLines="1-14" expandMoreLabel="Show Imports"
|
||||
import {
|
||||
createStep,
|
||||
StepResponse,
|
||||
@@ -1588,18 +1589,17 @@ import {
|
||||
import {
|
||||
OrderLineItemDTO,
|
||||
ProductVariantDTO,
|
||||
InferTypeOf,
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
DigitalProductData,
|
||||
OrderStatus,
|
||||
} from "../../../modules/digital-product/types"
|
||||
import { OrderStatus } from "../../../modules/digital-product/types"
|
||||
import DigitalProductModuleService from "../../../modules/digital-product/service"
|
||||
import { DIGITAL_PRODUCT_MODULE } from "../../../modules/digital-product"
|
||||
import DigitalProduct from "../../../modules/digital-product/models/digital-product"
|
||||
|
||||
type StepInput = {
|
||||
items: (OrderLineItemDTO & {
|
||||
variant: ProductVariantDTO & {
|
||||
digital_product: DigitalProductData
|
||||
digital_product: InferTypeOf<typeof DigitalProduct>
|
||||
}
|
||||
})[]
|
||||
}
|
||||
@@ -1833,20 +1833,21 @@ So, you only need to implement the second step.
|
||||
Before creating the step, add to `src/modules/digital-product/types/index.ts` the following:
|
||||
|
||||
```ts
|
||||
import { OrderDTO } from "@medusajs/types"
|
||||
import { OrderDTO, InferTypeOf } from "@medusajs/types"
|
||||
import DigitalProductOrder from "../models/digital-product-order"
|
||||
|
||||
// ...
|
||||
|
||||
export type DigitalProductOrderData = {
|
||||
id: string
|
||||
status: OrderStatus
|
||||
products?: DigitalProductData[]
|
||||
order?: OrderDTO
|
||||
}
|
||||
export type DigitalProductOrder =
|
||||
InferTypeOf<typeof DigitalProductOrder> & {
|
||||
order?: OrderDTO
|
||||
}
|
||||
```
|
||||
|
||||
This adds a type for a digital product order, which you'll use next.
|
||||
|
||||
You use the `InferTypeOf` utility to infer the type of the `DigitalProductOrder` data model, and add to it the optional `order` property, which is the linked order.
|
||||
|
||||
### Create sendDigitalOrderNotificationStep
|
||||
|
||||
To create the step, create the file `src/workflows/fulfill-digital-order/steps/send-digital-order-notification.ts` with the following content:
|
||||
@@ -1854,23 +1855,23 @@ To create the step, create the file `src/workflows/fulfill-digital-order/steps/s
|
||||
```ts title="src/workflows/fulfill-digital-order/steps/send-digital-order-notification.ts" collapsibleLines="1-11" expandMoreLabel="Show Imports"
|
||||
import {
|
||||
createStep,
|
||||
StepResponse
|
||||
StepResponse,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import {
|
||||
INotificationModuleService,
|
||||
IFileModuleService
|
||||
IFileModuleService,
|
||||
} from "@medusajs/types"
|
||||
import { ModuleRegistrationName } from "@medusajs/utils"
|
||||
import { DigitalProductOrderData, MediaType } from "../../../modules/digital-product/types"
|
||||
import { DigitalProductOrder, MediaType } from "../../../modules/digital-product/types"
|
||||
|
||||
type SendDigitalOrderNotificationStepInput = {
|
||||
digital_product_order: DigitalProductOrderData
|
||||
digital_product_order: DigitalProductOrder
|
||||
}
|
||||
|
||||
export const sendDigitalOrderNotificationStep = createStep(
|
||||
"send-digital-order-notification",
|
||||
async ({
|
||||
digital_product_order: digitalProductOrder
|
||||
digital_product_order: digitalProductOrder,
|
||||
}: SendDigitalOrderNotificationStepInput,
|
||||
{ container }) => {
|
||||
const notificationModuleService: INotificationModuleService = container
|
||||
@@ -1907,7 +1908,7 @@ const notificationData = await Promise.all(
|
||||
|
||||
return {
|
||||
name: product.name,
|
||||
medias
|
||||
medias,
|
||||
}
|
||||
})
|
||||
)
|
||||
@@ -1925,8 +1926,8 @@ const notification = await notificationModuleService.createNotifications({
|
||||
template: "digital-order-template",
|
||||
channel: "email",
|
||||
data: {
|
||||
products: notificationData
|
||||
}
|
||||
products: notificationData,
|
||||
},
|
||||
})
|
||||
|
||||
return new StepResponse(notification)
|
||||
@@ -1946,10 +1947,10 @@ export const fulfillWorkflowHighlights = [
|
||||
```ts title="src/workflows/fulfill-digital-order/index.ts" highlights={fulfillWorkflowHighlights} collapsibleLines="1-10" expandMoreLabel="Show Imports"
|
||||
import {
|
||||
createWorkflow,
|
||||
WorkflowResponse
|
||||
WorkflowResponse,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import {
|
||||
useRemoteQueryStep
|
||||
useRemoteQueryStep,
|
||||
} from "@medusajs/core-flows"
|
||||
import { sendDigitalOrderNotificationStep } from "./steps/send-digital-order-notification"
|
||||
|
||||
@@ -1966,7 +1967,7 @@ export const fulfillDigitalOrderWorkflow = createWorkflow(
|
||||
"*",
|
||||
"products.*",
|
||||
"products.medias.*",
|
||||
"order.*"
|
||||
"order.*",
|
||||
],
|
||||
variables: {
|
||||
filters: {
|
||||
@@ -1974,11 +1975,11 @@ export const fulfillDigitalOrderWorkflow = createWorkflow(
|
||||
},
|
||||
},
|
||||
list: false,
|
||||
throw_if_key_not_found: true
|
||||
throw_if_key_not_found: true,
|
||||
})
|
||||
|
||||
sendDigitalOrderNotificationStep({
|
||||
digital_product_order: digitalProductOrder
|
||||
digital_product_order: digitalProductOrder,
|
||||
})
|
||||
|
||||
return new WorkflowResponse(
|
||||
@@ -2021,7 +2022,7 @@ module.exports = defineConfig({
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
```
|
||||
@@ -2040,7 +2041,7 @@ import type {
|
||||
SubscriberConfig,
|
||||
} from "@medusajs/medusa"
|
||||
import {
|
||||
fulfillDigitalOrderWorkflow
|
||||
fulfillDigitalOrderWorkflow,
|
||||
} from "../workflows/fulfill-digital-order"
|
||||
|
||||
async function digitalProductOrderCreatedHandler({
|
||||
@@ -2049,8 +2050,8 @@ async function digitalProductOrderCreatedHandler({
|
||||
}: SubscriberArgs<{ id: string }>) {
|
||||
await fulfillDigitalOrderWorkflow(container).run({
|
||||
input: {
|
||||
id: data.id
|
||||
}
|
||||
id: data.id,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -435,17 +435,13 @@ Before implementing the functionalities, you’ll create type files in the Resta
|
||||
Create the file `src/modules/restaurant/types/index.ts` with the following content:
|
||||
|
||||
```ts title="src/modules/restaurant/types/index.ts"
|
||||
import { InferTypeOf } from "@medusajs/types"
|
||||
import RestaurantModuleService from "../service"
|
||||
import { Restaurant } from "../models/restaurant"
|
||||
|
||||
export interface CreateRestaurant {
|
||||
name: string;
|
||||
handle: string;
|
||||
address: string;
|
||||
phone: string;
|
||||
email: string;
|
||||
image_url?: string;
|
||||
is_open?: boolean;
|
||||
}
|
||||
export type CreateRestaurant = Omit<
|
||||
InferTypeOf<typeof Restaurant>, "id" | "admins"
|
||||
>
|
||||
|
||||
declare module "@medusajs/types" {
|
||||
export interface ModuleImplementations {
|
||||
@@ -456,6 +452,12 @@ declare module "@medusajs/types" {
|
||||
|
||||
This adds a type used for inputs in creating a restaurant. It also adds a type for `restaurantModuleService` in `ModuleImplementations` so that when you resolve it from the Medusa container, it has the correct typing.
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
Since the `Restaurant` data model is a variable, use the `InferTypeOf` utility imported from `@medusajs/types` to infer its type.
|
||||
|
||||
</Note>
|
||||
|
||||
### Create Workflow
|
||||
|
||||
To implement the functionality of creating a restaurant, create a workflow and execute it in the API route.
|
||||
@@ -630,7 +632,7 @@ In the file `src/api/restaurants/route.ts` add the following API route:
|
||||
import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
QueryContext
|
||||
QueryContext,
|
||||
} from "@medusajs/utils"
|
||||
|
||||
// ...
|
||||
@@ -662,7 +664,7 @@ export async function GET(req: MedusaRequest, res: MedusaResponse) {
|
||||
variants: {
|
||||
calculated_price: QueryContext({
|
||||
currency_code,
|
||||
})
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -2259,40 +2261,26 @@ Before implementing the necessary functionalities, add the following types to `s
|
||||
|
||||
```ts title="src/modules/delivery/types/index.ts"
|
||||
// other imports...
|
||||
import {
|
||||
CartLineItemDTO,
|
||||
OrderLineItemDTO,
|
||||
CartDTO,
|
||||
OrderDTO,
|
||||
} from "@medusajs/types"
|
||||
import { InferTypeOf } from "@medusajs/types"
|
||||
import { Delivery } from "../models/delivery"
|
||||
|
||||
// ...
|
||||
|
||||
export interface Delivery {
|
||||
id: string;
|
||||
transaction_id: string;
|
||||
driver_id?: string;
|
||||
delivered_at?: Date;
|
||||
delivery_status: DeliveryStatus;
|
||||
created_at: Date;
|
||||
updated_at: Date;
|
||||
eta?: Date;
|
||||
items: DeliveryItem[];
|
||||
cart?: CartDTO;
|
||||
order?: OrderDTO;
|
||||
}
|
||||
export type Delivery = InferTypeOf<typeof Delivery>
|
||||
|
||||
export type DeliveryItem = (CartLineItemDTO | OrderLineItemDTO) & {
|
||||
quantity: number;
|
||||
}
|
||||
|
||||
export interface UpdateDelivery extends Partial<Delivery> {
|
||||
export type UpdateDelivery = Partial<Delivery> & {
|
||||
id: string;
|
||||
}
|
||||
```
|
||||
|
||||
These types are useful in the upcoming implementation steps.
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
Since the `Delivery` data model is a variable, use the `InferTypeOf` utility imported from `@medusajs/types` to infer its type.
|
||||
|
||||
</Note>
|
||||
|
||||
### Create Workflow
|
||||
|
||||
As the API route should update the delivery’s status, you’ll create a new workflow to implement that functionality.
|
||||
|
||||
@@ -862,11 +862,11 @@ This step groups the items by the vendor associated with the product into an obj
|
||||
Next, create the fourth step in the file `src/workflows/marketplace/create-vendor-orders/steps/create-vendor-orders.ts`:
|
||||
|
||||
export const vendorOrder1Highlights = [
|
||||
["41", "linkDefs", "An array of links to be created."],
|
||||
["58", "created_orders", "Pass the created orders to the compensation function."]
|
||||
["42", "linkDefs", "An array of links to be created."],
|
||||
["59", "created_orders", "Pass the created orders to the compensation function."]
|
||||
]
|
||||
|
||||
```ts title="src/workflows/marketplace/create-vendor-orders/steps/create-vendor-orders.ts" highlights={vendorOrder1Highlights} collapsibleLines="1-18" expandMoreLabel="Show Imports"
|
||||
```ts title="src/workflows/marketplace/create-vendor-orders/steps/create-vendor-orders.ts" highlights={vendorOrder1Highlights} collapsibleLines="1-19" expandMoreLabel="Show Imports"
|
||||
import {
|
||||
createStep,
|
||||
StepResponse,
|
||||
@@ -874,7 +874,8 @@ import {
|
||||
import {
|
||||
CartLineItemDTO,
|
||||
OrderDTO,
|
||||
LinkDefinition
|
||||
LinkDefinition,
|
||||
InferTypeOf,
|
||||
} from "@medusajs/types"
|
||||
import { Modules } from "@medusajs/utils"
|
||||
import {
|
||||
@@ -883,10 +884,10 @@ import {
|
||||
} from "@medusajs/core-flows"
|
||||
import MarketplaceModuleService from "../../../../modules/marketplace/service"
|
||||
import { MARKETPLACE_MODULE } from "../../../../modules/marketplace"
|
||||
import { VendorData } from "../../../../modules/marketplace/types"
|
||||
import Vendor from "../../../../modules/marketplace/models/vendor"
|
||||
|
||||
export type VendorOrder = (OrderDTO & {
|
||||
vendor: VendorData
|
||||
vendor: InferTypeOf<typeof Vendor>
|
||||
})
|
||||
|
||||
type StepInput = {
|
||||
|
||||
@@ -363,6 +363,9 @@ The `getExpirationDate` method accepts a subscription’s date, interval, and pe
|
||||
Before overriding the `createSubscriptions` method, add the following types to `src/modules/subscription/types/index.ts`:
|
||||
|
||||
```ts title="src/modules/subscription/types/index.ts"
|
||||
import { InferTypeOf } from "@medusajs/types"
|
||||
import Subscription from "../models/subscription"
|
||||
|
||||
// ...
|
||||
|
||||
export type CreateSubscriptionData = {
|
||||
@@ -373,19 +376,15 @@ export type CreateSubscriptionData = {
|
||||
metadata?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export type SubscriptionData = {
|
||||
id: string
|
||||
status: SubscriptionStatus
|
||||
interval: SubscriptionInterval
|
||||
subscription_date: Date
|
||||
last_order_date: Date
|
||||
next_order_date: Date | null
|
||||
expiration_date: Date
|
||||
metadata: Record<string, unknown> | null
|
||||
}
|
||||
|
||||
export type SubscriptionData = InferTypeOf<typeof Subscription>
|
||||
```
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
Since the `Subscription` data model is a variable, use the `InferTypeOf` utility imported from `@medusajs/types` to infer its type.
|
||||
|
||||
</Note>
|
||||
|
||||
Then, in `src/modules/subscription/service.ts`, add the following to override the `createSubscriptions` method:
|
||||
|
||||
```ts title="src/modules/subscription/service.ts"
|
||||
|
||||
Reference in New Issue
Block a user