docs: fixes following QA testing (#9690)

This commit is contained in:
Shahed Nasser
2024-10-22 18:20:21 +03:00
committed by GitHub
parent b2122c4073
commit 731309e87a
40 changed files with 70 additions and 66 deletions
@@ -23,4 +23,4 @@ Refer to the [Medusa UI documentation](https://docs.medusajs.com/ui) to learn ho
## Admin Components List
To build admin customizations that match the Medusa Admin's designs and layouts, refer to [this guide](!resources!/admin-component) to find common components.
To build admin customizations that match the Medusa Admin's designs and layouts, refer to [this guide](!resources!/admin-components) to find common components.
@@ -165,4 +165,4 @@ If you run the Medusa application and go to `localhost:9000/app/custom/123`, you
## Admin Components List
To build admin customizations that match the Medusa Admin's designs and layouts, refer to [this guide](!resources!/admin-component) to find common components.
To build admin customizations that match the Medusa Admin's designs and layouts, refer to [this guide](!resources!/admin-components) to find common components.
@@ -147,7 +147,7 @@ import { Modules } from "@medusajs/framework/utils"
createProductsWorkflow.hooks.productsCreated(
async ({ products, additional_data }, { container }) => {
if (!additional_data.brand) {
if (!additional_data?.brand) {
return
}
@@ -204,4 +204,4 @@ createProductsWorkflow.hooks.productsCreated(
)
```
This updates the product to their original state before adding the brand to their `metadata` property.
This updates the products to their original state before adding the brand to their `metadata` property.
@@ -68,7 +68,7 @@ export default defineMiddlewares({
The `authenticate` middleware function accepts three parameters:
1. The type of user authenticating. Use `user` for authenticating admin users, and `customer` for authenticating customers. You can also pass `*` to allow all types of users.
2. An array of the types of authentication methods allowed. Both `user` and `customer` scopes support `session` and `bearer`. The `admin` scope also supports the `api-key` authentication method.
2. An array of types of authentication methods allowed. Both `user` and `customer` scopes support `session` and `bearer`. The `admin` scope also supports the `api-key` authentication method.
3. An optional object of configurations accepting the following property:
- `allowUnauthenticated`: (default: `false`) A boolean indicating whether authentication is required. For example, you may have an API route where you want to access the logged-in customer if available, but guest customers can still access it too.
@@ -4,7 +4,7 @@ export const metadata = {
# {metadata.title}
In this chapter, you'll learn how create and execute custom scripts from Medusa's CLI tool.
In this chapter, you'll learn how to create and execute custom scripts from Medusa's CLI tool.
## What is a Custom CLI Script?
@@ -42,7 +42,7 @@ In the example above, you pass the `user` property when creating or updating an
When you create a record of a data model that has one of another, pass the ID of the other data model's record in the relation property.
For example, assuming you have the [User and Email data models from the previous chapter](../relationships/page.mdx#one-to-one-relationship), set an user's email ID as follows:
For example, assuming you have the [User and Email data models from the previous chapter](../relationships/page.mdx#one-to-one-relationship), set a user's email ID as follows:
export const hasOneHighlights = [
["4", "email", "The ID of the email that the user has."],
@@ -34,7 +34,7 @@ A one-to-one relationship indicates that one record of a data model belongs to o
To define a one-to-one relationship, create relationship properties in the data models using the following methods:
1. `hasOne`: indicates that the model has one record of the specified model.
1. `hasOne`: indicates that the model has one records of the specified model.
2. `belongsTo`: indicates that the model belongs to one record of the specified model.
For example:
@@ -8,7 +8,7 @@ In this chapter, you'll learn how to add custom columns to a link definition and
## How to Add Custom Columns to a Link's Table?
The `defineLink` function used to define a link accepts a third paramter, which is an object of options.
The `defineLink` function used to define a link accepts a third parameter, which is an object of options.
To add custom columns to a link's table, pass in the third parameter of `defineLink` a `database` property:
@@ -14,7 +14,7 @@ So, resources in the module, such as services or loaders, can only resolve other
### List of Registered Resources
Find a list of resources or dependencies registered in a module's container in [this Learning Resources reference](!resoures!/medusa-container-resources).
Find a list of resources or dependencies registered in a module's container in [this Development Resources reference](!resources!/medusa-container-resources).
---
@@ -161,9 +161,9 @@ Refer to [MikroORM's reference](https://mikro-orm.io/api/5.9/knex/class/EntityMa
### Why Wrap a Transactional Method
The variables in the transactional method (for example, `update_`) hold values that are uncomitted to the database. They're only committed once the method finishes execution.
The variables in the transactional method (for example, `update_`) hold values that are uncommitted to the database. They're only committed once the method finishes execution.
So, if in your method you perform database operations, then use their result to perform other actions, such as connect to a third-party service, you'll be working with uncommitted data.
So, if in your method you perform database operations, then use their result to perform other actions, such as connecting to a third-party service, you'll be working with uncommitted data.
By placing only the database operations in a method that has the `InjectTransactionManager` and using it in a wrapper method, the wrapper method receives the committed result of the transactional method.
@@ -201,7 +201,7 @@ In this case, only the `update_` method is wrapped in a transaction. The returne
### Using Methods in Transactional Methods
If your transactional method uses other methods that accept a Medusa context, pass the shared context to those method.
If your transactional method uses other methods that accept a Medusa context, pass the shared context to those methods.
For example:
@@ -8,7 +8,7 @@ This chapter lists constraints to keep in mind when creating a service.
## Use Async Methods
Medusa wraps service method executions to inject useful context or transactions. However, since Medusa can't detect whether the method is asynchronus, it always executes methods in the wrapper with the `await` keyword.
Medusa wraps service method executions to inject useful context or transactions. However, since Medusa can't detect whether the method is asynchronous, it always executes methods in the wrapper with the `await` keyword.
For example, if you have a synchronous `getMessage` method, and you use it other resources like workflows, Medusa executes it as an async method:
@@ -6,7 +6,7 @@ export const metadata = {
In the previous chapters, you got a brief introduction to Medusas basic concepts. However, to build a custom commerce application, you need a deeper understanding of how you utilize these concepts for your business use case.
The next chapters dive deeper into each concept, and explores Medusa's architecture. By the end of these chapters, youll be able to:
The next chapters dive deeper into each concept, and explore Medusa's architecture. By the end of these chapters, youll be able to:
- Expose API routes with control over authentication.
- Build sophisticated business logic in modules and manage links between them.
@@ -41,7 +41,7 @@ const workflow = createWorkflow(
)
```
Instead of invoking the workflow, passing it the container, you use its `runAsStep` method and pass it an object as a parameter.
Instead of invoking the workflow and passing it the container, you use its `runAsStep` method and pass it an object as a parameter.
The object has an `input` property to pass input to the workflow.
@@ -6,7 +6,7 @@ export const metadata = {
In this chapter, you'll learn how to manipulate variables in a workflow using the transform utility.
## Why Variable Manipulation isn't Allowed in Worflows?
## Why Variable Manipulation isn't Allowed in Workflows?
Medusa creates an internal representation of the workflow definition you pass to `createWorkflow` to track and store its steps.
@@ -29,7 +29,7 @@ const str1 = step1()
const str2 = step2()
```
To concatinate the strings, you create a new variable `str3` using the `transform` function:
To concatenate the strings, you create a new variable `str3` using the `transform` function:
export const highlights = [
["14", "str3", "Holds the result returned by `transform`'s second parameter function."],
@@ -61,4 +61,4 @@ Then, open a products details page in the Medusa Admin. Youll find your cu
## Admin Components List
To build admin customizations that match the Medusa Admin's designs and layouts, refer to [this guide](!resources!/admin-component) to find common components.
To build admin customizations that match the Medusa Admin's designs and layouts, refer to [this guide](!resources!/admin-components) to find common components.
@@ -40,7 +40,7 @@ export const config: SubscriberConfig = {
A subscriber file must export:
- A subscriber function that is an asynchronous function executed whenever the associated event is triggered.
- An asynchronous subscriber function that's 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`.
@@ -10,7 +10,7 @@ In this chapter, youll learn about loaders and how to use them.
A loader is a function executed when the Medusa application starts. You define and export it in a module.
Loaders are useful to perform a task at the application start-up, such as to sync data between Medusa and a third-pary service.
Loaders are useful to perform a task at the application start-up, such as to sync data between Medusa and a third-party service.
---
@@ -58,7 +58,7 @@ Data models automatically have the date properties `created_at`, `updated_at`, a
### 2. Create Service
A module must define a service that implements its functionalities, such as manage the records of your custom data models in the database.
A module must define a service that implements its functionalities, such as managing the records of your custom data models in the database.
A service is a TypeScript or JavaScript class defined in the `service.ts` file at the root of your module's directory.
@@ -140,11 +140,11 @@ module.exports = defineConfig({
})
```
Its value is an array of objects, each having a `resolve` property, whose value is either a path to module's directory, or an `npm` packages name.
Its value is an array of objects, each having a `resolve` property, whose value is either a path to the module's directory, or an `npm` packages name.
### 5. Generate Migrations
A migration is a TypeScript or JavaScript file that defines database changes made by your module, such as create the `my_custom` table for the `MyCustom` data model.
A migration is a TypeScript or JavaScript file that defines database changes made by your module, such as creating the `my_custom` table for the `MyCustom` data model.
To generate a migration for the data models in your module, run the following command:
@@ -160,7 +160,7 @@ The module name `helloModuleService` is the key used when registering the module
</Note>
The above command creates a migration file at the directory `src/modules/hello/migrations` similar to the following:
The above command creates a migration file in the directory `src/modules/hello/migrations` similar to the following:
```ts
import { Migration } from "@mikro-orm/migrations"
+3 -3
View File
@@ -4,15 +4,15 @@ export const metadata = {
# {metadata.title}
In the next chapters, youll learn about the basic concepts of Medusa that are central in your development.
In the next chapters, youll learn about the basic concepts of Medusa that are central to your development.
By the end of these chapter, youll be able to:
By the end of these chapters, youll be able to:
- Expose your custom functionalities through endpoints.
- Create custom modules that define custom business logic.
- Create custom tables in the database through data models.
- Execute scripts when the Medusa application starts.
- Perform asynchronus actions when an event occurs.
- Perform asynchronous actions when an event occurs.
- Run tasks at a specified time or pattern during the Medusa application's runtime.
- Create custom flows as a series of steps involving multiple services.
- Customize the admin dashboard to inject components on existing pages or add new pages.
@@ -267,4 +267,4 @@ const myWorkflow = createWorkflow(
export default myWorkflow
```
In the step, you resolve the Product Module's main service and use it to retrieve the product count.
In `step1`, you resolve the Product Module's main service and use it to retrieve the product count.
@@ -76,7 +76,7 @@ This method accepts as a first parameter filters to apply on the retrieved data,
<Note>
Learn more about the `listAndCount` method and its parameters in [this reference](!resources!service-factory-reference/methods/listAndCount).
Learn more about the `listAndCount` method and its parameters in [this reference](!resources!/service-factory-reference/methods/listAndCount).
</Note>
@@ -94,7 +94,7 @@ import BrandModuleService from "../../modules/brand/service"
createProductsWorkflow.hooks.productsCreated(
(async ({ products, additional_data }, { container }) => {
if (!additional_data.brand_id) {
if (!additional_data?.brand_id) {
return new StepResponse([], [])
}
@@ -215,7 +215,7 @@ In the Medusa application's logs, you'll find the message `Linked brand to produ
---
## Worflows and API Routes References
## Workflows and API Routes References
Medusa exposes hooks in many of its workflows that you can consume to add custom logic.
@@ -140,7 +140,7 @@ In the compensation function, you undo the step's action using the `deleteBrand`
### Add Step to Workflow
Finally, add the step to the `syncBrandToSystemWorkflow` in `src/workflows/sync-brand-to-system/index.ts`:
Finally, add this step to the `syncBrandToSystemWorkflow` in `src/workflows/sync-brand-to-system/index.ts`:
```ts title="src/workflows/sync-brand-to-system/index.ts"
// other imports...
@@ -6,7 +6,7 @@ export const metadata = {
The previous examples under the Customization chapter explained more about customizing Medusa for a realistic use case.
Your learning journey doesn't end here, and this only presents some of Medusa's powerful feature.
Your learning journey doesn't end here, and this only presents some of Medusa's powerful features.
This chapter guides you into how to continue your learning journey, and what resources will be helpful for you during your development.
@@ -33,6 +33,6 @@ Some of these guides and references are:
## More Examples in Recipes
In the Development Resources documentation, you'll also find step-by-step guides of different use cases, such as building a marketplace, digital products, and more.
In the Development Resources documentation, you'll also find step-by-step guides for different use cases, such as building a marketplace, digital products, and more.
Refer to the [Recipes](!resources!/recipes) documentation to learn more.
@@ -148,7 +148,7 @@ If you check traces in your exporter, you'll find new traces reported.
Trace span names start with the following keywords based on what it's reporting:
- `{methodName} {URL}` when reporting HTTP requests, where `{methodName}` is the HTTP method, and `{URL}` is the URL the request is sent to.
- `route:` when reporting route handlers running on an HTTP requests.
- `route:` when reporting route handlers running on an HTTP request.
- `middleware:` when reporting a middleware running on an HTTP request.
- `workflow:` when reporting a workflow execution.
- `step:` when reporting a step in a workflow execution.
+1 -1
View File
@@ -4,7 +4,7 @@ export const metadata = {
# {metadata.title}
In this chapter, youll learn about the approach to deploy your Medusa application.
In this chapter, youll learn the general approach to deploying the Medusa application.
<Note title="Important">
@@ -1,4 +1,3 @@
import { TriangleRightMini } from "@medusajs/icons"
import clsx from "clsx"
import {
CalendarRefreshIcon,
+1 -6
View File
@@ -475,7 +475,7 @@ export const sidebar = numberSidebarItems(
children: [
{
type: "link",
path: "/advanced-development/custom-cli-scripts/seed-data",
path: "/learn/advanced-development/custom-cli-scripts/seed-data",
title: "Seed Data",
},
],
@@ -589,11 +589,6 @@ export const sidebar = numberSidebarItems(
path: "/learn/more-resources/cheatsheet",
title: "Cheat Sheet",
},
{
type: "link",
path: "/learn/more-resources/examples",
title: "Examples",
},
],
},
])
@@ -183,4 +183,4 @@ 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.
And create a product either using the [API route](!api!/admin#products_postproducts) or the Medusa Admin. This runs the subscriber and sends an email using SendGrid.
@@ -309,7 +309,7 @@ curl -X POST 'localhost:9000/store/carts' \
Make sure to replace `{publishable_api_key}` with your publishable API key, which you can retrieve from the Medusa Admin. Also, replace the value of `region_id` with an ID of a region in your application.
The request will return the cart's details. You'll learn how to retrive the `custom_name` property with the cart's details in the next section.
The request will return the cart's details. You'll learn how to retrieve the `custom_name` property with the cart's details in the next section.
---
@@ -401,7 +401,7 @@ export default defineMiddlewares({
})
```
The validation schema is the similar to that of the Create Cart API route, except you can pass a `null` value for `custom_name` to remove or unset the `custom_name`'s value.
The validation schema is similar to that of the Create Cart API route, except you can pass a `null` value for `custom_name` to remove or unset the `custom_name`'s value.
### Create Workflow to Update Custom Record
@@ -617,7 +617,7 @@ return new WorkflowResponse({
})
```
Using the `when-then` utility, you check if the cart has a linked `Custom` record and `custom_name` is passed in the `additional_data`. If so, you update the linked `Custom` recod.
Using the `when-then` utility, you check if the cart has a linked `Custom` record and `custom_name` is passed in the `additional_data`. If so, you update the linked `Custom` record.
You return in the workflow response the created, updated, and deleted `Custom` record.
@@ -118,7 +118,7 @@ const shippingAdjustments =
A cart is scoped to a sales channel, region, and a customer.
The Medusa application links the Cart Module to each of their respective modules, providing with features like:
The Medusa application links the Cart Module to each of their respective modules, providing features like:
- Checking product availability in a sales channel.
- Retrieving pricing per region.
@@ -8,7 +8,7 @@ In this document, youll learn how registered and unregistered accounts are di
## `has_account` Property
The [Customer data model](/references/customer/models/Customer) has a `has_account` property, which is a boolean that indicates whether a customer is registerd.
The [Customer data model](/references/customer/models/Customer) has a `has_account` property, which is a boolean that indicates whether a customer is registered.
When a guest customer places an order, a new `Customer` record is created with `has_account` set to `false`.
@@ -321,7 +321,7 @@ curl -X POST 'localhost:9000/admin/customers' \
Make sure to replace `{token}` with an admin user's JWT token. Learn how to retrieve it in the [API reference](!api!/admin#1-bearer-authorization-with-jwt-tokens).
The request will return the customer's details. You'll learn how to retrive the `custom_name` property with the customer's details in the next section.
The request will return the customer's details. You'll learn how to retrieve the `custom_name` property with the customer's details in the next section.
---
@@ -629,7 +629,7 @@ return new WorkflowResponse({
})
```
Using the `when-then` utility, you check if the customer has a linked `Custom` record and `custom_name` is passed in the `additional_data`. If so, you update the linked `Custom` recod.
Using the `when-then` utility, you check if the customer has a linked `Custom` record and `custom_name` is passed in the `additional_data`. If so, you update the linked `Custom` record.
You return in the workflow response the created, updated, and deleted `Custom` record.
@@ -50,4 +50,4 @@ When an item in an order is returned and the associated variant has its `manage_
### Dismissed Returned Items
If a returned item is considered damanged or its dismissed, its quantity doesn't increment the `stocked_quantity` of the inventory item's level.
If a returned item is considered damaged or is dismissed, its quantity doesn't increment the `stocked_quantity` of the inventory item's level.
@@ -14,14 +14,18 @@ This is useful in many cases such as when a payment is being processed asynchron
---
## processEvent Method
## getWebhookActionAndData Method
The Payment Modules main service has a [processEvent method](/references/payment/processEvent) used to handle incoming webhook events from third-party payment services. The method delegates the handling to the associated payment provider, which returns the event's details.
The Payment Modules main service has a [getWebhookActionAndData method](/references/payment/getWebhookActionAndData) used to handle incoming webhook events from third-party payment services. The method delegates the handling to the associated payment provider, which returns the event's details.
Medusa implements a webhook listener route at the `/hooks/payment/[provider]` API route, where `[provider]` is the ID of the provider (for example, `stripe`). Use that webhook listener in your third-party payment provider's configurations.
![A diagram showcasing the steps of how the processEvent method words](https://res.cloudinary.com/dza7lstvk/image/upload/v1711567415/Medusa%20Resources/payment-webhook_seaocg.jpg)
![A diagram showcasing the steps of how the getWebhookActionAndData method words](https://res.cloudinary.com/dza7lstvk/image/upload/v1711567415/Medusa%20Resources/payment-webhook_seaocg.jpg)
If the event's details indicate that the payment should be authorized, then the [authorizePaymentSession method of the main service](/references/payment/authorizePaymentSession) is executed on the specified payment session.
If the event's details indicate that the payment should be captured, then the [capturePayment method of the main service](/references/payment/capturePayment) is executed on the payment of the specified payment session.
If the event's details indicate that the payment should be captured, then the [capturePayment method of the main service](/references/payment/capturePayment) is executed on the payment of the specified payment session.
### Actions After Webhook Payment Processing
After the payment webhook actions are processed and the payment is authorized or captured, the Medusa application completes the cart associated with the payment's collection if it's not completed yet.
@@ -327,7 +327,7 @@ curl -X POST 'localhost:9000/admin/products' \
Make sure to replace `{token}` with an admin user's JWT token. Learn how to retrieve it in the [API reference](!api!/admin#1-bearer-authorization-with-jwt-tokens).
The request will return the product's details. You'll learn how to retrive the `custom_name` property with the product's details in the next section.
The request will return the product's details. You'll learn how to retreive the `custom_name` property with the product's details in the next section.
---
@@ -635,7 +635,7 @@ return new WorkflowResponse({
})
```
Using the `when-then` utility, you check if the product has a linked `Custom` record and `custom_name` is passed in the `additional_data`. If so, you update the linked `Custom` recod.
Using the `when-then` utility, you check if the product has a linked `Custom` record and `custom_name` is passed in the `additional_data`. If so, you update the linked `Custom` record.
You return in the workflow response the created, updated, and deleted `Custom` record.
@@ -333,7 +333,7 @@ curl --location 'localhost:9000/admin/promotions' \
Make sure to replace `{token}` with an admin user's JWT token. Learn how to retrieve it in the [API reference](!api!/admin#1-bearer-authorization-with-jwt-tokens).
The request will return the promotion's details. You'll learn how to retrive the `custom_name` property with the promotion's details in the next section.
The request will return the promotion's details. You'll learn how to retrieve the `custom_name` property with the promotion's details in the next section.
---
@@ -641,7 +641,7 @@ return new WorkflowResponse({
})
```
Using the `when-then` utility, you check if the promotion has a linked `Custom` record and `custom_name` is passed in the `additional_data`. If so, you update the linked `Custom` recod.
Using the `when-then` utility, you check if the promotion has a linked `Custom` record and `custom_name` is passed in the `additional_data`. If so, you update the linked `Custom` record.
You return in the workflow response the created, updated, and deleted `Custom` record.
@@ -119,7 +119,7 @@ Extend the Medusa Admin to add widgets to existing pages or add new pages.
<CardList items={[
{
href: "!docs!/learn/advanced-development/admin/widget",
href: "!docs!/learn/advanced-development/admin/widgets",
title: "Create Admin Widget",
text: "Learn how to add widgets into existing admin pages.",
icon: AcademicCapSolid,
@@ -142,7 +142,7 @@ class MyNotificationProviderService extends AbstractNotificationProviderService
#### Parameters
<TypeList types={[{"name":"notification","type":"[ProviderSendNotificationDTO](../../../types/NotificationTypes/interfaces/types.NotificationTypes.ProviderSendNotificationDTO/page.mdx)","description":"The details of the\nnotification to send.","optional":false,"defaultValue":"","expandable":false,"children":[{"name":"to","type":"`string`","description":"The recipient of the notification. It can be email, phone number, or username, depending on the channel.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"channel","type":"`string`","description":"The channel through which the notification is sent, such as 'email' or 'sms'","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"template","type":"`string`","description":"The template name in the provider's system.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"from","type":"`null` \\| `string`","description":"The sender of the notification. It can be email, phone number, or username, depending on the channel.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"attachments","type":"`null` \\| [Attachment](../../../types/NotificationTypes/interfaces/types.NotificationTypes.Attachment/page.mdx)[]","description":"Optional attachments for the notification.","optional":true,"defaultValue":"","expandable":false,"children":[{"name":"content","type":"`string`","description":"The content of the attachment, encoded as a base64 string.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"filename","type":"`string`","description":"The filename of the attachment.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"content_type","type":"`string`","description":"The MIME type of the attachment.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"disposition","type":"`string`","description":"The disposition of the attachment, e.g., \"inline\" or \"attachment\".","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"id","type":"`string`","description":"The ID, if the attachment is meant to be referenced within the body of the message.","optional":true,"defaultValue":"","expandable":false,"children":[]}]},{"name":"data","type":"`null` \\| `Record<string, unknown>`","description":"The data that gets passed over to the provider for rendering the notification.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"content","type":"`null` \\| [NotificationContent](../../../types/NotificationTypes/interfaces/types.NotificationTypes.NotificationContent/page.mdx)","description":"The content that gets passed to the provider.","optional":true,"defaultValue":"","expandable":false,"children":[{"name":"subject","type":"`string`","description":"the subject of the notification","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"text","type":"`string`","description":"the text content of the notification","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"html","type":"`string`","description":"the html content of the notification","optional":true,"defaultValue":"","expandable":false,"children":[]}]}]}]} expandUrl="https://docs.medusajs.com/v2/advanced-development/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="send"/>
<TypeList types={[{"name":"notification","type":"[ProviderSendNotificationDTO](../../../types/NotificationTypes/interfaces/types.NotificationTypes.ProviderSendNotificationDTO/page.mdx)","description":"The details of the\nnotification to send.","optional":false,"defaultValue":"","expandable":false,"children":[{"name":"to","type":"`string`","description":"The recipient of the notification. It can be email, phone number, or username, depending on the channel.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"channel","type":"`string`","description":"The channel through which the notification is sent, such as 'email' or 'sms'","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"template","type":"`string`","description":"The template name in the provider's system.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"from","type":"`null` \\| `string`","description":"The sender of the notification. It can be email, phone number, or username, depending on the channel.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"attachments","type":"`null` \\| [Attachment](../../../types/NotificationTypes/interfaces/types.NotificationTypes.Attachment/page.mdx)[]","description":"Optional attachments for the notification.","optional":true,"defaultValue":"","expandable":false,"children":[{"name":"content","type":"`string`","description":"The content of the attachment, encoded as a base64 string.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"filename","type":"`string`","description":"The filename of the attachment.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"content_type","type":"`string`","description":"The MIME type of the attachment.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"disposition","type":"`string`","description":"The disposition of the attachment, e.g., \"inline\" or \"attachment\".","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"id","type":"`string`","description":"The ID, if the attachment is meant to be referenced within the body of the message.","optional":true,"defaultValue":"","expandable":false,"children":[]}]},{"name":"data","type":"`null` \\| `Record<string, unknown>`","description":"The data that gets passed over to the provider for rendering the notification.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"content","type":"`null` \\| `NotificationContent`","description":"The content that gets passed to the provider.","optional":true,"defaultValue":"","expandable":false,"children":[{"name":"subject","type":"`string`","description":"the subject of the notification","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"text","type":"`string`","description":"the text content of the notification","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"html","type":"`string`","description":"the html content of the notification","optional":true,"defaultValue":"","expandable":false,"children":[]}]}]}]} expandUrl="https://docs.medusajs.com/v2/advanced-development/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="send"/>
#### Returns
@@ -15,7 +15,7 @@ import {
} from "../utils/expression-is-utils.js"
import { ComponentLinkFixerOptions } from "../types/index.js"
const MD_LINK_REGEX = /\[(.*?)\]\((?<link>.*?)\)/gm
const MD_LINK_REGEX = /\[(.*?)\]\((?<link>(![a-z]+!|\.).*?)\)/gm
const VALUE_LINK_REGEX = /^(![a-z]+!|\.)/gm
function matchMdLinks(
@@ -23,8 +23,10 @@ function matchMdLinks(
linkOptions: Omit<FixLinkOptions, "linkedPath">
) {
let linkMatches
// reset regex
MD_LINK_REGEX.lastIndex = 0
while ((linkMatches = MD_LINK_REGEX.exec(str)) !== null) {
if (!linkMatches.groups?.link || linkMatches.groups?.link.startsWith("http")) {
if (!linkMatches.groups?.link) {
return
}
@@ -34,6 +36,8 @@ function matchMdLinks(
})
str = str.replace(linkMatches.groups.link, newUrl)
// reset regex
MD_LINK_REGEX.lastIndex = 0
}
return str
@@ -43,7 +47,9 @@ function matchValueLink(
str: string,
linkOptions: Omit<FixLinkOptions, "linkedPath">
) {
if (!VALUE_LINK_REGEX.exec(str) || str.startsWith("http")) {
// reset index
VALUE_LINK_REGEX.lastIndex = 0
if (!VALUE_LINK_REGEX.exec(str)) {
return str
}