docs: general fixes and improvements (#7918)
* docs improvements and changes * updated module definition * modules + dml changes * fix build * fix vale error * fix lint errors * fixes to stripe docs * fix condition * fix condition * fix module defintion * fix checkout * disable UI action * change oas preview action * flatten provider module options * fix lint errors * add module link docs * pr comments fixes * fix vale error * change node engine version * links -> linkable * add note about database name * small fixes * link fixes * fix response code in api reference * added migrations step
This commit is contained in:
1 parent
32982e708a
commit
964927b597
149 files changed
+1676
-3008
No files matched your search
@@ -10,9 +10,9 @@ In this chapter, you’ll learn how to customize the Medusa Admin dashboard.
|
||||
|
||||
The Medusa Admin is an admin dashboard that merchants use to manage their store's data.
|
||||
|
||||
You can extend the Medusa Admin to add widgets and new pages. Your customizations interact with API routes to provide merchants with custom functionalities.
|
||||
You can extend the Medusa Admin to add widgets and new pages. In your customizations, you interact with API routes to provide merchants with custom functionalities.
|
||||
|
||||
The Medusa Admin is installed in your Medusa application and runs at the path `/app` when you start the Medusa application.
|
||||
The Medusa Admin is installed in your Medusa application and runs at `http://localhost:9000/app` when you start the application.
|
||||
|
||||
---
|
||||
|
||||
@@ -34,13 +34,13 @@ const ProductWidget = () => {
|
||||
}
|
||||
|
||||
export const config = defineWidgetConfig({
|
||||
zone: "product.details.after",
|
||||
zone: "product.details.before",
|
||||
})
|
||||
|
||||
export default ProductWidget
|
||||
```
|
||||
|
||||
This inserts a widget with the text “Product Widget” at the end of a product’s details page.
|
||||
This inserts a widget with the text “Product Widget” at the beginning of a product’s details page.
|
||||
|
||||
### Test the Widget
|
||||
|
||||
@@ -50,4 +50,4 @@ To test out the widget, start the Medusa application:
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Then, open a product’s details page. You’ll find your custom widget at the bottom of the page.
|
||||
Then, open a product’s details page in the Medusa Admin. You’ll find your custom widget at the top of the page.
|
||||
@@ -14,11 +14,11 @@ The Medusa core application provides a set of admin and store API routes out-of-
|
||||
|
||||
---
|
||||
|
||||
## How to Create an API Route
|
||||
## How to Create an API Route?
|
||||
|
||||
An API Route is created in a TypeScript or JavaScript file under the `/src/api` directory of your Medusa application. The file’s name must be `route.ts` or `route.js`.
|
||||
An API Route is created in a TypeScript or JavaScript file under the `src/api` directory of your Medusa application. The file’s name must be `route.ts` or `route.js`.
|
||||
|
||||
Each route file exports API Route handler functions for at least one HTTP method (`GET`, `POST`, `DELETE`, etc…).
|
||||
Each file exports API Route handler functions for at least one HTTP method (`GET`, `POST`, `DELETE`, etc…).
|
||||
|
||||
For example, to create a `GET` API Route at `/store/hello-world`, create the file `src/api/store/hello-world/route.ts` with the following content:
|
||||
|
||||
@@ -58,6 +58,6 @@ curl http://localhost:9000/store/hello-world
|
||||
|
||||
<Note title="Use API routes when" type="success">
|
||||
|
||||
- You're exposing custom functionality to be used in the admin dashboard or an external application, such as a storefront.
|
||||
- You're exposing custom functionality to be used by a storefront, admin dashboard, or any external application.
|
||||
|
||||
</Note>
|
||||
@@ -18,7 +18,7 @@ Refer to [this reference](!resources!/commerce-modules) for a full list of comme
|
||||
|
||||
## Resolve Commerce Module Services
|
||||
|
||||
Similarly to your custom module, a commerce module's main service is registered in the Medusa container. So, you can resolve it in your resources, such as API route, to use its functionality.
|
||||
Similarly to your custom module, a commerce module's main service is registered in the Medusa container. So, you can resolve it in your resources, such as API routes, to use its functionality.
|
||||
|
||||
For example, you saw this code snippet in the [Medusa container chapter](../medusa-container/page.mdx):
|
||||
|
||||
|
||||
@@ -12,17 +12,17 @@ A data model is a class that represents a table in the database. It's created in
|
||||
|
||||
---
|
||||
|
||||
## How to Create a Data Model
|
||||
## How to Create a Data Model?
|
||||
|
||||
<Note title="Steps Summary">
|
||||
|
||||
1. Create data model class in a module.
|
||||
2. Generate migration for the data model.
|
||||
4. Run migration to add table for data model in the database.
|
||||
1. Create a data model in a module.
|
||||
2. Create migration for the data model.
|
||||
4. Run migration to add the data model's table in the database.
|
||||
|
||||
</Note>
|
||||
|
||||
A data model is created in a TypeScript or JavaScript file under a module's `models` directory. It's defined using the `model` utility imported from `@medjusajs/utils`.
|
||||
A data model is created in a TypeScript or JavaScript file under a module's `models` directory. It's defined using the `model` utility imported from `@medusajs/utils`.
|
||||
|
||||
For example, create the file `src/modules/hello/models/my-custom.ts` with the following content:
|
||||
|
||||
@@ -48,8 +48,6 @@ The example above defines the data model `MyCustom` with the properties `id` and
|
||||
|
||||
A migration defines changes to be made in the database, such as create or update tables.
|
||||
|
||||
So, you must create a migration that creates a table for your data model in the database.
|
||||
|
||||
A migration is a class created in a TypeScript or JavaScript file under a module's `migrations` directory. It has two methods:
|
||||
|
||||
- The `up` method reflects changes on the database.
|
||||
@@ -74,6 +72,15 @@ A migration is a class created in a TypeScript or JavaScript file under a module
|
||||
})
|
||||
```
|
||||
|
||||
<Note title="Important">
|
||||
|
||||
The `databaseName`'s value is only used to generate the migrations. So, make sure it:
|
||||
|
||||
1. Is unique to the module. Two modules shouldn't have the same database name, and it shouldn't be the same as the Medusa application.
|
||||
2. Doesn't change between migrations, as that causes inconsistencies between the migrations.
|
||||
|
||||
</Note>
|
||||
|
||||
2. Run the following command in the root directory of your Medusa application:
|
||||
|
||||
```bash
|
||||
@@ -95,7 +102,7 @@ For example:
|
||||
```ts title="src/modules/migrations/Migration20240429090012.ts"
|
||||
import { Migration } from "@mikro-orm/migrations"
|
||||
|
||||
export class Migration20240624145652 extends Migration {
|
||||
export class Migration20240702105919 extends Migration {
|
||||
|
||||
async up(): Promise<void> {
|
||||
this.addSql("create table if not exists \"my_custom\" (\"id\" text not null, \"name\" text not null, \"created_at\" timestamptz not null default now(), \"updated_at\" timestamptz not null default now(), \"deleted_at\" timestamptz null, constraint \"my_custom_pkey\" primary key (\"id\"));")
|
||||
@@ -120,7 +127,7 @@ The queries performed in each of the methods use PostgreSQL syntax.
|
||||
|
||||
To reflect the changes in the migration, run the `migration` command:
|
||||
|
||||
```bash npm2yarn
|
||||
```bash
|
||||
npx medusa migrations run
|
||||
```
|
||||
|
||||
|
||||
@@ -14,9 +14,11 @@ When an action is performed in Medusa, such as creating a product, the Medusa ap
|
||||
|
||||
## What is a Subscriber?
|
||||
|
||||
A subscriber is a function executed whenever its associated event is emitted.
|
||||
A subscriber is a function executed whenever the event it listens to is emitted.
|
||||
|
||||
The subscriber is created in a TypeScript or JavaScript file under the `src/subscribers` directory.
|
||||
### How to Create a Subscriber?
|
||||
|
||||
A subscriber is created in a TypeScript or JavaScript file under the `src/subscribers` directory.
|
||||
|
||||
For example, create the file `src/subscribers/product-created.ts` with the following content:
|
||||
|
||||
@@ -36,13 +38,32 @@ export const config: SubscriberConfig = {
|
||||
|
||||
A subscriber file must export:
|
||||
|
||||
- The subscriber function that is an asynchronous function executed whenever the associated event is triggered.
|
||||
- A subscriber function that is an asynchronous function executed whenever the associated event is triggered.
|
||||
- A configuration object defining the event this subscriber is listening to.
|
||||
|
||||
The above subscriber listens to the `product.created` event. Whenever the event is emitted, it logs in the terminal `A product is created`.
|
||||
|
||||
---
|
||||
|
||||
## Test the Subscriber
|
||||
|
||||
To test the subscriber, start the Medusa application:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Then, go to the Medusa Admin at `localhost:9000/app` and create a product. You’ll see the following messages logged in the Medusa application's terminal:
|
||||
|
||||
```bash
|
||||
info: Processing product.created which has 1 subscribers
|
||||
A product was created
|
||||
```
|
||||
|
||||
The first message indicates that the `product.created` event was emitted, and the second one is the message logged from the subscriber.
|
||||
|
||||
---
|
||||
|
||||
## When to Use Subscribers
|
||||
|
||||
<Note title="Use subscribers when" type="success">
|
||||
@@ -59,16 +80,10 @@ The subscriber function accepts an object parameter with the property `container
|
||||
|
||||
For example:
|
||||
|
||||
{/* TODO change how event names are loaded */}
|
||||
|
||||
export const highlights = [
|
||||
["10", "container", "Recieve the Medusa Container in the object parameter."],
|
||||
["13", "resolve", "Resolve the Product Module's main service."],
|
||||
[
|
||||
"13",
|
||||
"ModuleRegistrationName.PRODUCT",
|
||||
"The resource registration name imported from `@medusajs/modules-sdk`.",
|
||||
],
|
||||
["13", "ModuleRegistrationName.PRODUCT", "The module's registration name imported from `@medusajs/modules-sdk`."]
|
||||
]
|
||||
|
||||
```ts title="src/subscribers/product-created.ts" highlights={highlights}
|
||||
@@ -79,12 +94,15 @@ import { ModuleRegistrationName } from "@medusajs/utils"
|
||||
export default async function productCreateHandler({
|
||||
data,
|
||||
container,
|
||||
}: SubscriberArgs<Record<string, string>>) {
|
||||
const productModuleService: IProductModuleService = container.resolve(
|
||||
ModuleRegistrationName.PRODUCT
|
||||
)
|
||||
}: SubscriberArgs<{ id: string }>) {
|
||||
const productModuleService: IProductModuleService =
|
||||
container.resolve(ModuleRegistrationName.PRODUCT)
|
||||
|
||||
const product = await productModuleService.retrieve(data.id)
|
||||
const productId = "data" in data ? data.data.id : data.id
|
||||
|
||||
const product = await productModuleService.retrieveProduct(
|
||||
productId
|
||||
)
|
||||
|
||||
console.log(`The product ${product.title} was created`)
|
||||
}
|
||||
|
||||
@@ -8,9 +8,7 @@ In this chapter, you’ll learn about loaders and how to use them.
|
||||
|
||||
## What is a Loader?
|
||||
|
||||
A loader is a function executed when the Medusa application starts.
|
||||
|
||||
A module can define loaders to execute on application start-up.
|
||||
A loader is a function executed when the Medusa application starts. You define and export it in a module.
|
||||
|
||||
---
|
||||
|
||||
@@ -30,25 +28,23 @@ export default function helloWorldLoader() {
|
||||
|
||||
### Export Loader in Module Definition
|
||||
|
||||
You must export your loaders in the module definition.
|
||||
|
||||
To do that, import the loader in `src/modules/hello/index.ts` and export it in the module's definition:
|
||||
Import the loader in `src/modules/hello/index.ts` and export it in the module's definition:
|
||||
|
||||
```ts title="src/modules/hello/index.ts"
|
||||
// other imports...
|
||||
import helloWorldLoader from "./loaders/hello-world"
|
||||
|
||||
// ...
|
||||
|
||||
export default {
|
||||
export default Module("hello", {
|
||||
// ...
|
||||
loaders: [helloWorldLoader],
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
The value of the `loaders` property is an array of loader functions.
|
||||
|
||||
### Test Loader
|
||||
---
|
||||
|
||||
## Test the Loader
|
||||
|
||||
Start the Medusa application:
|
||||
|
||||
@@ -75,6 +71,6 @@ Among the messages logged in the terminal, you’ll see the following message:
|
||||
|
||||
<Note title="Don't use loaders if" type="error">
|
||||
|
||||
- You want to perform an action continuously or at a set time pattern in the application. Use scheduled jobs instead, which is explained in the next chapter.
|
||||
- You want to perform an action continuously or at a set time pattern in the application. Use scheduled jobs instead, which is explained in an upcoming chapter.
|
||||
|
||||
</Note>
|
||||
@@ -33,7 +33,8 @@ export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||
ModuleRegistrationName.PRODUCT
|
||||
)
|
||||
|
||||
const [, count] = await productModuleService.listAndCount()
|
||||
const [, count] = await productModuleService
|
||||
.listAndCountProducts()
|
||||
|
||||
res.json({
|
||||
count,
|
||||
|
||||
@@ -14,7 +14,7 @@ Use modules to customize or develop commerce and architectural features in your
|
||||
|
||||
---
|
||||
|
||||
## How to Create a Module
|
||||
## How to Create a Module?
|
||||
|
||||
<Note title="Steps Summary">
|
||||
|
||||
@@ -28,7 +28,7 @@ Modules are created in a sub-directory of `src/modules`.
|
||||
|
||||
For example, create the directory `src/modules/hello`.
|
||||
|
||||
### 1. Create a Service
|
||||
### 1. Create Main Service
|
||||
|
||||
A module must define a service. A service is a TypeScript or JavaScript class holding methods related to a business logic or commerce functionality.
|
||||
|
||||
@@ -46,21 +46,27 @@ export default class HelloModuleService {
|
||||
|
||||
A module must have an `index.ts` file in its root directory that exports its definition. The definition specifies the main service of the module.
|
||||
|
||||
For example, create the file `src/modules/hello.index.ts` with the following content:
|
||||
For example, create the file `src/modules/hello/index.ts` with the following content:
|
||||
|
||||
```ts title="src/modules/hello.index.ts" highlights={[["4", "", "The main service of the module."]]}
|
||||
```ts title="src/modules/hello.index.ts" highlights={[["5", "", "The main service of the module."]]}
|
||||
import HelloModuleService from "./service"
|
||||
import { Module } from "@medusajs/utils"
|
||||
|
||||
export default {
|
||||
export default Module("hello", {
|
||||
service: HelloModuleService,
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
You use the `Module` function imported from `@medusajs/utils` to create the module definition. It requires two parameters:
|
||||
|
||||
1. The module's name.
|
||||
2. An object with a required property `service` indicating the module's main service.
|
||||
|
||||
### 3. Add Module to Configurations
|
||||
|
||||
The last step is to add the module in Medusa’s configurations.
|
||||
|
||||
In `medusa-config.js`, add the module to the `modules` object:
|
||||
In `medusa-config.js`, add a `modules` property and pass to it your custom module:
|
||||
|
||||
```js title="medusa-config.js" highlights={[["4", "helloModuleService", "The key of the main service to be registered in the Medusa container."]]}
|
||||
module.exports = defineConfig({
|
||||
@@ -75,23 +81,25 @@ module.exports = defineConfig({
|
||||
|
||||
Its key (`helloModuleService`) is the name of the module’s main service. It will be registered in the Medusa container with that name.
|
||||
|
||||
Its value is an object having the `resolve` property, whose value is either a path to module's directory (relative to `src`, so it shouldn't include `src` in the path) or an `npm` package’s name.
|
||||
Its value is an object having the `resolve` property, whose value is either a path to module's directory relative to `src`(it shouldn't include `src` in the path), or an `npm` package’s name.
|
||||
|
||||
### 4. Test the Module
|
||||
---
|
||||
|
||||
## Test the Module
|
||||
|
||||
Since the module's main service is registered in the Medusa container, you can resolve it in other resources to use its functionalities.
|
||||
|
||||
One way to test the module is to create the API route `src/api/store/custom/route.ts` with the following content:
|
||||
For example, create the API route `src/api/store/custom/route.ts` with the following content:
|
||||
|
||||
```ts title="src/api/store/custom/route.ts"
|
||||
import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
|
||||
import HelloService from "../../../modules/hello/service"
|
||||
import HelloModuleService from "../../../modules/hello/service"
|
||||
|
||||
export async function GET(
|
||||
req: MedusaRequest,
|
||||
res: MedusaResponse
|
||||
): Promise<void> {
|
||||
const helloModuleService: HelloService = req.scope.resolve(
|
||||
const helloModuleService: HelloModuleService = req.scope.resolve(
|
||||
"helloModuleService"
|
||||
)
|
||||
|
||||
@@ -128,7 +136,6 @@ You’ll receive the following response:
|
||||
<Note title="Use modules when" type="success">
|
||||
|
||||
- You're implementing a custom commerce feature. For example, you're implementing digital products.
|
||||
- You want to extend data models in other commerce modules, such as adding a field or a relation to the `Product` model.
|
||||
- You want to re-use your custom commerce functionalities across Medusa applications or use them in other environments, such as Edge functions and Next.js apps.
|
||||
|
||||
</Note>
|
||||
@@ -4,11 +4,11 @@ export const metadata = {
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In the next chapters, you’ll learn about the basic concepts of Medusa. These concepts are central to your Medusa development.
|
||||
In the next chapters, you’ll learn about the basic concepts of Medusa that are central in your development.
|
||||
|
||||
By the end of these chapter, you’ll be able to:
|
||||
|
||||
- Expose your custom functionalities through REST APIs.
|
||||
- Expose your custom functionalities through endpoints.
|
||||
- Create custom modules that define custom business logic.
|
||||
- Create custom data models.
|
||||
- Execute scripts when the Medusa application starts.
|
||||
|
||||
+5
-4
@@ -1,10 +1,10 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Important Directories and Files`,
|
||||
title: `${pageNumber} Project Directories and Files`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this chapter, you’ll learn about important directories and files in your Medusa application's codebase.
|
||||
In this chapter, you’ll learn about important directories and files in your Medusa application's project.
|
||||
|
||||
## src
|
||||
|
||||
@@ -13,10 +13,11 @@ This directory is the central place for your custom development. It includes the
|
||||
- `admin`: Holds your admin dashboard's custom components and pages.
|
||||
- `api`: Holds your custom API routes that are added as endpoints in your Medusa application.
|
||||
- `jobs`: Holds your scheduled jobs that run at a specified interval during your Medusa application's runtime.
|
||||
- `loaders`: Holds your loaders that run at the Medusa application's start-up.
|
||||
- `modules`: Holds your custom modules that implement custom business logic.
|
||||
- `scripts`: Holds your custom scripts to be executed using Medusa's CLI tool.
|
||||
- `subscribers`: Holds your event listeners that are executed asynchronously whenever an event is emitted.
|
||||
- `workflows`: Holds your custom flows that can be executed from anywhere in your application.
|
||||
|
||||
## medusa-config.js
|
||||
|
||||
This file holds your Medusa configurations, such as your PostgreSQL database configurations or your Medusa Admin plugin configurations.
|
||||
This file holds your Medusa configurations, such as your PostgreSQL database configurations.
|
||||
@@ -28,7 +28,7 @@ export default function () {
|
||||
|
||||
// the job's configurations
|
||||
export const config = {
|
||||
name: "hello-world",
|
||||
name: "every-minute-message",
|
||||
// execute every minute
|
||||
schedule: "* * * * *",
|
||||
}
|
||||
@@ -37,10 +37,10 @@ export const config = {
|
||||
|
||||
A scheduled job file must export:
|
||||
|
||||
- The function to be executed whenever it’s time to run the scheduled job.
|
||||
- A function to be executed whenever it’s time to run the scheduled job.
|
||||
- A configuration object defining the job. It has two properties:
|
||||
- `name`: a unique name for the job.
|
||||
- `schedule`: a [cron expression](https://crontab.guru/).
|
||||
- `schedule`: a [cron expression](https://crontab.guru/) specifying when to run the job.
|
||||
|
||||
This scheduled job executes every minute and logs into the terminal `Time to say hello world!`.
|
||||
|
||||
@@ -81,13 +81,13 @@ Time to say hello world!
|
||||
|
||||
## Resolve Resources
|
||||
|
||||
The scheduled job function receives an object parameter that has a `container` property. Its value is the Medusa container, which you can use to resolve resources in your Medusa application, such as services.
|
||||
The scheduled job function receives a `container` parameter, which is the Medusa container. Use it to resolve resources in your Medusa application, such as services.
|
||||
|
||||
For example:
|
||||
|
||||
export const highlights = [
|
||||
["11", "resolve", "Resolve the Product Module's main service."],
|
||||
["11", "ModuleRegistrationName.PRODUCT", "The resource registration name imported from `@medusajs/modules-sdk`."]
|
||||
["11", "ModuleRegistrationName.PRODUCT", "The module's registration name imported from `@medusajs/modules-sdk`."]
|
||||
]
|
||||
|
||||
```ts title="src/jobs/hello-world.ts" highlights={highlights}
|
||||
@@ -111,7 +111,7 @@ export default async function myCustomJob(
|
||||
}
|
||||
|
||||
export const config = {
|
||||
name: "hello-world",
|
||||
name: "every-minute-message",
|
||||
// execute every minute
|
||||
schedule: "* * * * *",
|
||||
}
|
||||
|
||||
@@ -12,11 +12,11 @@ In this chapter, you’ll learn about workflows and how to define and execute th
|
||||
|
||||
A workflow is a series of queries and actions that complete a task.
|
||||
|
||||
You construct a workflow similar to how you create a JavaScript function, but unlike regular functions, a workflow creates an internal representation of your steps. This makes it possible to keep track of your Workflow’s progress, automatically retry failing steps, and roll back steps.
|
||||
You construct a workflow similar to how you create a JavaScript function, but unlike regular functions, a workflow creates an internal representation of your steps. This makes it possible to keep track of your workflow’s progress, automatically retry failing steps, and roll back steps.
|
||||
|
||||
---
|
||||
|
||||
## How to Create and Execute a Workflow
|
||||
## How to Create and Execute a Workflow?
|
||||
|
||||
### 1. Create the Steps
|
||||
|
||||
@@ -34,7 +34,9 @@ const step1 = createStep("step-1", async () => {
|
||||
|
||||
This creates one step that returns a hello message.
|
||||
|
||||
Steps can accepts input parameters. For example:
|
||||
Steps can accept input parameters.
|
||||
|
||||
For example, add the following to `src/workflows/hello-world.ts`:
|
||||
|
||||
```ts title="src/workflows/hello-world.ts"
|
||||
type WorkflowInput = {
|
||||
@@ -48,7 +50,7 @@ const step2 = createStep("step-2", async ({ name }: WorkflowInput) => {
|
||||
|
||||
### 2. Create a Workflow
|
||||
|
||||
Next, create the workflow using the `createWorkflow` function:
|
||||
Next, add the following to the same file to create the workflow using the `createWorkflow` function:
|
||||
|
||||
```ts title="src/workflows/hello-world.ts"
|
||||
import {
|
||||
@@ -93,7 +95,7 @@ To execute the workflow, invoke it passing the Medusa container as a parameter.
|
||||
<CodeTabs group="resource-types">
|
||||
<CodeTab label="API Route" value="api-route">
|
||||
|
||||
```ts title="src/api/store/workflow/route.ts" highlights={[["11"], ["12"], ["13"], ["14"], ["15"], ["16"]]}
|
||||
```ts title="src/api/store/workflow/route.ts" highlights={[["11"], ["12"], ["13"], ["14"], ["15"], ["16"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -118,23 +120,30 @@ To execute the workflow, invoke it passing the Medusa container as a parameter.
|
||||
</CodeTab>
|
||||
<CodeTab label="Subscriber" value="subscriber">
|
||||
|
||||
```ts title="src/subscribers/customer-created.ts" highlights={[["13"], ["14"], ["15"], ["16"], ["17"], ["18"]]}
|
||||
```ts title="src/subscribers/customer-created.ts" highlights={[["20"], ["21"], ["22"], ["23"], ["24"], ["25"]]} collapsibleLines="1-9" expandButtonLabel="Show Imports"
|
||||
import {
|
||||
type SubscriberConfig,
|
||||
type SubscriberArgs,
|
||||
CustomerService,
|
||||
Customer,
|
||||
} from "@medusajs/medusa"
|
||||
import myWorkflow from "../workflows/hello-world"
|
||||
import { ModuleRegistrationName } from "@medusajs/utils"
|
||||
import { IUserModuleService } from "@medusajs/types"
|
||||
|
||||
export default async function handleCustomerCreate({
|
||||
data,
|
||||
container,
|
||||
}: SubscriberArgs<Customer>) {
|
||||
}: SubscriberArgs<{ id: string }>) {
|
||||
const userId = "data" in data ? data.data.id : data.id
|
||||
const userModuleService: IUserModuleService = container.resolve(
|
||||
ModuleRegistrationName.USER
|
||||
)
|
||||
|
||||
const user = await userModuleService.retrieveUser(userId)
|
||||
|
||||
const { result } = await myWorkflow(container)
|
||||
.run({
|
||||
input: {
|
||||
name: data.first_name,
|
||||
name: user.first_name,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -142,7 +151,7 @@ To execute the workflow, invoke it passing the Medusa container as a parameter.
|
||||
}
|
||||
|
||||
export const config: SubscriberConfig = {
|
||||
event: CustomerService.Events.CREATED,
|
||||
event: "user.created",
|
||||
}
|
||||
```
|
||||
|
||||
@@ -205,7 +214,7 @@ You’ll receive the following response:
|
||||
|
||||
- You're defining a flow with interactions across multiple systems and services.
|
||||
- You're defining flows to be used across different resources. For example, if you want to invoke the flow manually through an API Router, but also want to automate its running through a scheduled job.
|
||||
- You want to define how the series of actions are rolled-back when an error occurs.
|
||||
- You want to define configurations related to errors and how to roll-back steps. This is explained more in later chapters.
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -240,10 +249,12 @@ type WorkflowOutput = {
|
||||
}
|
||||
|
||||
const step1 = createStep("step-1", async (_, context) => {
|
||||
const productModuleService: IProductModuleService = context.container.resolve(
|
||||
ModuleRegistrationName.PRODUCT
|
||||
)
|
||||
return new StepResponse((await productModuleService.listAndCount())[1])
|
||||
const productModuleService: IProductModuleService =
|
||||
context.container.resolve(ModuleRegistrationName.PRODUCT)
|
||||
|
||||
const [, count] = await productModuleService.listAndCountProducts()
|
||||
|
||||
return new StepResponse(count)
|
||||
})
|
||||
|
||||
const myWorkflow = createWorkflow<unknown, WorkflowOutput>(
|
||||
|
||||
Reference in new issue
Block a user