docs: read-only links + other changes (#11878)
* docs: read-only links + other changes * re-generate * fix vale errors
This commit is contained in:
@@ -67,12 +67,58 @@ 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.
|
||||
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, or pass an array of actor types.
|
||||
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 properties:
|
||||
- `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.
|
||||
- `allowUnregistered` (default: `false`): A boolean indicating if unregistered users should be allowed access. This is useful when you want to allow users who aren’t registered to access certain routes.
|
||||
|
||||
### Example: Custom Actor Type
|
||||
|
||||
For example, to require authentication of a custom actor type `manager` to an API route:
|
||||
|
||||
```ts title="src/api/middlewares.ts"
|
||||
import {
|
||||
defineMiddlewares,
|
||||
authenticate,
|
||||
} from "@medusajs/framework/http"
|
||||
|
||||
export default defineMiddlewares({
|
||||
routes: [
|
||||
{
|
||||
matcher: "/manager*",
|
||||
middlewares: [authenticate("manager", ["session", "bearer"])],
|
||||
},
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
Refer to the [Custom Actor-Type Guide](!resources!/commerce-modules/auth/create-actor-type) for detailed explanation on how to create a custom actor type and apply authentication middlewares.
|
||||
|
||||
</Note>
|
||||
|
||||
### Example: Allow Multiple Actor Types
|
||||
|
||||
To allow multiple actor types to access an API route, pass an array of actor types to the `authenticate` middleware:
|
||||
|
||||
```ts title="src/api/middlewares.ts"
|
||||
import {
|
||||
defineMiddlewares,
|
||||
authenticate,
|
||||
} from "@medusajs/framework/http"
|
||||
|
||||
export default defineMiddlewares({
|
||||
routes: [
|
||||
{
|
||||
matcher: "/custom*",
|
||||
middlewares: [authenticate(["user", "customer"], ["session", "bearer"])],
|
||||
},
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Authentication Opt-Out
|
||||
|
||||
@@ -6,25 +6,31 @@ export const metadata = {
|
||||
|
||||
In this chapter, you'll learn about the difference in module link directions, and which to use based on your use case.
|
||||
|
||||
<Note>
|
||||
|
||||
The details in this chapter don't apply to [Read-Only Module Links](../read-only/page.mdx). Refer to the [Read-Only Module Links chapter](../read-only/page.mdx) for more information on read-only links and their direction.
|
||||
|
||||
</Note>
|
||||
|
||||
## Link Direction
|
||||
|
||||
The module link's direction depends on the order you pass the data model configuration parameters to `defineLink`.
|
||||
|
||||
For example, the following defines a link from the `helloModuleService`'s `myCustom` data model to the Product Module's `product` data model:
|
||||
For example, the following defines a link from the Blog Module's `post` data model to the Product Module's `product` data model:
|
||||
|
||||
```ts
|
||||
export default defineLink(
|
||||
HelloModule.linkable.myCustom,
|
||||
BlogModule.linkable.post,
|
||||
ProductModule.linkable.product
|
||||
)
|
||||
```
|
||||
|
||||
Whereas the following defines a link from the Product Module's `product` data model to the `helloModuleService`'s `myCustom` data model:
|
||||
Whereas the following defines a link from the Product Module's `product` data model to the Blog Module's `post` data model:
|
||||
|
||||
```ts
|
||||
export default defineLink(
|
||||
ProductModule.linkable.product,
|
||||
HelloModule.linkable.myCustom
|
||||
BlogModule.linkable.post
|
||||
)
|
||||
```
|
||||
|
||||
@@ -43,7 +49,7 @@ For example, consider you want to add a `subtitle` custom field to the `product`
|
||||
```ts
|
||||
export default defineLink(
|
||||
ProductModule.linkable.product,
|
||||
HelloModule.linkable.subtitle
|
||||
BlogModule.linkable.subtitle
|
||||
)
|
||||
```
|
||||
|
||||
@@ -55,7 +61,7 @@ For example, consider you have `Post` data model representing a blog post, and y
|
||||
|
||||
```ts
|
||||
export default defineLink(
|
||||
HelloModule.linkable.post,
|
||||
BlogModule.linkable.post,
|
||||
ProductModule.linkable.product
|
||||
)
|
||||
```
|
||||
|
||||
@@ -0,0 +1,521 @@
|
||||
import { Table } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Read-Only Module Link`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this chapter, you’ll learn what a read-only module link is and how to define one.
|
||||
|
||||
## What is a Read-Only Module Link?
|
||||
|
||||
Consider a scenario where you need to access related records from another module, but don't want the overhead of managing or storing the links between them. This can include cases where you're working with external data models not stored in your Medusa database, such as third-party systems.
|
||||
|
||||
In those cases, instead of defining a [Module Link](../page.mdx) whose linked records must be stored in a link table in the database, you can use a read-only module link. A read-only module link builds a virtual relation from one data model to another in a different module without creating a link table in the database. Instead, the linked record's ID is stored in the first data model's field.
|
||||
|
||||
For example, Medusa creates a read-only module link from the `Cart` data model of the [Cart Module](!resources!/commerce-modules/cart) to the `Customer` data model of the [Customer Module](!resources!/commerce-modules/customer). This link allows you to access the details of the cart's customer without managing the link. Instead, the customer's ID is stored in the `Cart` data model.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## How to Define a Read-Only Module Link
|
||||
|
||||
The `defineLink` function accepts an optional third-parameter object that can hold additional configurations for the module link.
|
||||
|
||||
<Note>
|
||||
|
||||
If you're not familiar with the `defineLink` function, refer to the [Module Links chapter](../page.mdx) for more information.
|
||||
|
||||
</Note>
|
||||
|
||||
To make the module link read-only, pass the `readOnly` property as `true`. You must also set in the link configuration of the first data model a `field` property that specifies the data model's field where the linked record's ID is stored.
|
||||
|
||||
For example:
|
||||
|
||||
export const highlights = [
|
||||
["8", "field", "The field where the linked record's ID is stored."],
|
||||
["12", "readOnly", "Set the link as read-only."]
|
||||
]
|
||||
|
||||
```ts highlights={highlights}
|
||||
import BlogModule from "../modules/blog"
|
||||
import ProductModule from "@medusajs/medusa/product"
|
||||
import { defineLink } from "@medusajs/framework/utils"
|
||||
|
||||
export default defineLink(
|
||||
{
|
||||
linkable: BlogModule.linkable.post,
|
||||
field: "product_id",
|
||||
},
|
||||
ProductModule.linkable.product,
|
||||
{
|
||||
readOnly: true
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
In this example, you define a read-only module link from the Blog Module's `post` data model to the Product Module's `product` data model. You do that by:
|
||||
|
||||
- Passing an object as a first parameter that accepts the linkable configuration and the field where the linked record's ID is stored.
|
||||
- Setting the `readOnly` property to `true` in the third parameter.
|
||||
|
||||
Unlike the stored module link, Medusa will not create a table in the database for this link. Instead, Medusa uses the ID stored in the specified field of the first data model to retrieve the linked record.
|
||||
|
||||
---
|
||||
|
||||
## Retrieve Read-Only Linked Record
|
||||
|
||||
[Query](../query/page.mdx) allows you to retrieve records linked through a read-only module link.
|
||||
|
||||
For example, assuming you have the module link created in [the above section](#how-to-define-a-read-only-module-link), you can retrieve a post and its linked product as follows:
|
||||
|
||||
```ts
|
||||
const { result } = await query.graph({
|
||||
entity: "post",
|
||||
fields: ["id", "product.*"],
|
||||
filters: {
|
||||
id: "post_123"
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
In the above example, you retrieve a post and its linked product. Medusa will use the ID of the product in the post's `product_id` field to determine which product should be retrieved.
|
||||
|
||||
---
|
||||
|
||||
## Read-Only Module Link Direction
|
||||
|
||||
A read-only module is uni-directional. So, you can only retrieve the linked record from the first data model. If you need to access the linked record from the second data model, you must define another read-only module link in the opposite direction.
|
||||
|
||||
In the `blog` -> `product` example, you can access a post's product, but you can't access a product's posts. You would have to define another read-only module link from `product` to `blog` to access a product's posts.
|
||||
|
||||
---
|
||||
|
||||
## Inverse Read-Only Module Link
|
||||
|
||||
An inverse read-only module link is a read-only module link that allows you to access the linked record based on the ID stored in the second data model.
|
||||
|
||||
For example, consider you want to access a product's posts. You can define a read-only module link from the Product Module's `product` data model to the Blog Module's `post` data model:
|
||||
|
||||
```ts
|
||||
import BlogModule from "../modules/blog"
|
||||
import ProductModule from "@medusajs/medusa/product"
|
||||
import { defineLink } from "@medusajs/framework/utils"
|
||||
|
||||
export default defineLink(
|
||||
{
|
||||
linkable: ProductModule.linkable.product,
|
||||
field: "id",
|
||||
},
|
||||
{
|
||||
...BlogModule.linkable.post.id,
|
||||
primaryKey: "product_id",
|
||||
},
|
||||
{
|
||||
readOnly: true
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
In the above example, you define a read-only module link from the Product Module's `product` data model to the Blog Module's `post` data model. This link allows you to access a product's posts.
|
||||
|
||||
Since you can't add a `post_id` field to the `product` data model, you must:
|
||||
|
||||
1. Set the `field` property in the first data model's link configuration to the product's ID field.
|
||||
2. Spread the `BlogModule.linkable.post.id` object in the second parameter object and set the `primaryKey` property to the field in the `post` data model that holds the product's ID.
|
||||
|
||||
You can now retrieve a product and its linked posts:
|
||||
|
||||
```ts
|
||||
const { result } = await query.graph({
|
||||
entity: "product",
|
||||
fields: ["id", "post.*"],
|
||||
filters: {
|
||||
id: "prod_123"
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## One-to-One or One-to-Many?
|
||||
|
||||
When you retrieve the linked record through a read-only module link, the retrieved data may be an object (one-to-one) or an array of objects (one-to-many) based on different criteria.
|
||||
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>Scenario</Table.HeaderCell>
|
||||
<Table.HeaderCell>Relation Type</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
The first data model's `field` is of type string.
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
One-to-one relation
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
The first data model's `field` is of type array of strings.
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
One-to-many relation
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
The read-only module link is inversed.
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
One-to-many relation if multiple records in the second data model have the same ID of the first data model. Otherwise, one-to-one relation.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table>
|
||||
|
||||
### One-to-One Relation
|
||||
|
||||
Consider the first read-only module link you defined in this chapter:
|
||||
|
||||
```ts
|
||||
import BlogModule from "../modules/blog"
|
||||
import ProductModule from "@medusajs/medusa/product"
|
||||
|
||||
export default defineLink(
|
||||
{
|
||||
linkable: BlogModule.linkable.post,
|
||||
field: "product_id",
|
||||
},
|
||||
ProductModule.linkable.product,
|
||||
{
|
||||
readOnly: true
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
Since the `product_id` field of a post stores the ID of a single product, the link is a one-to-one relation. When querying a post, you'll get a single product object:
|
||||
|
||||
```json title="Example Data"
|
||||
[
|
||||
{
|
||||
"id": "post_123",
|
||||
"product_id": "prod_123",
|
||||
"product": {
|
||||
"id": "prod_123",
|
||||
// ...
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### One-to-Many Relation
|
||||
|
||||
Consider the read-only module link from the `post` data model uses an array of product IDs:
|
||||
|
||||
```ts
|
||||
import BlogModule from "../modules/blog"
|
||||
import ProductModule from "@medusajs/medusa/product"
|
||||
|
||||
export default defineLink(
|
||||
{
|
||||
linkable: BlogModule.linkable.post,
|
||||
field: "product_ids",
|
||||
},
|
||||
ProductModule.linkable.product,
|
||||
{
|
||||
readOnly: true
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
Where `product_ids` in the `post` data model is an array of strings. In this case, the link would be a one-to-many relation. So, an array of products would be returned when querying a post:
|
||||
|
||||
```json title="Example Data"
|
||||
[
|
||||
{
|
||||
"id": "post_123",
|
||||
"product_ids": ["prod_123", "prod_124"],
|
||||
"product": [
|
||||
{
|
||||
"id": "prod_123",
|
||||
// ...
|
||||
},
|
||||
{
|
||||
"id": "prod_124",
|
||||
// ...
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### Relation with Inversed Read-Only Link
|
||||
|
||||
If you define an inversed read-only module link where the ID of the linked record is stored in the second data model, the link can be either one-to-one or one-to-many based on the number of records in the second data model that have the same ID of the first data model.
|
||||
|
||||
For example, consider the `product` -> `post` link you defined in an earlier section:
|
||||
|
||||
```ts
|
||||
import BlogModule from "../modules/blog"
|
||||
import ProductModule from "@medusajs/medusa/product"
|
||||
import { defineLink } from "@medusajs/framework/utils"
|
||||
|
||||
export default defineLink(
|
||||
{
|
||||
linkable: ProductModule.linkable.product,
|
||||
field: "id",
|
||||
},
|
||||
{
|
||||
...BlogModule.linkable.post.id,
|
||||
primaryKey: "product_id",
|
||||
},
|
||||
{
|
||||
readOnly: true
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
In the above snippet, the ID of the product is stored in the `post`'s `product_id` string field.
|
||||
|
||||
When you retrieve the post of a product, it may be a post object, or an array of post objects if multiple posts are linked to the product:
|
||||
|
||||
```json title="Example Data"
|
||||
[
|
||||
{
|
||||
"id": "prod_123",
|
||||
"post": {
|
||||
"id": "post_123",
|
||||
"product_id": "prod_123"
|
||||
// ...
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "prod_321",
|
||||
"post": [
|
||||
{
|
||||
"id": "post_123",
|
||||
"product_id": "prod_321"
|
||||
// ...
|
||||
},
|
||||
{
|
||||
"id": "post_124",
|
||||
"product_id": "prod_321"
|
||||
// ...
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
If, however, you use an array field in `post`, the relation would always be one-to-many:
|
||||
|
||||
```json title="Example Data"
|
||||
[
|
||||
{
|
||||
"id": "prod_123",
|
||||
"post": [
|
||||
{
|
||||
"id": "post_123",
|
||||
"product_id": "prod_123"
|
||||
// ...
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
#### Force One-to-Many Relation
|
||||
|
||||
Alternatively, you can force a one-to-many relation by setting `isList` to `true` in the first data model's link configuration. For example:
|
||||
|
||||
```ts
|
||||
import BlogModule from "../modules/blog"
|
||||
import ProductModule from "@medusajs/medusa/product"
|
||||
import { defineLink } from "@medusajs/framework/utils"
|
||||
|
||||
export default defineLink(
|
||||
{
|
||||
linkable: ProductModule.linkable.product,
|
||||
field: "id",
|
||||
isList: true
|
||||
},
|
||||
{
|
||||
...BlogModule.linkable.post.id,
|
||||
primaryKey: "product_id"
|
||||
},
|
||||
{
|
||||
readOnly: true
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
In this case, the relation would always be one-to-many, even if only one post is linked to a product:
|
||||
|
||||
```json title="Example Data"
|
||||
[
|
||||
{
|
||||
"id": "prod_123",
|
||||
"post": [
|
||||
{
|
||||
"id": "post_123",
|
||||
"product_id": "prod_123"
|
||||
// ...
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Example: Read-Only Module Link for Virtual Data Models
|
||||
|
||||
Read-only module links are most useful when working with data models that aren't stored in your Medusa database. For example, data that is stored in a third-party system. In those cases, you can define a read-only module link between a data model in Medusa and the data model in the external system, facilitating the retrieval of the linked data.
|
||||
|
||||
To define the read-only module link to a virtual data model, you must:
|
||||
|
||||
1. Create a `list` method in the custom module's service. This method retrieves the linked records filtered by the ID(s) of the first data model.
|
||||
2. Define the read-only module link from the first data model to the virtual data model.
|
||||
3. Use Query to retrieve the first data model and its linked records from the virtual data model.
|
||||
|
||||
For example, consider you have a third-party Content-Management System (CMS) that you're integrating with Medusa, and you want to retrieve the posts in the CMS associated with a product in Medusa.
|
||||
|
||||
To do that, first, create a CMS Module having the following service:
|
||||
|
||||
<Note>
|
||||
|
||||
Refer to the [Modules chapter](../../modules/page.mdx) to learn how to create a module and its service.
|
||||
|
||||
</Note>
|
||||
|
||||
```ts title="src/modules/cms/service.ts"
|
||||
type CmsModuleOptions = {
|
||||
apiKey: string
|
||||
}
|
||||
|
||||
export default class CmsModuleService {
|
||||
private client
|
||||
|
||||
constructor({}, options: CmsModuleOptions) {
|
||||
this.client = new Client(options)
|
||||
}
|
||||
|
||||
async list(
|
||||
filter: {
|
||||
id: string | string[]
|
||||
}
|
||||
) {
|
||||
return this.client.getPosts(filter)
|
||||
/**
|
||||
* Example of returned data:
|
||||
*
|
||||
* [
|
||||
* {
|
||||
* "id": "post_123",
|
||||
* "product_id": "prod_321"
|
||||
* },
|
||||
* {
|
||||
* "id": "post_456",
|
||||
* "product_id": "prod_654"
|
||||
* }
|
||||
* ]
|
||||
*/
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The above service initializes a client, assuming your CMS has an SDK that allows you to retrieve posts.
|
||||
|
||||
The service must have a `list` method to be part of the read-only module link. This method accepts the ID(s) of the products to retrieve their associated posts. The posts must include the product's ID in a field, such as `product_id`.
|
||||
|
||||
Next, define a read-only module link from the Product Module to the CMS Module:
|
||||
|
||||
```ts title="src/links/product-cms.ts"
|
||||
import { defineLink } from "@medusajs/framework/utils"
|
||||
import ProductModule from "@medusajs/medusa/product"
|
||||
import { CMS_MODULE } from "../modules/cms"
|
||||
|
||||
export default defineLink(
|
||||
{
|
||||
linkable: ProductModule.linkable.product,
|
||||
field: "id"
|
||||
},
|
||||
{
|
||||
linkable: {
|
||||
serviceName: CMS_MODULE,
|
||||
alias: "cms_post",
|
||||
primaryKey: "product_id",
|
||||
}
|
||||
},
|
||||
{
|
||||
readOnly: true,
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
To define the read-only module link, you must pass to `defineLink`:
|
||||
|
||||
1. The first parameter: an object with the linkable configuration of the data model in Medusa, and the fields that will be passed as a filter to the CMS service. For example, if you want to filter by product title instead, you can pass `title` instead of `id`.
|
||||
2. The second parameter: an object with the linkable configuration of the virtual data model in the CMS. This object must have the following properties:
|
||||
- `serviceName`: The name of the service, which is the CMS Module's name. Medusa uses this name to resolve the module's service from the [Medusa container](../../medusa-container/page.mdx).
|
||||
- `alias`: The alias to use when querying the linked records. You'll see how that works in a bit.
|
||||
- `primaryKey`: The field in the CMS data model that holds the ID of a product.
|
||||
3. The third parameter: an object with the `readOnly` property set to `true`.
|
||||
|
||||
Now, you can use Query to retrieve a product and its linked post from the CMS:
|
||||
|
||||
```ts
|
||||
const { data } = await query.graph({
|
||||
entity: "product",
|
||||
fields: ["id", "cms_post.*"],
|
||||
})
|
||||
```
|
||||
|
||||
In the above example, each product that has a CMS post with the `product_id` field set to the product's ID will be retrieved:
|
||||
|
||||
```json title="Example Data"
|
||||
[
|
||||
{
|
||||
"id": "prod_123",
|
||||
"cms_post": {
|
||||
"id": "post_123",
|
||||
"product_id": "prod_123",
|
||||
// ...
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
If multiple posts have their `product_id` set to a product's ID, an array of posts is returned instead:
|
||||
|
||||
```json title="Example Data"
|
||||
[
|
||||
{
|
||||
"id": "prod_123",
|
||||
"cms_post": [
|
||||
{
|
||||
"id": "post_123",
|
||||
"product_id": "prod_123",
|
||||
// ...
|
||||
},
|
||||
{
|
||||
"id": "post_124",
|
||||
"product_id": "prod_123",
|
||||
// ...
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
<Note title="Recommended Tutorial">
|
||||
|
||||
[Sanity Integration Tutorial](!resources!/integrations/guides/sanity).
|
||||
|
||||
</Note>
|
||||
@@ -24,7 +24,7 @@ export const generatedEditDates = {
|
||||
"app/learn/fundamentals/admin/widgets/page.mdx": "2024-12-09T16:43:24.260Z",
|
||||
"app/learn/fundamentals/data-models/page.mdx": "2024-12-09T11:34:51.065Z",
|
||||
"app/learn/fundamentals/modules/remote-link/page.mdx": "2024-09-30T08:43:53.127Z",
|
||||
"app/learn/fundamentals/api-routes/protected-routes/page.mdx": "2024-12-09T16:44:32.277Z",
|
||||
"app/learn/fundamentals/api-routes/protected-routes/page.mdx": "2025-03-17T11:47:10.101Z",
|
||||
"app/learn/fundamentals/workflows/add-workflow-hook/page.mdx": "2024-12-09T14:42:39.693Z",
|
||||
"app/learn/fundamentals/events-and-subscribers/data-payload/page.mdx": "2024-10-21T13:30:21.369Z",
|
||||
"app/learn/fundamentals/data-models/default-properties/page.mdx": "2024-10-21T13:30:21.368Z",
|
||||
@@ -71,7 +71,7 @@ export const generatedEditDates = {
|
||||
"app/learn/debugging-and-testing/testing-tools/modules-tests/module-example/page.mdx": "2025-01-31T13:19:02.586Z",
|
||||
"app/learn/debugging-and-testing/testing-tools/modules-tests/page.mdx": "2025-01-31T13:19:02.587Z",
|
||||
"app/learn/fundamentals/module-links/custom-columns/page.mdx": "2025-03-11T13:29:54.752Z",
|
||||
"app/learn/fundamentals/module-links/directions/page.mdx": "2024-12-12T15:31:31.555Z",
|
||||
"app/learn/fundamentals/module-links/directions/page.mdx": "2025-03-17T12:52:06.161Z",
|
||||
"app/learn/fundamentals/module-links/page.mdx": "2025-03-11T13:39:14.345Z",
|
||||
"app/learn/fundamentals/module-links/query/page.mdx": "2025-03-11T15:35:10.605Z",
|
||||
"app/learn/fundamentals/modules/db-operations/page.mdx": "2024-12-09T14:40:50.581Z",
|
||||
@@ -121,5 +121,6 @@ export const generatedEditDates = {
|
||||
"app/learn/resources/usage/page.mdx": "2025-02-26T13:35:34.824Z",
|
||||
"app/learn/configurations/medusa-config/page.mdx": "2025-03-11T14:27:04.528Z",
|
||||
"app/learn/configurations/ts-aliases/page.mdx": "2025-02-11T16:57:46.683Z",
|
||||
"app/learn/production/worker-mode/page.mdx": "2025-03-11T15:21:50.906Z"
|
||||
"app/learn/production/worker-mode/page.mdx": "2025-03-11T15:21:50.906Z",
|
||||
"app/learn/fundamentals/module-links/read-only/page.mdx": "2025-03-17T14:18:29.924Z"
|
||||
}
|
||||
@@ -411,6 +411,16 @@ export const generatedSidebars = [
|
||||
"chapterTitle": "3.3.4. Add Custom Columns",
|
||||
"number": "3.3.4."
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"path": "/learn/fundamentals/module-links/read-only",
|
||||
"title": "Read-Only Links",
|
||||
"children": [],
|
||||
"chapterTitle": "3.3.5. Read-Only Links",
|
||||
"number": "3.3.5."
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
@@ -418,8 +428,8 @@ export const generatedSidebars = [
|
||||
"path": "/learn/fundamentals/module-links/query-context",
|
||||
"title": "Query Context",
|
||||
"children": [],
|
||||
"chapterTitle": "3.3.5. Query Context",
|
||||
"number": "3.3.5."
|
||||
"chapterTitle": "3.3.6. Query Context",
|
||||
"number": "3.3.6."
|
||||
}
|
||||
],
|
||||
"chapterTitle": "3.3. Module Links",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -220,6 +220,11 @@ export const sidebars = [
|
||||
path: "/learn/fundamentals/module-links/custom-columns",
|
||||
title: "Add Custom Columns",
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
path: "/learn/fundamentals/module-links/read-only",
|
||||
title: "Read-Only Links",
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
path: "/learn/fundamentals/module-links/query-context",
|
||||
|
||||
@@ -30,7 +30,7 @@ module.exports = defineConfig({
|
||||
providers: [
|
||||
{
|
||||
resolve: "@medusajs/medusa/locking-postgres",
|
||||
id: "postgres-lock",
|
||||
id: "locking-postgres",
|
||||
// set this if you want this provider to be used by default
|
||||
// and you have other Locking Module Providers registered.
|
||||
is_default: true,
|
||||
@@ -72,7 +72,7 @@ module.exports = defineConfig({
|
||||
providers: [
|
||||
{
|
||||
resolve: "@medusajs/medusa/locking-postgres",
|
||||
id: "postgres-lock",
|
||||
id: "locking-postgres",
|
||||
is_default: true,
|
||||
},
|
||||
]
|
||||
|
||||
@@ -35,7 +35,7 @@ module.exports = defineConfig({
|
||||
providers: [
|
||||
{
|
||||
resolve: "@medusajs/medusa/locking-redis",
|
||||
id: "redis-lock",
|
||||
id: "locking-redis",
|
||||
// set this if you want this provider to be used by default
|
||||
// and you have other Locking Module Providers registered.
|
||||
is_default: true,
|
||||
@@ -253,7 +253,7 @@ module.exports = defineConfig({
|
||||
providers: [
|
||||
{
|
||||
resolve: "@medusajs/medusa/locking-redis",
|
||||
id: "redis-lock",
|
||||
id: "locking-redis",
|
||||
is_default: true,
|
||||
options: {
|
||||
// ...
|
||||
|
||||
@@ -55,34 +55,6 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "category",
|
||||
"title": "Server Guides",
|
||||
"autogenerate_tags": "server+auth",
|
||||
"autogenerate_as_ref": true,
|
||||
"sort_sidebar": "alphabetize",
|
||||
"description": "Learn how to use the API Key Module in your customizations on the Medusa application server.",
|
||||
"children": [
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "Create Actor Type",
|
||||
"path": "https://docs.medusajs.com/resources/commerce-modules/auth/create-actor-type",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "Create Auth Provider",
|
||||
"path": "https://docs.medusajs.com/resources/references/auth/provider",
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
@@ -504,28 +476,12 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
"sort_sidebar": "alphabetize",
|
||||
"description": "Learn how to use the Auth Module in your customizations on the Medusa application server.",
|
||||
"children": [
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "Create Actor Type",
|
||||
"path": "https://docs.medusajs.com/resources/commerce-modules/auth/create-actor-type",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"path": "/commerce-modules/auth/create-actor-type",
|
||||
"title": "Create an Actor Type",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "Create Auth Provider",
|
||||
"path": "https://docs.medusajs.com/resources/references/auth/provider",
|
||||
"title": "Create Actor Type",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
@@ -1115,14 +1071,6 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
"sort_sidebar": "alphabetize",
|
||||
"description": "Learn how to use the Cart Module in your customizations on the Medusa application server.",
|
||||
"children": [
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "Extend Cart",
|
||||
"path": "https://docs.medusajs.com/resources/commerce-modules/cart/extend",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
@@ -2433,14 +2381,6 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
"sort_sidebar": "alphabetize",
|
||||
"description": "Learn how to use the Customer Module in your customizations on the Medusa application server.",
|
||||
"children": [
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "Extend Customer",
|
||||
"path": "https://docs.medusajs.com/resources/commerce-modules/customer/extend",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
@@ -3374,14 +3314,6 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
"sort_sidebar": "alphabetize",
|
||||
"description": "Learn how to use the Fulfillment Module in your customizations on the Medusa application server.",
|
||||
"children": [
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "Create Fulfillment Provider",
|
||||
"path": "https://docs.medusajs.com/resources/references/fulfillment/provider",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
@@ -4933,14 +4865,6 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
"title": "Links to Modules",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "Inventory Kits",
|
||||
"path": "https://docs.medusajs.com/resources/commerce-modules/inventory/inventory-kit",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
@@ -8876,14 +8800,6 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
"path": "/references/payment/provider",
|
||||
"title": "Create Payment Provider",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "Create Payment Provider",
|
||||
"path": "https://docs.medusajs.com/resources/references/payment/provider",
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -11100,14 +11016,6 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
"title": "Extend Module",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "Extend Product",
|
||||
"path": "https://docs.medusajs.com/resources/commerce-modules/product/extend",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
@@ -11116,14 +11024,6 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
"title": "Get Variant Price with Taxes",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "Get Variant Price with Taxes",
|
||||
"path": "https://docs.medusajs.com/resources/commerce-modules/product/guides/price-with-taxes",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
@@ -11131,22 +11031,6 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
"path": "/commerce-modules/product/guides/price",
|
||||
"title": "Get Variant Prices",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "Get Variant Prices",
|
||||
"path": "https://docs.medusajs.com/resources/commerce-modules/product/guides/price",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "Implement Product Reviews in Medusa",
|
||||
"path": "https://docs.medusajs.com/resources/how-to-tutorials/tutorials/product-reviews",
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -12826,14 +12710,6 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
"path": "/commerce-modules/promotion/extend",
|
||||
"title": "Extend Module",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "Extend Promotion",
|
||||
"path": "https://docs.medusajs.com/resources/commerce-modules/promotion/extend",
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -15580,9 +15456,9 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"type": "link",
|
||||
"path": "/references/tax/provider",
|
||||
"title": "Create Tax Provider",
|
||||
"path": "https://docs.medusajs.com/resources/references/tax/provider",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
@@ -15592,14 +15468,6 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
"title": "Get Variant Price with Taxes",
|
||||
"path": "https://docs.medusajs.com/resources/commerce-modules/product/guides/price-with-taxes",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"path": "/references/tax/provider",
|
||||
"title": "Tax Provider Reference",
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -32,7 +32,7 @@ export const apiKeySidebar = [
|
||||
{
|
||||
type: "category",
|
||||
title: "Server Guides",
|
||||
autogenerate_tags: "server+auth",
|
||||
autogenerate_tags: "server+apiKey",
|
||||
autogenerate_as_ref: true,
|
||||
sort_sidebar: "alphabetize",
|
||||
description:
|
||||
|
||||
@@ -56,7 +56,7 @@ export const authSidebar = [
|
||||
{
|
||||
type: "link",
|
||||
path: "/commerce-modules/auth/create-actor-type",
|
||||
title: "Create an Actor Type",
|
||||
title: "Create Actor Type",
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
|
||||
@@ -51,7 +51,7 @@ export const taxSidebar = [
|
||||
{
|
||||
type: "link",
|
||||
path: "/references/tax/provider",
|
||||
title: "Tax Provider Reference",
|
||||
title: "Create Tax Provider",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -117,6 +117,7 @@ const sidebarMappings: {
|
||||
"/test-tools-reference",
|
||||
"/references/workflows",
|
||||
"/references-overview",
|
||||
"/references/medusa-workflows",
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -123,7 +123,7 @@ async function getAutogeneratedTagSidebarItems(
|
||||
return true
|
||||
}
|
||||
|
||||
return existingItem.path !== tagItem.path
|
||||
return !tagItem.path.endsWith(existingItem.path)
|
||||
})
|
||||
: true
|
||||
})
|
||||
|
||||
@@ -18,4 +18,6 @@ exceptions:
|
||||
- the second module
|
||||
- the module provider
|
||||
- the specified module
|
||||
- the associated module
|
||||
- the associated module
|
||||
- the stored module
|
||||
- the read-only module
|
||||
Reference in New Issue
Block a user