docs: fixes and changes based on latest updates (#7322)

* docs: changes based on DX changes

* remove fields no longer needed

* remove unnecessary parameters

* fixes to authenticate middleware usage

* add highlight to migrations config

* change configuration to http

* added missing remote link docs

* fix name in sidebar

* added notification module docs + updated file module docs

* add vale exceptions

* fix vale errors

* added docs on custom cli scripts
This commit is contained in:
Shahed Nasser
2024-05-22 13:37:48 +03:00
committed by GitHub
parent ff5d573887
commit 154673f3d8
55 changed files with 1674 additions and 3791 deletions
+17 -1
View File
@@ -6,6 +6,22 @@ export const metadata = {
# {metadata.title}
Learn how to create a cache module in [this guide](./create/page.mdx).
A Cache Module is used to cache the results of computations such as price selection or various tax calculations.
The underlying database, third-party service, or caching logic is flexible since it's implemented in a module. You can choose from Medusas cache modules or create your own to support something more suitable for your architecture.
---
## List of Cache Modules
By default, Medusa uses the In-Memory Cache Module. This module uses a plain JavaScript Map object to store the cache data.
This is useful for development. However, for production, it's highly recommended to use other Cache Modules, such as the Redis Cache Module.
<ChildDocs type="item" filters={["Guides"]} onlyTopLevel={true} />
---
## Create a Cache Module
To create a cache module, refer to [this guide](./create/page.mdx).
@@ -6,6 +6,22 @@ export const metadata = {
# {metadata.title}
Learn how to create a event module in [this guide](./create/page.mdx).
An Event Module implements the underlying publish/subscribe system that handles queueing events, emitting them, and executing their subscribers.
This makes the event architecture customizable, as you can either choose one of Medusas event modules or create your own.
---
## List of Event Modules
By default, Medusa uses the Local Event Module. This module uses Nodes EventEmitter to implement the publish/subscribe system.
This is useful for development. However, for production, its highly recommended to use other Event Modules, Redis Event Module.
<ChildDocs type="item" filters={["Guides"]} onlyTopLevel={true} />
---
## Create a Event Module
To create an event module, refer to [this guide](./create/page.mdx).
@@ -6,6 +6,22 @@ export const metadata = {
# {metadata.title}
Learn how to create a file provider module in [this guide](/references/file-provider-module).
A File Module exposes the functionalities to upload assets, such as product images, to the Medusa application.
---
## What is a File Provider Module?
A file provider module implements the logic of handling uploads and downloads. The File Module must have one file provider module configured.
By default, Medusa uses the Local File Module. This module uploads files to the `uploads` directory of your Medusa application.
This is useful for development. However, for production, its highly recommended to use other File Modules, such as the S3 Module.
<ChildDocs type="item" filters={["Guides"]} onlyTopLevel={true} />
---
## Create a File Provider Module
To create a file provider module, refer to [this guide](/references/file-provider-module).
@@ -0,0 +1,311 @@
import { Table, Tabs, TabsList, TabsContent, TabsContentWrapper, TabsTrigger } from "docs-ui"
export const metadata = {
title: `S3 File Provider Module`,
}
# {metadata.title}
The S3 File Provider Module integrates Amazon S3 and services following a compatible API (such as MinIO or DigitalOcean Spaces) to store files uploaded to your Medusa application.
---
## Prerequisites
<Tabs defaultValue="aws">
<TabsList>
<TabsTrigger value="aws">AWS S3</TabsTrigger>
<TabsTrigger value="minio">MinIO</TabsTrigger>
<TabsTrigger value="spaces">DigitalOcean Spaces</TabsTrigger>
</TabsList>
<TabsContentWrapper>
<TabsContent value="aws">
- [AWS account](https://console.aws.amazon.com/console/home?nc2=h_ct&src=header-signin).
- [S3 bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-bucket-overview.html) with the "Public Access setting" enabled.
- [AWS user with AmazonS3FullAccess permissions](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-and-attach-iam-policy.html).
- [AWS user access key ID and secret access key](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html#Using_CreateAccessKey).
- Change your [bucket's policy](https://docs.aws.amazon.com/AmazonS3/latest/userguide/add-bucket-policy.html) to the following:
```json
{
"Version": "2012-10-17",
"Id": "Policy1397632521960",
"Statement": [
{
"Sid": "Stmt1397633323327",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::{bucket_name}/*"
}
]
}
```
Make sure to replace `{bucket_name}` with the name of the bucket you created.
</TabsContent>
<TabsContent value="minio">
- [Install MinIO](https://min.io/docs/minio/linux/index.html).
- Change port to `9001` using the [console address](https://min.io/docs/minio/linux/reference/minio-server/minio-server.html#minio.server.-console-address) and [address](https://min.io/docs/minio/linux/reference/minio-server/minio-server.html#minio.server.-address) CLI options.
- [MinIO bucket with public access policy](https://min.io/docs/minio/linux/administration/console/managing-objects.html#creating-buckets).
- [MinIO access and secret access key](https://min.io/docs/minio/linux/administration/console/security-and-access.html#id1).
</TabsContent>
<TabsContent value="spaces">
- [DigitalOcean account](https://cloud.digitalocean.com/registrations/new).
- [DigitalOcean Spaces bucket](https://docs.digitalocean.com/products/spaces/how-to/create/).
- [DigitalOcean Spaces access and secret access keys](https://docs.digitalocean.com/products/spaces/how-to/manage-access/#access-keys).
</TabsContent>
</TabsContentWrapper>
</Tabs>
---
## Install the S3 File Module
To install the S3 File Provider Module, run the following command in the directory of your Medusa application:
```bash npm2yarn
npm install @medusajs/file-s3
```
Next, add the module into the `providers` array of the File Module:
<Note>
The File Module accepts one provider only.
</Note>
```js title="medusa-config.js"
module.exports = {
// ...
modules: {
// ...
[Modules.FILE]: {
resolve: "@medusajs/file",
options: {
providers: [
{
resolve: "@medusajs/file-s3",
options: {
config: {
s3: {
file_url: process.env.S3_FILE_URL,
access_key_id: process.env.S3_ACCESS_KEY_ID,
secret_access_key: process.env.S3_SECRET_ACCESS_KEY,
region: process.env.S3_REGION,
bucket: process.env.S3_BUCKET,
endpoint: process.env.S3_ENDPOINT,
// other options...
},
},
},
},
],
},
},
},
}
```
### S3 File Module Options
<Table>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Option</Table.HeaderCell>
<Table.HeaderCell>Description</Table.HeaderCell>
<Table.HeaderCell>Default</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>
`file_url`
</Table.Cell>
<Table.Cell>
The base URL to upload files to.
- For AWS S3, the endpoint is of the format `https://{bucket}.s3.{region}.amazonaws.com`
- For MinIO, it's the URL to the MinIO server.
- For DigitalOcean Spaces, it's either the Origin Endpoint or the CDN endpoint of your Spaces Object Storage bucket.
</Table.Cell>
<Table.Cell>
\-
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
`access_key_id`
</Table.Cell>
<Table.Cell>
The AWS or (S3 compatible) user's access key ID.
</Table.Cell>
<Table.Cell>
\-
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
`secret_access_key`
</Table.Cell>
<Table.Cell>
The AWS or (S3 compatible) user's secret access key.
</Table.Cell>
<Table.Cell>
\-
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
`region`
</Table.Cell>
<Table.Cell>
The bucket's region code.
</Table.Cell>
<Table.Cell>
\-
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
`bucket`
</Table.Cell>
<Table.Cell>
The bucket's name.
</Table.Cell>
<Table.Cell>
\-
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
`endpoint`
</Table.Cell>
<Table.Cell>
The URL to the AWS S3 (or compatible S3 API) server.
- For AWS S3, the endpoint is of the format `{bucket}.s3.{region}.amazonaws.com`
- For MinIO, it's the URL to the MinIO server.
- For DigitalOcean Spaces, it's the Spaces Origin Endpoint.
</Table.Cell>
<Table.Cell>
\-
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
`prefix`
</Table.Cell>
<Table.Cell>
A string to prefix each uploaded file's name.
</Table.Cell>
<Table.Cell>
\-
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
`cache_control`
</Table.Cell>
<Table.Cell>
A string indicating how long objects remain in the AWS S3 (or compatible S3 API) cache.
</Table.Cell>
<Table.Cell>
`public, max-age=31536000`
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
`download_file_duration`
</Table.Cell>
<Table.Cell>
A number indicating the expiry time of presigned URLs in seconds.
</Table.Cell>
<Table.Cell>
`3600` (An hour)
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
`additional_client_config`
</Table.Cell>
<Table.Cell>
Any additional configurations to pass to the S3 client.
Refer to [this AWS API reference](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Config.html) for a full list of accepted configuration.
</Table.Cell>
<Table.Cell>
\-
</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
@@ -0,0 +1,80 @@
import { Table } from "docs-ui"
export const metadata = {
title: `Local Notification Provider Module`,
}
# {metadata.title}
The Local Notification Provider Module simulates sending a notification, but only logs the notification's details in the terminal. This is useful for development.
---
## Install the Local Notification Module
To install the Local Notification Provider Module, run the following command in the directory of your Medusa application:
```bash npm2yarn
npm install @medusajs/notification-local
```
Next, add the module into the `providers` array of the Notification Module:
<Note>
Only one provider can be defined for a channel.
</Note>
```js title="medusa-config.js"
module.exports = {
// ...
modules: {
// ...
[Modules.NOTIFICATION]: {
resolve: "@medusajs/notification",
options: {
providers: [
// ...
{
resolve: "@medusajs/notification-local",
options: {
config: {
local: {
channels: ["email"]
},
},
},
},
],
},
},
},
}
```
### Local Notification Module Options
<Table>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Option</Table.HeaderCell>
<Table.HeaderCell>Description</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>
`channels`
</Table.Cell>
<Table.Cell>
The channels this notification module is used to send notifications for. While the local notification module doesn't actually send the notification,
it's important to specify its channels to make sure it's used when a notification for that channel is created.
</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
@@ -0,0 +1,66 @@
import { ChildDocs } from "docs-ui"
export const metadata = {
title: `Notification Provider Modules`,
}
# {metadata.title}
A Notification Module exposes the functionalities to send a notification to a customer or user. For example, sending an order confirmation email.
You can resolve the Notification Module and send notifications in API routes, subscribers, or other resources.
---
## What is a Notification Provider Module?
A notification provider module implements the logic of sending the notification. It either integrates a third-party service or uses custom logic to send the notification.
By default, Medusa uses the Local Notification Module which only simulates sending the notification by logging a message in the terminal.
Medusa provides other Notification Modules that actually send notifications, such as the SendGrid Notification Provider Module.
<ChildDocs type="item" filters={["Guides"]} onlyTopLevel={true} />
---
## Notification Provider Module Channels
When you send a notification, you specify the channel to send it through, such as `email` or `sms`. Each provider defined in the Notification Module's `providers` option has a `channels` option specifying which channels it can be used in. Only one provider can be setup for each channel.
For example:
```js title="medusa-config.js" highlights={[["15"]]}
module.exports = {
// ...
modules: {
// ...
[Modules.NOTIFICATION]: {
resolve: "@medusajs/notification",
options: {
providers: [
// ...
{
resolve: "@medusajs/notification-local",
options: {
config: {
local: {
channels: ["email"]
},
},
},
},
],
},
},
},
}
```
The `channels` option is an array of strings indicating the channels this provider is used for.
---
## Create a Notification Provider Module
To create a notification provider module, refer to [this guide](/references/notification-provider-module).
@@ -0,0 +1,86 @@
import { TypeList } from "docs-ui"
export const metadata = {
title: `Send Notification with the Notification Module`,
}
# {metadata.title}
In this guide, you'll learn how to send a notification using the Notification Module.
## Use the Create Method
In your resource, such as a subscriber, resolve the Notification Module's main service and use its `create` method:
export const highlights = [
["12", "notificationModuleService", "Resolve the Notification Module."],
["17", "create", "Create the notification to be sent."],
["19", '"email"', "Use the provider module defined for the `email` channel to send an email."],
["20", '"product-created"', "The ID of the template defined in the third-party service, such as SendGrid."],
["21", "data", "The data to pass to the template defined in the third-party service."]
]
```ts title="src/subscribers/product-created.ts" highlights={highlights}
import type {
SubscriberArgs,
SubscriberConfig,
} from "@medusajs/medusa"
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { INotificationModuleService } from "@medusajs/types"
export default async function productCreateHandler({
data,
container
}: SubscriberArgs<{ id: string }>) {
const notificationModuleService: INotificationModuleService =
container.resolve(
ModuleRegistrationName.NOTIFICATION
)
await notificationModuleService.create({
to: "shahednasser@gmail.com",
channel: "email",
template: "product-created",
data: "data" in data ? data.data : data
})
}
export const config: SubscriberConfig = {
event: "product.created",
}
```
The `create` method accepts an object or an array of objects having the following properties:
<TypeList
types={[
{
name: "to",
type: "`string`",
description: "The destination to send the notification to. When sending an email, it'll be the email address. When sending an SMS, it'll be the phone number.",
optional: false,
},
{
name: "channel",
type: "`string`",
description: "The channel to send the notification through. For example, `email` or `sms`. The provider module defined for that channel will be used to send the notification.",
optional: false
},
{
name: "template",
type: "`string`",
description: "The ID of the template used for the notification. This is useful for providers like SendGrid, where you define templates within SendGrid and use their IDs here.",
optional: false
},
{
name: "data",
type: "`Record<string, unknown>`",
description: "The data to pass along to the template, if necessary."
}
]}
sectionTitle="Use the Create Method"
/>
{/* TODO add once reference for type once generated */}
{/* For a full list of properties accepted, refer to [this guide](/references/notification-provider-module#create). */}
@@ -0,0 +1,192 @@
import { Table } from "docs-ui"
export const metadata = {
title: `SendGrid Notification Provider Module`,
}
# {metadata.title}
The SendGrid Notification Provider Module integrates [SendGrid](https://sendgrid.com) to send emails to users and customers.
---
## Install the SendGrid Notification Module
<Note type="check">
- [SendGrid account](https://signup.sendgrid.com)
- [Setup SendGrid single sender](https://docs.sendgrid.com/ui/sending-email/sender-verification)
- [SendGrid API Key](https://docs.sendgrid.com/ui/account-and-settings/api-keys)
</Note>
To install the SendGrid Notification Provider Module, run the following command in the directory of your Medusa application:
```bash npm2yarn
npm install @medusajs/notification-sendgrid
```
Next, add the module into the `providers` array of the Notification Module:
<Note>
Only one provider can be defined for a channel.
</Note>
```js title="medusa-config.js"
module.exports = {
// ...
modules: {
// ...
[Modules.NOTIFICATION]: {
resolve: "@medusajs/notification",
options: {
providers: [
// ...
{
resolve: "@medusajs/notification-sendgrid",
options: {
config: {
sendgrid: {
channels: ["email"],
api_key: process.env.SENDGRID_API_KEY,
from: process.env.SENDGRID_FROM
},
},
},
},
],
},
},
},
}
```
### Environment Variables
Make sure to add the following environment variables:
```bash
SENDGRID_API_KEY=<YOUR_SENDGRID_API_KEY>
SENDGRID_FROM=<YOUR_SENDGRID_FROM>
```
### SendGrid Notification Module Options
<Table>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Option</Table.HeaderCell>
<Table.HeaderCell>Description</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>
`channels`
</Table.Cell>
<Table.Cell>
The channels this notification module is used to send notifications for. Only one provider can be defined for a channel.
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
`api_key`
</Table.Cell>
<Table.Cell>
The SendGrid API key.
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
`from`
</Table.Cell>
<Table.Cell>
The SendGrid from email.
</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
---
## SendGrid Templates
When you send a notification, you must specify the ID of the template to use in SendGrid.
Refer to [this SendGrid documentation guide](https://docs.sendgrid.com/ui/sending-email/how-to-send-an-email-with-dynamic-templates) on how to create templates for your different email types.
---
## Test out the Module
To test the module out, create a simple subscriber at `src/subscribers/product-created.ts` with the following content:
export const highlights = [
["12", "notificationModuleService", "Resolve the Notification Module."],
["17", "create", "Create the notification to be sent."],
["19", '"email"', "By specifying the `email` channel, SendGrid will be used to send the notification."],
["20", '"product-created"', "The ID of the template defined in SendGrid."],
["21", "data", "The data to pass to the template defined in SendGrid."]
]
```ts title="src/subscribers/product-created.ts" highlights={highlights}
import type {
SubscriberArgs,
SubscriberConfig,
} from "@medusajs/medusa"
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { INotificationModuleService } from "@medusajs/types"
export default async function productCreateHandler({
data,
container
}: SubscriberArgs<{ id: string }>) {
const notificationModuleService: INotificationModuleService =
container.resolve(
ModuleRegistrationName.NOTIFICATION
)
await notificationModuleService.create({
to: "test@gmail.com",
channel: "email",
template: "product-created",
data: "data" in data ? data.data : data
})
}
export const config: SubscriberConfig = {
event: "product.created",
}
```
In this subscriber:
- Resolve the Notification Module's main service.
- Use the `create` method of the main service to create a notification to be sent to the specified email.
- By specifying the `email` channel, the SendGrid Notification Provider Module is used to send the notification.
- The `template` property of the `create` method's parameter specifies the ID of the template defined in SendGrid.
- The `data` property allows you to pass data to the template in SendGrid.
Then, start the Medusa application:
```bash npm2yarn
npm run dev
```
{/* TODO add links */}
And create a product either using the [API route](!api!/api/admin#products_postproducts) or the Medusa Admin. This runs the subscriber and sends an email using SendGrid.
@@ -0,0 +1,13 @@
import { ChildDocs } from "docs-ui"
export const metadata = {
title: `Workflow Engine Modules`,
}
# {metadata.title}
Workflow engine modules handle tracking and recording the transactions and statuses of workflows and their steps.
Medusa uses the In-Memory Workflow Engine Module by default. For production purposes, it's recommended to use the Redis Engine Module instead.
<ChildDocs type="item" filters={["Guides"]} onlyTopLevel={true} />
@@ -55,9 +55,9 @@ This example uses the [jsonwebtoken NPM package](https://www.npmjs.com/package/j
return
}
const { jwt_secret } =
req.scope.resolve("configModule").projectConfig
const token = jwt.sign(authUser, jwt_secret)
const { jwtSecret } =
req.scope.resolve("configModule").projectConfig.http
const token = jwt.sign(authUser, jwtSecret)
res.status(200).json({ token })
}
@@ -153,9 +153,9 @@ This example uses the [jsonwebtoken NPM package](https://www.npmjs.com/package/j
throw new MedusaError(MedusaError.Types.UNAUTHORIZED, error)
}
const { jwt_secret } =
req.scope.resolve("configModule").projectConfig
const token = jwt.sign(authUser, jwt_secret)
const { jwtSecret } =
req.scope.resolve("configModule").projectConfig.http
const token = jwt.sign(authUser, jwtSecret)
if (successRedirectUrl) {
const url = new URL(successRedirectUrl!)
@@ -227,6 +227,6 @@ GOOGLE_SUCCESS_REDIRECT_URL=<YOUR_GOOGLE_SUCCESS_REDIRECT_URL>
## Auth CORS
The Medusa application's authentication API routes are defined under the `/auth` prefix that requires setting the `auth_cors` configuration. So, before using these routes, make sure to set that configuration.
The Medusa application's authentication API routes are defined under the `/auth` prefix that requires setting the `authCors` property of the `http` configuration. So, before using these routes, make sure to set that configuration.
Refer to [Medusa's configuration guide](/references/medusa-config#auth_cors) for more details.
Refer to [Medusa's configuration guide](/references/medusa-config#authCors) for more details.
@@ -45,10 +45,10 @@ const {
// ...
const {
jwt_secret,
} = req.scope.resolve("configModule").projectConfig
jwtSecret,
} = req.scope.resolve("configModule").projectConfig.http
const token = jwt.sign(authUser, jwt_secret)
const token = jwt.sign(authUser, jwtSecret)
```
Then, the token is passed in the header of subsequent requests in the Authorization Bearer header.
@@ -32,7 +32,7 @@ Make sure the `start` script in your `package.json` runs migrations, the `build`
## Set SSL Database Option
In production, its recommended to set the [database_extra option](/medusa-configurations) in `medusa-config.js` to disable the `ssl.rejectUnauthorized` option:
In production, its recommended to set the [database_extra option](/references/medusa-config#database_extra) in `medusa-config.js` to disable the `ssl.rejectUnauthorized` option:
```js title="medusa-config.js" highlights={[["4"]]}
module.exports = {
@@ -151,7 +151,7 @@ After youve deployed your Medusa application, you can test it out in differen
## Set Up CORS Configuration
To connect your storefront and, if deployed separately, your admin dashboard to your deployed Medusa application, set up the [admin_cors](/medusa-configurations#admin_cors) and [store_cors](/medusa-configurations#store_cors) configurations in `medusa-config.js`.
To connect your storefront and, if deployed separately, your admin dashboard to your deployed Medusa application, set up the [adminCors](/references/medusa-config#adminCors) and [storeCors](/references/medusa-config#storeCors) properties of the `http` configuration in `medusa-config.js`.
---
@@ -561,6 +561,62 @@ npx medusa user --email <email> [--password <password>]
</Table.Body>
</Table>
### exec
Run a custom CLI script. Learn more about it in [this guide](!docs!/advanced-development/custom-cli-scripts).
```bash
npx medusa exec [file] [args...]
```
#### Arguments
<Table>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Argument</Table.HeaderCell>
<Table.HeaderCell>Description</Table.HeaderCell>
<Table.HeaderCell>Required</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>
`file`
</Table.Cell>
<Table.Cell>
The path to a JavaScript file holding the function to execute.
</Table.Cell>
<Table.Cell>
Yes
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>
`args`
</Table.Cell>
<Table.Cell>
A list of arguments to pass to the function. These arguments are passed in the `args` property of the function's object parameter.
</Table.Cell>
<Table.Cell>
No
</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
### start-cluster
Starts the Medusa application in [cluster mode](https://expressjs.com/en/advanced/best-practice-performance.html#run-your-app-in-a-cluster). Running in cluster mode significantly improves performance as the workload and tasks are distributed among all available instances instead of a single one.
@@ -4,7 +4,7 @@ If you're running the Medusa backend through tools like VSCode or GitHub Codespa
- [VSCode local development.](https://code.visualstudio.com/docs/editor/port-forwarding)
- [VSCode remote development.](https://code.visualstudio.com/docs/remote/ssh#_forwarding-a-port-creating-ssh-tunnel)
- [GitHub Codespaces.](https://docs.github.com/en/codespaces/developing-in-a-codespace/forwarding-ports-in-your-codespace)
2. If your tool or IDE exposes an address other than `localhost`, such as `127.0.0.1`, make sure to add that address to the [admin_cors](/references/medusa-config) Medusa configuration. Your tool will show you what the forwarded address is.
2. If your tool or IDE exposes an address other than `localhost`, such as `127.0.0.1`, make sure to add that address to the [adminCors](/references/medusa-config#adminCors) Medusa configuration. Your tool will show you what the forwarded address is.
After setting these configurations, run your Medusa backend and try again. If you couldn't create an admin user before, run the following command in the root directory of your Medusa project to create an admin user:
@@ -22,4 +22,4 @@ npx create-medusa-app@latest --db-url "postgres://user:password@localhost:<YOUR_
Where `<YOUR_PORT>` is the exposed port if it's different than `5432`.
Refer to the [database_url configuration documentation](/medusa-configurations#database_url) to learn how to set the database URL for an installed Medusa backend.
Refer to the [database_url configuration documentation](/references/medusa-config#database_url) to learn how to set the database URL for an installed Medusa backend.
+26 -10
View File
@@ -191,6 +191,26 @@ export const filesMap = [
"filePath": "/www/apps/resources/app/architectural-modules/file/page.mdx",
"pathname": "/architectural-modules/file"
},
{
"filePath": "/www/apps/resources/app/architectural-modules/file/s3/page.mdx",
"pathname": "/architectural-modules/file/s3"
},
{
"filePath": "/www/apps/resources/app/architectural-modules/notification/local/page.mdx",
"pathname": "/architectural-modules/notification/local"
},
{
"filePath": "/www/apps/resources/app/architectural-modules/notification/page.mdx",
"pathname": "/architectural-modules/notification"
},
{
"filePath": "/www/apps/resources/app/architectural-modules/notification/send-notification/page.mdx",
"pathname": "/architectural-modules/notification/send-notification"
},
{
"filePath": "/www/apps/resources/app/architectural-modules/notification/sendgrid/page.mdx",
"pathname": "/architectural-modules/notification/sendgrid"
},
{
"filePath": "/www/apps/resources/app/architectural-modules/page.mdx",
"pathname": "/architectural-modules"
@@ -199,6 +219,10 @@ export const filesMap = [
"filePath": "/www/apps/resources/app/architectural-modules/workflow-engine/in-memory/page.mdx",
"pathname": "/architectural-modules/workflow-engine/in-memory"
},
{
"filePath": "/www/apps/resources/app/architectural-modules/workflow-engine/page.mdx",
"pathname": "/architectural-modules/workflow-engine"
},
{
"filePath": "/www/apps/resources/app/architectural-modules/workflow-engine/redis/page.mdx",
"pathname": "/architectural-modules/workflow-engine/redis"
@@ -6400,16 +6424,8 @@ export const filesMap = [
"pathname": "/references/modules/workflows"
},
{
"filePath": "/www/apps/resources/references/notification/classes/notification.AbstractNotificationService/page.mdx",
"pathname": "/references/notification/classes/notification.AbstractNotificationService"
},
{
"filePath": "/www/apps/resources/references/notification/interfaces/notification.INotificationService/page.mdx",
"pathname": "/references/notification/interfaces/notification.INotificationService"
},
{
"filePath": "/www/apps/resources/references/notification/interfaces/notification.ReturnedData/page.mdx",
"pathname": "/references/notification/interfaces/notification.ReturnedData"
"filePath": "/www/apps/resources/references/notification/classes/notification.AbstractNotificationProviderService/page.mdx",
"pathname": "/references/notification/classes/notification.AbstractNotificationProviderService"
},
{
"filePath": "/www/apps/resources/references/order/IMessageAggregator/methods/order.IMessageAggregator.clearMessages/page.mdx",
+52
View File
@@ -6757,6 +6757,13 @@ export const generatedSidebar = [
"title": "Local",
"children": []
},
{
"loaded": true,
"isPathHref": true,
"path": "/architectural-modules/file/s3",
"title": "AWS S3 (and Compatible APIs)",
"children": []
},
{
"loaded": true,
"isPathHref": true,
@@ -6776,6 +6783,51 @@ export const generatedSidebar = [
{
"loaded": true,
"isPathHref": true,
"path": "/architectural-modules/notification",
"title": "Notification Provider Modules",
"hasTitleStyling": true,
"children": [
{
"loaded": true,
"isPathHref": true,
"path": "/architectural-modules/notification/local",
"title": "Local",
"children": []
},
{
"loaded": true,
"isPathHref": true,
"path": "/architectural-modules/notification/sendgrid",
"title": "SendGrid",
"children": []
},
{
"loaded": true,
"isPathHref": true,
"title": "Guides",
"children": [
{
"loaded": true,
"isPathHref": true,
"path": "/architectural-modules/notification/send-notification",
"title": "Send Notification",
"children": []
},
{
"loaded": true,
"isPathHref": true,
"path": "/references/notification-provider-module",
"title": "Create Notification Module",
"children": []
}
]
}
]
},
{
"loaded": true,
"isPathHref": true,
"path": "/architectural-modules/workflow-engine",
"title": "Workflow Engine Modules",
"hasTitleStyling": true,
"children": [
@@ -1880,9 +1880,9 @@ export const slugChanges = [
"filePath": "/www/apps/resources/references/modules/workflows/page.mdx"
},
{
"origSlug": "/references/notification/classes/notification.AbstractNotificationService",
"newSlug": "/references/notification-service",
"filePath": "/www/apps/resources/references/notification/classes/notification.AbstractNotificationService/page.mdx"
"origSlug": "/references/notification/classes/notification.AbstractNotificationProviderService",
"newSlug": "/references/notification-provider-module",
"filePath": "/www/apps/resources/references/notification/classes/notification.AbstractNotificationProviderService/page.mdx"
},
{
"origSlug": "/references/order/IOrderModuleService/methods/order.IOrderModuleService.addOrderAction",
@@ -99,26 +99,27 @@ The File Module accepts one provider only.
</Note>
```js title="medusa-config.js"
module.exports = {
const { Modules } = require("@medusajs/modules-sdk")
// ...
const modules = {
// ...
modules: {
// ...
[Modules.FILE]: {
resolve: "@medusajs/file",
options: {
providers: [
{
resolve: "./dist/modules/my-file",
options: {
config: {
"my-file": {
// provider options...
},
[Modules.FILE]: {
resolve: "@medusajs/file",
options: {
providers: [
{
resolve: "./dist/modules/my-file",
options: {
config: {
"my-file": {
// provider options...
},
},
},
],
},
},
],
},
},
}
@@ -4,9 +4,4 @@ import { TypeList } from "docs-ui"
## Classes
- [AbstractNotificationService](../../notification/classes/notification.AbstractNotificationService/page.mdx)
## Interfaces
- [ReturnedData](../../notification/interfaces/notification.ReturnedData/page.mdx)
- [INotificationService](../../notification/interfaces/notification.INotificationService/page.mdx)
- [AbstractNotificationProviderService](../../notification/classes/notification.AbstractNotificationProviderService/page.mdx)
@@ -0,0 +1,103 @@
---
slug: /references/notification-provider-module
---
import { TypeList } from "docs-ui"
# How to Create a Notification Provider Module
In this document, youll learn how to create a notification provider module and the methods you must implement in it.
---
## 1. Create Module Directory
Start by creating a new directory for your module. For example, `src/modules/my-notification`.
---
## 2. Create the Notification Provider Service
Create the file `src/modules/my-notification/service.ts` that holds the implementation of the notification service.
The Notification Provider Module's main service must extend the `AbstractNotificationProviderService` class imported from `@medusajs/utils`:
```ts title="src/modules/my-notification/service.ts"
import {
AbstractNotificationProviderService
} from "@medusajs/utils"
class MyNotificationProviderService extends AbstractNotificationProviderService {
// TODO add methods
}
export default MyNotificationProviderService
```
### constructor
### send
#### Parameters
<TypeList types={[{"name":"notification","type":"`ProviderSendNotificationDTO`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]}]} sectionTitle="send"/>
#### Returns
<TypeList types={[{"name":"Promise","type":"Promise&#60;ProviderSendNotificationResultsDTO&#62;","optional":false,"defaultValue":"","description":"","expandable":false,"children":[{"name":"ProviderSendNotificationResultsDTO","type":"`ProviderSendNotificationResultsDTO`","optional":false,"defaultValue":"","description":"","expandable":false,"children":[]}]}]} sectionTitle="send"/>
---
## 3. Create Module Definition File
Create the file `src/modules/my-notification/index.ts` with the following content:
```ts title="src/modules/my-notification/index.ts"
import MyNotificationProviderService from "./service"
export default {
service: MyNotificationProviderService,
}
```
This exports the module's definition, indicating that the `MyNotificationProviderService` is the main service of the module.
---
## 4. Use Module
To use your Notification Provider Module, add it to the `providers` array of the Notification Module:
<Note>
The Notification Module accepts one provider per channel.
</Note>
```js title="medusa-config.js"
const { Modules } = require("@medusajs/modules-sdk")
// ...
const modules = {
// ...
[Modules.NOTIFICATION]: {
resolve: "@medusajs/notification",
options: {
providers: [
{
resolve: "./dist/modules/my-notification",
options: {
config: {
"my-notification": {
channels: ["email"],
// provider options...
},
},
},
},
],
},
},
}
```
@@ -1,287 +0,0 @@
---
slug: /references/notification-service
---
import { TypeList } from "docs-ui"
# How to Create a Notification Provider
In this document, youll learn how to create a notification provider in the Medusa backend and the methods you must implement in it. Learn more about the notification architecture in [this documentation](https://docs.medusajs.com/development/notification/overview)
## Overview
:::note[Prerequisites]
Before creating a Notification Provider, [install an event bus module](https://docs.medusajs.com/development/events/modules/redis).
:::
A Notification Provider is a provider that handles sending and resending of notifications.
To create a Notification Provider, create a TypeScript or JavaScript file in `src/services`. The name of the file is the name of the provider
(for example, `sendgrid.ts`). The file must export a class that extends the `AbstractNotificationService` class imported from `@medusajs/medusa`.
For example, create the file `src/services/email-sender.ts` with the following content:
```ts title="src/services/email-sender.ts"
import { AbstractNotificationService } from "@medusajs/medusa"
import { EntityManager } from "typeorm"
class EmailSenderService extends AbstractNotificationService {
protected manager_: EntityManager
protected transactionManager_: EntityManager
sendNotification(
event: string,
data: unknown,
attachmentGenerator: unknown
): Promise<{
to: string;
status: string;
data: Record<string, unknown>;
}> {
throw new Error("Method not implemented.")
}
resendNotification(
notification: unknown,
config: unknown,
attachmentGenerator: unknown
): Promise<{
to: string;
status: string;
data: Record<string, unknown>;
}> {
throw new Error("Method not implemented.")
}
}
export default EmailSenderService
```
---
## Identifier Property
The `NotificationProvider` entity has 2 properties: `identifier` and `is_installed`. The value of the `identifier` property in the notification provider
class is used when the Notification Provider is created in the database.
The value of this property is also used later when you want to subscribe the Notification Provider to events in a [Loader](https://docs.medusajs.com/development/loaders/overview).
For example:
```ts
class EmailSenderService extends AbstractNotificationService {
static identifier = "email-sender"
// ...
}
```
---
## constructor
You can use the `constructor` of your notification provider to access the different services in Medusa through dependency injection.
You can also use the constructor to initialize your integration with the third-party provider. For example, if you use a client to connect to the third-party providers APIs,
you can initialize it in the constructor and use it in other methods in the service.
Additionally, if youre creating your notification provider as an external plugin to be installed on any Medusa backend and you want to access the options
added for the plugin, you can access it in the constructor.
### Example
```ts
// ...
import { AbstractNotificationService, OrderService } from "@medusajs/medusa"
import { EntityManager } from "typeorm"
class EmailSenderService extends AbstractNotificationService {
// ...
protected orderService: OrderService
constructor(container, options) {
super(container)
// you can access options here in case you're
// using a plugin
this.orderService = container.orderService
// you can also initialize a client that
// communicates with a third-party service.
this.client = new Client(options)
}
// ...
}
export default EmailSenderService
```
### Parameters
<TypeList types={[{"name":"container","type":"`Record<string, unknown>`","description":"An instance of `MedusaContainer` that allows you to access other resources, such as services, in your Medusa backend.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"config","type":"`Record<string, unknown>`","description":"If this notification provider is created in a plugin, the plugin's options are passed in this parameter.","optional":true,"defaultValue":"","expandable":false,"children":[]}]} sectionTitle="new AbstractNotificationService"/>
___
## Methods
### sendNotification
When an event is triggered that your Notification Provider is registered as a handler for, the [`NotificationService`](https://docs.medusajs.com/references/services/classes/services.NotificationService)
in the Medusa backend executes this method of your Notification Provider.
In this method, you can perform the necessary operation to send the Notification. For example, you can send an email to the customer when they place an order.
#### Example
```ts
class EmailSenderService extends AbstractNotificationService {
// ...
async sendNotification(
event: string,
data: any,
attachmentGenerator: unknown
): Promise<{
to: string;
status: string;
data: Record<string, unknown>;
}> {
if (event === "order.placed") {
// retrieve order
const order = await this.orderService.retrieve(data.id)
// TODO send email
console.log("Notification sent")
return {
to: order.email,
status: "done",
data: {
// any data necessary to send the email
// for example:
subject: "You placed a new order!",
items: order.items,
},
}
}
}
// ...
}
```
#### Parameters
<TypeList types={[{"name":"event","type":"`string`","description":"The name of the event that was triggered. For example, `order.placed`.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"data","type":"`unknown`","description":"The data payload of the event that was triggered. For example, if the `order.placed` event is triggered,\nthe `eventData` object contains the property `id` which is the ID of the order that was placed. You can refer to the\n[Events reference](https://docs.medusajs.com/development/events/events-list) for information on all events and their payloads.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"attachmentGenerator","type":"`unknown`","description":"If youve previously register an attachment generator to the `NotificationService` using the\n[`registerAttachmentGenerator`](https://docs.medusajs.com/references/services/classes/services.NotificationService#registerattachmentgenerator) method,\nyou have access to it here. You can use the `attachmentGenerator` to generate on-demand invoices or other documents. The default value of this parameter is `null`.","optional":false,"defaultValue":"","expandable":false,"children":[]}]} sectionTitle="sendNotification"/>
#### Returns
<TypeList types={[{"name":"Promise","type":"Promise&#60;[ReturnedData](../../interfaces/notification.ReturnedData/page.mdx)&#62;","optional":false,"defaultValue":"","description":"The sending details.","expandable":false,"children":[{"name":"ReturnedData","type":"[ReturnedData](../../interfaces/notification.ReturnedData/page.mdx)","optional":false,"defaultValue":"","description":"The details of a sent or resent notification.","expandable":false,"children":[{"name":"to","type":"`string`","description":"The receiver of the Notification. For example, if you sent an email to the customer then `to` is the email address of the customer.\nIn other cases, it might be a phone number or a username.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"status","type":"`string`","description":"The status of the sent notification. There are no restriction on the returned status.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"data","type":"`Record<string, unknown>`","description":"The data used to send the Notification. For example, if you sent an order confirmation email to the customer, then the `data` object\nmight include the order items or the subject of the email. This `data` is necessary if the notification is resent later as you can use the same data.","optional":false,"defaultValue":"","expandable":false,"children":[]}]}]}]} sectionTitle="sendNotification"/>
### resendNotification
This method is used to resend notifications, which is typically triggered by the
[Resend Notification API Route](https://docs.medusajs.com/api/admin#notifications\_postnotificationsnotificationresend).
#### Example
```ts
class EmailSenderService extends AbstractNotificationService {
// ...
async resendNotification(
notification: any,
config: any,
attachmentGenerator: unknown
): Promise<{
to: string;
status: string;
data: Record<string, unknown>;
}> {
// check if the receiver should be changed
const to: string = config.to || notification.to
// TODO resend the notification using the same data
// that is saved under notification.data
console.log("Notification resent")
return {
to,
status: "done",
data: notification.data, // make changes to the data
}
}
}
```
#### Parameters
<TypeList types={[{"name":"notification","type":"`unknown`","description":"The original [Notification record](https://docs.medusajs.com/references/entities/classes/Notification) that was created after you sent the\nnotification with `sendNotification`. It includes the `to` and `data` attributes which are populated originally using the `to` and `data` properties of\nthe object you return in [sendNotification](page.mdx#sendnotification).","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"config","type":"`unknown`","description":"The new configuration used to resend the notification. The [Resend Notification API Route](https://docs.medusajs.com/api/admin#notifications\\_postnotificationsnotificationresend),\nallows you to pass a new `to` field. If specified, it will be available in this config object.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"attachmentGenerator","type":"`unknown`","description":"f youve previously register an attachment generator to the `NotificationService` using the\n[`registerAttachmentGenerator`](https://docs.medusajs.com/references/services/classes/services.NotificationService#registerattachmentgenerator) method,\nyou have access to it here. You can use the `attachmentGenerator` to generate on-demand invoices or other documents. The default value of this parameter is `null`.","optional":false,"defaultValue":"","expandable":false,"children":[]}]} sectionTitle="resendNotification"/>
#### Returns
<TypeList types={[{"name":"Promise","type":"Promise&#60;[ReturnedData](../../interfaces/notification.ReturnedData/page.mdx)&#62;","optional":false,"defaultValue":"","description":"The resend details.","expandable":false,"children":[{"name":"ReturnedData","type":"[ReturnedData](../../interfaces/notification.ReturnedData/page.mdx)","optional":false,"defaultValue":"","description":"The details of a sent or resent notification.","expandable":false,"children":[{"name":"to","type":"`string`","description":"The receiver of the Notification. For example, if you sent an email to the customer then `to` is the email address of the customer.\nIn other cases, it might be a phone number or a username.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"status","type":"`string`","description":"The status of the sent notification. There are no restriction on the returned status.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"data","type":"`Record<string, unknown>`","description":"The data used to send the Notification. For example, if you sent an order confirmation email to the customer, then the `data` object\nmight include the order items or the subject of the email. This `data` is necessary if the notification is resent later as you can use the same data.","optional":false,"defaultValue":"","expandable":false,"children":[]}]}]}]} sectionTitle="resendNotification"/>
---
## Subscribe with Loaders
After creating your Notification Provider Service, you must create a [Loader](https://docs.medusajs.com/development/loaders/overview) that registers this Service as a notification handler of events.
For example, to register the `email-sender` Notification Provider as a handler for the `order.placed` event, create the file `src/loaders/notification.ts` with the following content:
```ts title="src/loaders/notification.ts"
import {
MedusaContainer,
NotificationService,
} from "@medusajs/medusa"
export default async (
container: MedusaContainer
): Promise<void> => {
const notificationService = container.resolve<
NotificationService
>("notificationService")
notificationService.subscribe(
"order.placed",
"email-sender"
)
}
```
This loader accesses the `notificationService` through the [MedusaContainer](https://docs.medusajs.com/development/fundamentals/dependency-injection). The `notificationService` has a `subscribe` method that accepts 2 parameters. The first one is the name of the event to subscribe to, and the second is the identifier of the Notification Provider that's subscribing to that event.
---
## Test Sending a Notification
Make sure you have an event bus module configured in your Medusa backend. You can learn more on how to do that in the [Configurations guide](https://docs.medusajs.com/development/backend/configurations#modules).
Then:
1\. Run the `build` command in the root directory of your Medusa backend:
```bash npm2yarn
npm run build
```
2\. Start your Medusa backend:
```bash npm2yarn
npx medusa develop
```
3\. Place an order either using the [REST APIs](https://docs.medusajs.com/api/store) or using the [storefront](https://docs.medusajs.com/starters/nextjs-medusa-starter).
4\. After placing an order, you can see in your console the message “Notification Sent”. If you added your own notification sending logic, you should receive an email or alternatively the type of notification youve set up.
---
## Test Resending a Notification
To test resending a notification:
1. Retrieve the ID of the notification you just sent using the [List Notifications API Route](https://docs.medusajs.com/api/admin#notifications_getnotifications). You can pass as a body parameter the `to` or `event_name` parameters to filter out the notification you just sent.
2. Send a request to the [Resend Notification API Route](https://docs.medusajs.com/api/admin#notifications_postnotificationsnotificationresend) using the ID retrieved from the previous request. You can pass the `to` parameter in the body to change the receiver of the notification.
3. You should see the message “Notification Resent” in your console.
@@ -1,224 +0,0 @@
import { TypeList } from "docs-ui"
# INotificationService
## Overview
:::note[Prerequisites]
Before creating a Notification Provider, [install an event bus module](https://docs.medusajs.com/development/events/modules/redis).
:::
A Notification Provider is a provider that handles sending and resending of notifications.
To create a Notification Provider, create a TypeScript or JavaScript file in `src/services`. The name of the file is the name of the provider
(for example, `sendgrid.ts`). The file must export a class that extends the `AbstractNotificationService` class imported from `@medusajs/medusa`.
For example, create the file `src/services/email-sender.ts` with the following content:
```ts title="src/services/email-sender.ts"
import { AbstractNotificationService } from "@medusajs/medusa"
import { EntityManager } from "typeorm"
class EmailSenderService extends AbstractNotificationService {
protected manager_: EntityManager
protected transactionManager_: EntityManager
sendNotification(
event: string,
data: unknown,
attachmentGenerator: unknown
): Promise<{
to: string;
status: string;
data: Record<string, unknown>;
}> {
throw new Error("Method not implemented.")
}
resendNotification(
notification: unknown,
config: unknown,
attachmentGenerator: unknown
): Promise<{
to: string;
status: string;
data: Record<string, unknown>;
}> {
throw new Error("Method not implemented.")
}
}
export default EmailSenderService
```
---
## Identifier Property
The `NotificationProvider` entity has 2 properties: `identifier` and `is_installed`. The value of the `identifier` property in the notification provider
class is used when the Notification Provider is created in the database.
The value of this property is also used later when you want to subscribe the Notification Provider to events in a [Loader](https://docs.medusajs.com/development/loaders/overview).
For example:
```ts
class EmailSenderService extends AbstractNotificationService {
static identifier = "email-sender"
// ...
}
```
---
## Properties
<TypeList types={[{"name":"manager_","type":"`EntityManager`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"transactionManager_","type":"`undefined` \\| `EntityManager`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"__container__","type":"`any`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"__configModule__","type":"`Record<string, unknown>`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"__moduleDeclaration__","type":"`Record<string, unknown>`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]}]} sectionTitle="INotificationService"/>
___
## Accessors
### activeManager\_
#### Returns
<TypeList types={[{"name":"EntityManager","type":"`EntityManager`","optional":false,"defaultValue":"","description":"","expandable":false,"children":[]}]} sectionTitle="activeManager_"/>
___
## Methods
### sendNotification
When an event is triggered that your Notification Provider is registered as a handler for, the [`NotificationService`](https://docs.medusajs.com/references/services/classes/services.NotificationService)
in the Medusa backend executes this method of your Notification Provider.
In this method, you can perform the necessary operation to send the Notification. For example, you can send an email to the customer when they place an order.
#### Example
```ts
class EmailSenderService extends AbstractNotificationService {
// ...
async sendNotification(
event: string,
data: any,
attachmentGenerator: unknown
): Promise<{
to: string;
status: string;
data: Record<string, unknown>;
}> {
if (event === "order.placed") {
// retrieve order
const order = await this.orderService.retrieve(data.id)
// TODO send email
console.log("Notification sent")
return {
to: order.email,
status: "done",
data: {
// any data necessary to send the email
// for example:
subject: "You placed a new order!",
items: order.items,
},
}
}
}
// ...
}
```
#### Parameters
<TypeList types={[{"name":"event","type":"`string`","description":"The name of the event that was triggered. For example, `order.placed`.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"data","type":"`unknown`","description":"The data payload of the event that was triggered. For example, if the `order.placed` event is triggered,\nthe `eventData` object contains the property `id` which is the ID of the order that was placed. You can refer to the\n[Events reference](https://docs.medusajs.com/development/events/events-list) for information on all events and their payloads.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"attachmentGenerator","type":"`unknown`","description":"If youve previously register an attachment generator to the `NotificationService` using the\n[`registerAttachmentGenerator`](https://docs.medusajs.com/references/services/classes/services.NotificationService#registerattachmentgenerator) method,\nyou have access to it here. You can use the `attachmentGenerator` to generate on-demand invoices or other documents. The default value of this parameter is `null`.","optional":false,"defaultValue":"","expandable":false,"children":[]}]} sectionTitle="sendNotification"/>
#### Returns
<TypeList types={[{"name":"Promise","type":"Promise&#60;[ReturnedData](../notification.ReturnedData/page.mdx)&#62;","optional":false,"defaultValue":"","description":"The sending details.","expandable":false,"children":[{"name":"ReturnedData","type":"[ReturnedData](../notification.ReturnedData/page.mdx)","optional":false,"defaultValue":"","description":"The details of a sent or resent notification.","expandable":false,"children":[{"name":"to","type":"`string`","description":"The receiver of the Notification. For example, if you sent an email to the customer then `to` is the email address of the customer.\nIn other cases, it might be a phone number or a username.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"status","type":"`string`","description":"The status of the sent notification. There are no restriction on the returned status.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"data","type":"`Record<string, unknown>`","description":"The data used to send the Notification. For example, if you sent an order confirmation email to the customer, then the `data` object\nmight include the order items or the subject of the email. This `data` is necessary if the notification is resent later as you can use the same data.","optional":false,"defaultValue":"","expandable":false,"children":[]}]}]}]} sectionTitle="sendNotification"/>
### resendNotification
This method is used to resend notifications, which is typically triggered by the
[Resend Notification API Route](https://docs.medusajs.com/api/admin#notifications\_postnotificationsnotificationresend).
#### Example
```ts
class EmailSenderService extends AbstractNotificationService {
// ...
async resendNotification(
notification: any,
config: any,
attachmentGenerator: unknown
): Promise<{
to: string;
status: string;
data: Record<string, unknown>;
}> {
// check if the receiver should be changed
const to: string = config.to || notification.to
// TODO resend the notification using the same data
// that is saved under notification.data
console.log("Notification resent")
return {
to,
status: "done",
data: notification.data, // make changes to the data
}
}
}
```
#### Parameters
<TypeList types={[{"name":"notification","type":"`unknown`","description":"The original [Notification record](https://docs.medusajs.com/references/entities/classes/Notification) that was created after you sent the\nnotification with `sendNotification`. It includes the `to` and `data` attributes which are populated originally using the `to` and `data` properties of\nthe object you return in [sendNotification](page.mdx#sendnotification).","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"config","type":"`unknown`","description":"The new configuration used to resend the notification. The [Resend Notification API Route](https://docs.medusajs.com/api/admin#notifications\\_postnotificationsnotificationresend),\nallows you to pass a new `to` field. If specified, it will be available in this config object.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"attachmentGenerator","type":"`unknown`","description":"f youve previously register an attachment generator to the `NotificationService` using the\n[`registerAttachmentGenerator`](https://docs.medusajs.com/references/services/classes/services.NotificationService#registerattachmentgenerator) method,\nyou have access to it here. You can use the `attachmentGenerator` to generate on-demand invoices or other documents. The default value of this parameter is `null`.","optional":false,"defaultValue":"","expandable":false,"children":[]}]} sectionTitle="resendNotification"/>
#### Returns
<TypeList types={[{"name":"Promise","type":"Promise&#60;[ReturnedData](../notification.ReturnedData/page.mdx)&#62;","optional":false,"defaultValue":"","description":"The resend details.","expandable":false,"children":[{"name":"ReturnedData","type":"[ReturnedData](../notification.ReturnedData/page.mdx)","optional":false,"defaultValue":"","description":"The details of a sent or resent notification.","expandable":false,"children":[{"name":"to","type":"`string`","description":"The receiver of the Notification. For example, if you sent an email to the customer then `to` is the email address of the customer.\nIn other cases, it might be a phone number or a username.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"status","type":"`string`","description":"The status of the sent notification. There are no restriction on the returned status.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"data","type":"`Record<string, unknown>`","description":"The data used to send the Notification. For example, if you sent an order confirmation email to the customer, then the `data` object\nmight include the order items or the subject of the email. This `data` is necessary if the notification is resent later as you can use the same data.","optional":false,"defaultValue":"","expandable":false,"children":[]}]}]}]} sectionTitle="resendNotification"/>
### withTransaction
#### Parameters
<TypeList types={[{"name":"transactionManager","type":"`EntityManager`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]}]} sectionTitle="withTransaction"/>
#### Returns
<TypeList types={[{"name":"this","type":"`this`","optional":false,"defaultValue":"","description":"","expandable":false,"children":[]}]} sectionTitle="withTransaction"/>
### shouldRetryTransaction\_
#### Parameters
<TypeList types={[{"name":"err","type":"`Record<string, unknown>` \\| `object`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]}]} sectionTitle="shouldRetryTransaction_"/>
#### Returns
<TypeList types={[{"name":"boolean","type":"`boolean`","optional":false,"defaultValue":"","description":"","expandable":false,"children":[]}]} sectionTitle="shouldRetryTransaction_"/>
### atomicPhase\_
Wraps some work within a transactional block. If the service already has
a transaction manager attached this will be reused, otherwise a new
transaction manager is created.
#### Type Parameters
<TypeList types={[{"name":"TResult","type":"`object`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"TError","type":"`object`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]}]} sectionTitle="atomicPhase_"/>
#### Parameters
<TypeList types={[{"name":"work","type":"(`transactionManager`: `EntityManager`) => Promise&#60;TResult&#62;","description":"the transactional work to be done","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"isolationOrErrorHandler","type":"`IsolationLevel` \\| (`error`: TError) => Promise&#60;void \\| TResult&#62;","description":"the isolation level to be used for the work.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"maybeErrorHandlerOrDontFail","type":"(`error`: TError) => Promise&#60;void \\| TResult&#62;","description":"Potential error handler","optional":true,"defaultValue":"","expandable":false,"children":[]}]} sectionTitle="atomicPhase_"/>
#### Returns
<TypeList types={[{"name":"Promise","type":"Promise&#60;TResult&#62;","optional":false,"defaultValue":"","description":"the result of the transactional work","expandable":false,"children":[{"name":"TResult","type":"TResult","optional":false,"defaultValue":"","description":"","expandable":false,"children":[]}]}]} sectionTitle="atomicPhase_"/>
@@ -1,9 +0,0 @@
import { TypeList } from "docs-ui"
# ReturnedData
The details of a sent or resent notification.
## Properties
<TypeList types={[{"name":"to","type":"`string`","description":"The receiver of the Notification. For example, if you sent an email to the customer then `to` is the email address of the customer.\nIn other cases, it might be a phone number or a username.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"status","type":"`string`","description":"The status of the sent notification. There are no restriction on the returned status.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"data","type":"`Record<string, unknown>`","description":"The data used to send the Notification. For example, if you sent an order confirmation email to the customer, then the `data` object\nmight include the order items or the subject of the email. This `data` is necessary if the notification is resent later as you can use the same data.","optional":false,"defaultValue":"","expandable":false,"children":[]}]} sectionTitle="ReturnedData"/>
@@ -4,6 +4,6 @@ displayed_sidebar: orderReference
import { TypeList } from "docs-ui"
# UpdateOrderTaxLineDTO
# UpdateOrderShippingMethodTaxLineDTO
<TypeList types={[{"name":"id","type":"`string`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"description","type":"`string`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"tax_rate_id","type":"`string`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"code","type":"`string`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"rate","type":"[BigNumberInput](../../types/order.BigNumberInput/page.mdx)","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"provider_id","type":"`string`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]}]} sectionTitle="UpdateOrderTaxLineDTO"/>
<TypeList types={[{"name":"id","type":"`string`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"description","type":"`string`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"tax_rate_id","type":"`string`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"code","type":"`string`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"rate","type":"[BigNumberInput](../../types/order.BigNumberInput/page.mdx)","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"provider_id","type":"`string`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]}]} sectionTitle="UpdateOrderShippingMethodTaxLineDTO"/>
@@ -4,6 +4,6 @@ displayed_sidebar: orderReference
import { TypeList } from "docs-ui"
# UpdateOrderShippingMethodTaxLineDTO
# UpdateOrderTaxLineDTO
<TypeList types={[{"name":"id","type":"`string`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"description","type":"`string`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"tax_rate_id","type":"`string`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"code","type":"`string`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"rate","type":"[BigNumberInput](../../types/order.BigNumberInput/page.mdx)","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"provider_id","type":"`string`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]}]} sectionTitle="UpdateOrderShippingMethodTaxLineDTO"/>
<TypeList types={[{"name":"id","type":"`string`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"description","type":"`string`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"tax_rate_id","type":"`string`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"code","type":"`string`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"rate","type":"[BigNumberInput](../../types/order.BigNumberInput/page.mdx)","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"provider_id","type":"`string`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]}]} sectionTitle="UpdateOrderTaxLineDTO"/>
+33
View File
@@ -1556,6 +1556,10 @@ export const sidebar = sidebarAttachHrefCommonOptions([
path: "/architectural-modules/file/local",
title: "Local",
},
{
path: "/architectural-modules/file/s3",
title: "AWS S3 (and Compatible APIs)",
},
{
title: "Guides",
children: [
@@ -1568,6 +1572,35 @@ export const sidebar = sidebarAttachHrefCommonOptions([
],
},
{
path: "/architectural-modules/notification",
title: "Notification Provider Modules",
hasTitleStyling: true,
children: [
{
path: "/architectural-modules/notification/local",
title: "Local",
},
{
path: "/architectural-modules/notification/sendgrid",
title: "SendGrid",
},
{
title: "Guides",
children: [
{
path: "/architectural-modules/notification/send-notification",
title: "Send Notification",
},
{
path: "/references/notification-provider-module",
title: "Create Notification Module",
},
],
},
],
},
{
path: "/architectural-modules/workflow-engine",
title: "Workflow Engine Modules",
hasTitleStyling: true,
children: [