docs: prepare configuration (#7877)

* update configuration

* resolve todos + remove events guides

* disable v2 docs in v1 navbar

* remove v2 from v1 mobile sidebar

* resolve build errors

* fix build errors

* fix lint errors

* fix lint
This commit is contained in:
Shahed Nasser authored and GitHub committed 2024-07-03 19:27:13 +03:00
1 parent 012a624ee4
commit 6713d76db3
57 files changed
+1456 -1736

No files matched your search

@@ -41,6 +41,7 @@ const Navbar = () => {
}}
additionalActionsBefore={<VersionSwitcher />}
additionalActionsAfter={<FeedbackModal />}
showSearchOpener
isLoading={isLoading}
/>
)
+1
View File
@@ -12,6 +12,7 @@ const nextConfig = {
destination: `${
process.env.NEXT_PUBLIC_DOCS_URL || "https://localhost:3001"
}/:path*`,
basePath: false,
},
],
}
@@ -53,7 +53,7 @@ import { model } from "@medusajs/utils"
const MyCustom = model.define("my_custom", {
id: model.id().primaryKey(),
name: model.text(),
age: model.number()
age: model.number(),
}).indexes([
{
on: ["name", "age"],
@@ -82,13 +82,13 @@ import { model } from "@medusajs/utils"
const MyCustom = model.define("my_custom", {
id: model.id().primaryKey(),
name: model.text(),
age: model.number()
age: model.number(),
}).indexes([
{
on: ["name", "age"],
where: {
age: 30
}
age: 30,
},
},
])
@@ -111,15 +111,15 @@ import { model } from "@medusajs/utils"
const MyCustom = model.define("my_custom", {
id: model.id().primaryKey(),
name: model.text(),
age: model.number().nullable()
age: model.number().nullable(),
}).indexes([
{
on: ["name", "age"],
where: {
age: {
$ne: null
}
}
$ne: null,
},
},
},
])
@@ -146,11 +146,11 @@ import { model } from "@medusajs/utils"
const MyCustom = model.define("my_custom", {
id: model.id().primaryKey(),
name: model.text(),
age: model.number()
age: model.number(),
}).indexes([
{
on: ["name", "age"],
unique: true
unique: true,
},
])
@@ -41,25 +41,6 @@ A subscriber file must export:
The above subscriber listens to the `product.created` event. Whenever the event is emitted, it logs in the terminal `A product is created`.
{/* TODO add when we have the admin dashboard to use with V2 for easy testing. */}
{/\* ### Test Subscriber
To test the subscriber, start the Medusa application:
```bash npm2yarn
npm run dev
```
Then, create a product using the Medusa Admin dashboard. Afterward, you’ll see the following messages logged in the terminal:
```bash
info: Processing product.created which has 1 subscribers
A product is created
```
The first message indicates that the `product.created` event was emitted, and the second one is the message logged from the subscriber. \*/}
---
## When to Use Subscribers
@@ -31,6 +31,7 @@ const Navbar = () => {
mobileSidebarOpen,
}}
isLoading={false}
showSearchOpener
/>
)
}
+8 -1
View File
@@ -108,6 +108,13 @@ const nextConfig = {
}/v2/resources/:path*`,
basePath: false,
},
{
source: "/v2/api/:path*",
destination: `${
process.env.NEXT_PUBLIC_API_URL || "https://localhost:3001"
}/v2/api/:path*`,
basePath: false,
},
// TODO comment out once we have the user guide published
// {
// source: "/user-guide",
@@ -122,7 +129,7 @@ const nextConfig = {
{
source: "/:path*",
destination: `${
process.env.NEXT_PUBLIC_DOCS_V1_URL || "https://localhost:3000"
process.env.NEXT_PUBLIC_API_V1_URL || "https://localhost:3001"
}/:path*`,
basePath: false,
},
@@ -91,6 +91,4 @@ The `create` method accepts an object or an array of objects having the followin
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). */}
For a full list of properties accepted, refer to [this guide](/references/notification-provider-module#create).
+270 -285
View File
@@ -36,8 +36,7 @@ You can create a sales channel through the Medusa Admin or Admin REST APIs.
{/* TODO add links */}
<CardList
items={[
<CardList items={[
{
href: "#",
title: "Option 1: Use Medusa Admin",
@@ -46,18 +45,17 @@ You can create a sales channel through the Medusa Admin or Admin REST APIs.
showLinkIcon: false,
badge: {
variant: "blue",
children: "Guide Soon",
},
children: "Guide Soon"
}
},
{
href: "!api!/api/admin#sales-channels_postsaleschannels",
title: "Option 2: Using the REST APIs",
text: "Create the sales channel using the REST APIs.",
startIcon: <AcademicCapSolid />,
showLinkIcon: false,
showLinkIcon: false
},
]}
/>
]} />
---
@@ -76,8 +74,7 @@ You can create a publishable API key through the Medusa Admin or the Admin REST
### Create Key
<CardList
items={[
<CardList items={[
{
href: "#",
title: "Option 1: Use Medusa Admin",
@@ -86,25 +83,23 @@ You can create a publishable API key through the Medusa Admin or the Admin REST
showLinkIcon: false,
badge: {
variant: "blue",
children: "Guide Soon",
},
children: "Guide Soon"
}
},
{
href: "!api!/api/admin#api-keys_postapikeys",
title: "Option 2: Using the REST APIs",
text: "Create the publishable API key using the REST APIs.",
startIcon: <AcademicCapSolid />,
showLinkIcon: false,
showLinkIcon: false
},
]}
/>
]} />
### Associate Key with Sales Channel
{/* TODO add links */}
<CardList
items={[
<CardList items={[
{
href: "#",
title: "Option 1: Use Medusa Admin",
@@ -113,18 +108,17 @@ You can create a publishable API key through the Medusa Admin or the Admin REST
showLinkIcon: false,
badge: {
variant: "blue",
children: "Guide Soon",
},
children: "Guide Soon"
}
},
{
href: "#",
title: "Option 2: Using the REST APIs",
text: "Associate the publishable API key with the B2B sales channel using the REST APIs.",
startIcon: <AcademicCapSolid />,
showLinkIcon: false,
showLinkIcon: false
},
]}
/>
]} />
---
@@ -136,8 +130,7 @@ You can create new products or add existing ones to the B2B sales channel using
{/* TODO add links */}
<CardList
items={[
<CardList items={[
{
href: "#",
title: "Using Medusa Admin",
@@ -146,25 +139,23 @@ You can create new products or add existing ones to the B2B sales channel using
showLinkIcon: false,
badge: {
variant: "blue",
children: "Guide Soon",
},
children: "Guide Soon"
}
},
{
href: "!api!/api/admin#products_postproducts",
title: "Using REST APIs",
text: "Create products using the REST APIs.",
startIcon: <AcademicCapSolid />,
showLinkIcon: false,
showLinkIcon: false
},
]}
/>
]} />
### Add Products to Sales Channel
{/* TODO add links */}
<CardList
items={[
<CardList items={[
{
href: "#",
title: "Using Medusa Admin",
@@ -173,18 +164,17 @@ You can create new products or add existing ones to the B2B sales channel using
showLinkIcon: false,
badge: {
variant: "blue",
children: "Guide Soon",
},
children: "Guide Soon"
}
},
{
href: "!api!/api/admin#sales-channels_postsaleschannelsidproductsbatchadd",
title: "Using REST APIs",
text: "Add the products to the B2B sales channel using the REST APIs.",
startIcon: <AcademicCapSolid />,
showLinkIcon: false,
showLinkIcon: false
},
]}
/>
]} />
---
@@ -202,108 +192,106 @@ Module Relationships is coming soon.
</Note>
<CardList
items={[
<CardList items={[
{
href: "!docs!/basics/modules-and-services",
title: "Create Module",
text: "Learn how to create a module in Medusa.",
startIcon: <AcademicCapSolid />,
showLinkIcon: false,
showLinkIcon: false
},
{
href: "!docs!/basics/data-models",
title: "Create Data Models",
text: "Learn how to create data models.",
startIcon: <AcademicCapSolid />,
showLinkIcon: false,
showLinkIcon: false
},
]}
/>
]} />
{/_ <Card
href="!docs!/advanced-development/modules/module-relationships"
title="Create Module Relationships"
text="Learn how to create a relationship between modules."
startIcon={<AcademicCapSolid />}
showLinkIcon={false}
className="mt-1"
/> _/}
{/* <Card
href="!docs!/advanced-development/modules/module-relationships"
title="Create Module Relationships"
text="Learn how to create a relationship between modules."
startIcon={<AcademicCapSolid />}
showLinkIcon={false}
className="mt-1"
/> */}
{/\* <Details summaryContent="Example">
In this section, you'll create a B2B module that has a `Company` data model. The `Company` data model has a relationship to the `CustomerGroup` data model of the Customer Module.
{/* <Details summaryContent="Example">
In this section, you'll create a B2B module that has a `Company` data model. The `Company` data model has a relationship to the `CustomerGroup` data model of the Customer Module.
Start by creating the `src/modules/b2b` directory.
Start by creating the `src/modules/b2b` directory.
Then, create the file `src/modules/b2b/models/company.ts` with the following content:
Then, create the file `src/modules/b2b/models/company.ts` with the following content:
```ts title="src/modules/b2b/models/company.ts" highlights={[["8", "", "The property will be used to create a relationship to customer groups."]]}
import { model } from "@medusajs/utils"
```ts title="src/modules/b2b/models/company.ts" highlights={[["8", "", "The property will be used to create a relationship to customer groups."]]}
import { model } from "@medusajs/utils"
const Company = model.define("company", {
const Company = model.define("company", {
id: model.id().primaryKey(),
name: model.text(),
city: model.text(),
country_code: model.text(),
customer_group_id: model.text().nullable(),
})
})
export default Company
```
export default Company
```
This creates a `Company` data model with some relevant properties. Most importantly, it has a `customer_group_id` property. It'll later be used when creating the relationship to the `CustomerGroup` data model in the Customer Module.
This creates a `Company` data model with some relevant properties. Most importantly, it has a `customer_group_id` property. It'll later be used when creating the relationship to the `CustomerGroup` data model in the Customer Module.
Next, create the migration in the file `src/modules/b2b/migrations/Migration20240516081502.ts` with the following content:
Next, create the migration in the file `src/modules/b2b/migrations/Migration20240516081502.ts` with the following content:
```ts title="src/modules/b2b/migrations/Migration20240516081502.ts"
import { Migration } from "@mikro-orm/migrations"
```ts title="src/modules/b2b/migrations/Migration20240516081502.ts"
import { Migration } from "@mikro-orm/migrations"
export class Migration20240516081502 extends Migration {
export class Migration20240516081502 extends Migration {
async up(): Promise<void> {
this.addSql(
'create table if not exists "company" ("id" text not null, "name" text not null, "city" text not null, "country_code" text not null, "customer_group_id" text not null, constraint "company_pkey" primary key ("id"));'
)
this.addSql("create table if not exists \"company\" (\"id\" text not null, \"name\" text not null, \"city\" text not null, \"country_code\" text not null, \"customer_group_id\" text not null, constraint \"company_pkey\" primary key (\"id\"));")
}
async down(): Promise<void> {
this.addSql('drop table if exists "company" cascade;')
this.addSql("drop table if exists \"company\" cascade;")
}
}
```
}
```
You'll run the migration to reflect the data model in the database after finishing the module definition.
You'll run the migration to reflect the data model in the database after finishing the module definition.
Then, create the module's main service at `src/modules/b2b/service.ts` with the following content:
Then, create the module's main service at `src/modules/b2b/service.ts` with the following content:
```ts title="src/modules/b2b/service.ts"
import { MedusaService } from "@medusajs/utils"
import Company from "./models/company"
```ts title="src/modules/b2b/service.ts"
import { MedusaService } from "@medusajs/utils"
import Company from "./models/company"
class B2bModuleService extends MedusaService({
class B2bModuleService extends MedusaService({
Company,
}) {
}){
// TODO add custom methods
}
}
export default B2bModuleService
```
export default B2bModuleService
```
This creates a `B2bModuleService` that extends the service factory, which generates data-management functionalities for the `Company` data model.
This creates a `B2bModuleService` that extends the service factory, which generates data-management functionalities for the `Company` data model.
Next, create the module definition at `src/modules/b2b/index.ts` with the following content:
Next, create the module definition at `src/modules/b2b/index.ts` with the following content:
```ts title="src/modules/b2b/index.ts"
import B2bModuleService from "./service"
```ts title="src/modules/b2b/index.ts"
import B2bModuleService from "./service"
import { Module } from "@medusajs/utils"
export default {
export default Module("b2b", {
service: B2bModuleService,
}
```
})
```
Finally, add the module to the `modules` object in `medusa-config.js`:
Finally, add the module to the `modules` object in `medusa-config.js`:
```js title="medusa-config.js"
module.exports = defineConfig({
```js title="medusa-config.js"
module.exports = defineConfig({
// ...
modules: {
b2bModuleService: {
@@ -313,95 +301,90 @@ module.exports = defineConfig({
},
},
},
})
```
})
```
You can now run migrations with the following commands:
You can now run migrations with the following commands:
```bash npm2yarn
npx medusa migrations run
```
```bash npm2yarn
npx medusa migrations run
```
### Add Create Company API Route
### Add Create Company API Route
To test out using the B2B Module, you'll add an API route to create a company.
To test out using the B2B Module, you'll add an API route to create a company.
Start by creating the file `src/types/b2b/index.ts` with some helper types:
Start by creating the file `src/types/b2b/index.ts` with some helper types:
```ts title="src/types/b2b/index.ts"
import { CustomerGroupDTO } from "@medusajs/types"
```ts title="src/types/b2b/index.ts"
import { CustomerGroupDTO } from "@medusajs/types"
export type CompanyDTO = {
export type CompanyDTO = {
id: string
name: string
city: string
country_code: string
customer_group_id?: string
customer_group?: CustomerGroupDTO
}
}
export type CreateCompanyDTO = {
export type CreateCompanyDTO = {
name: string
city: string
country_code: string
customer_group_id?: string
}
```
}
Then, create the file `src/workflows/create-company.ts` with the following content:
```
Then, create the file `src/workflows/create-company.ts` with the following content:
export const workflowHighlights = [
[
"23",
"tryToCreateCustomerGroupStep",
"This step creates the customer group if its data is passed in the `customer_group` property.",
],
[
"36",
"createCustomerGroupsWorkflow",
"Use the `createCustomerGroupsWorkflow` defined by Medusa to create the customer group.",
],
[
"44",
"",
"Set the ID of the new customer group in the `customer_group_id` property so that it's added to the created company.",
],
["23", "tryToCreateCustomerGroupStep", "This step creates the customer group if its data is passed in the `customer_group` property."],
["36", "createCustomerGroupsWorkflow", "Use the `createCustomerGroupsWorkflow` defined by Medusa to create the customer group."],
["44", "", "Set the ID of the new customer group in the `customer_group_id` property so that it's added to the created company."],
["54", "createCompanyStep", "This step creates the company."],
]
```ts title="src/workflows/create-company.ts" highlights={workflowHighlights} collapsibleLines="1-12" expandButtonLabel="Show Imports"
import {
```ts title="src/workflows/create-company.ts" highlights={workflowHighlights} collapsibleLines="1-12" expandButtonLabel="Show Imports"
import {
StepResponse,
createStep,
createWorkflow,
} from "@medusajs/workflows-sdk"
import { createCustomerGroupsWorkflow } from "@medusajs/core-flows"
import { CreateCustomerGroupDTO } from "@medusajs/types"
import { CompanyDTO, CreateCompanyDTO } from "../types/b2b"
import B2bModuleService from "../modules/b2b/service"
} from "@medusajs/workflows-sdk"
import {
createCustomerGroupsWorkflow,
} from "@medusajs/core-flows"
import { CreateCustomerGroupDTO } from "@medusajs/types"
import { CompanyDTO, CreateCompanyDTO } from "../types/b2b"
import B2bModuleService from "../modules/b2b/service"
export type CreateCompanyWorkflowInput = CreateCompanyDTO & {
export type CreateCompanyWorkflowInput = CreateCompanyDTO & {
customer_group?: CreateCustomerGroupDTO
}
}
type CreateCompanyWorkflowOutput = {
type CreateCompanyWorkflowOutput = {
company: CompanyDTO
}
}
type CreateCustomerGroupStepInput = CreateCompanyWorkflowInput
type CreateCustomerGroupStepInput = CreateCompanyWorkflowInput
const tryToCreateCustomerGroupStep = createStep(
const tryToCreateCustomerGroupStep = createStep(
"try-to-create-customer-group-step",
async (
{ customer_group, ...company }: CreateCustomerGroupStepInput,
{ container }
) => {
{
customer_group,
...company
}: CreateCustomerGroupStepInput,
{ container }) => {
if (!customer_group) {
return new StepResponse({ company })
}
// create customer group
const { result } = await createCustomerGroupsWorkflow(container).run({
const { result } = await createCustomerGroupsWorkflow(
container
).run({
input: {
customersData: [customer_group],
},
@@ -411,99 +394,114 @@ const tryToCreateCustomerGroupStep = createStep(
return new StepResponse({ company })
}
)
)
export type CreateCompanyStep = {
export type CreateCompanyStep = {
companyData: CreateCompanyDTO
}
}
const createCompanyStep = createStep(
const createCompanyStep = createStep(
"create-company-step",
async ({ companyData }: CreateCompanyStep, { container }) => {
const b2bModuleService: B2bModuleService =
container.resolve("b2bModuleService")
async (
{ companyData }: CreateCompanyStep,
{ container }) => {
const b2bModuleService: B2bModuleService = container
.resolve(
"b2bModuleService"
)
const company = await b2bModuleService.createCompany(companyData)
const company = await b2bModuleService.createCompany(
companyData
)
return new StepResponse({ company })
}
)
)
export const createCompanyWorkflow = createWorkflow<
export const createCompanyWorkflow = createWorkflow<
CreateCompanyWorkflowInput,
CreateCompanyWorkflowOutput
>("create-company", function (input) {
const { company: companyData } = tryToCreateCustomerGroupStep(input)
>(
"create-company",
function (input) {
const {
company: companyData,
} = tryToCreateCustomerGroupStep(input)
const company = createCompanyStep({ companyData })
return company
})
```
}
)
```
You create a workflow with two steps:
You create a workflow with two steps:
1. The first one tries to create a customer group if its data is provided in the `customer_group` property and sets its value in the `customer_group_id` property.
2. The second one creates the company.
1. The first one tries to create a customer group if its data is provided in the `customer_group` property and sets its value in the `customer_group_id` property.
2. The second one creates the company.
Finally, create the file `src/api/admin/b2b/company/route.ts` with the following content:
Finally, create the file `src/api/admin/b2b/company/route.ts` with the following content:
```ts title="src/api/admin/b2b/company/route.ts" collapsibleLines="1-9" expandButtonLabel="Show Imports"
import type { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
import {
```ts title="src/api/admin/b2b/company/route.ts" collapsibleLines="1-9" expandButtonLabel="Show Imports"
import type {
MedusaRequest,
MedusaResponse,
} from "@medusajs/medusa"
import {
CreateCompanyWorkflowInput,
createCompanyWorkflow,
} from "../../../../workflows/create-company"
} from "../../../../workflows/create-company"
type CreateCompanyReq = CreateCompanyWorkflowInput
type CreateCompanyReq = CreateCompanyWorkflowInput
export async function POST(
export async function POST(
req: MedusaRequest<CreateCompanyReq>,
res: MedusaResponse
) {
const { result } = await createCompanyWorkflow(req.scope).run({
) {
const { result } = await createCompanyWorkflow(req.scope)
.run({
input: req.body,
})
res.json({
company: result.company,
})
}
```
}
```
The API route uses the workflow to create the company. It passes the request body as the workflow's input.
The API route uses the workflow to create the company. It passes the request body as the workflow's input.
### Test API Route
### Test API Route
To test the API route, start the Medusa application:
To test the API route, start the Medusa application:
```bash npm2yarn
npm run dev
```
```bash npm2yarn
npm run dev
```
Next, make sure you authenticate as an admin user as explained in [this Authentication guide](!api!/api/admin#authentication).
Next, make sure you authenticate as an admin user as explained in [this Authentication guide](!api!/api/admin#authentication).
Then, send a `POST` request to the `/admin/b2b/company` API route:
Then, send a `POST` request to the `/admin/b2b/company` API route:
```bash
curl -X POST 'localhost:9000/admin/b2b/company' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {jwt_token}' \
--data '{
```bash
curl -X POST 'localhost:9000/admin/b2b/company' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {jwt_token}' \
--data '{
"name": "Acme",
"city": "London",
"country_code": "gb",
"customer_group": {
"name": "B2B"
}
}'
```
}'
```
This creates a company and its associated customer group.
This creates a company and its associated customer group.
<Note title="Tip">
You can alternatively pass a `customer_group_id` to use an existing customer group.
You can alternatively pass a `customer_group_id` to use an existing customer group.
</Note>
@@ -519,8 +517,7 @@ You can do that through the Medusa Admin or Admin REST APIs.
{/* TODO add links */}
<CardList
items={[
<CardList items={[
{
href: "#",
title: "Option 1: Use Medusa Admin",
@@ -529,25 +526,23 @@ You can do that through the Medusa Admin or Admin REST APIs.
showLinkIcon: false,
badge: {
variant: "blue",
children: "Guide Soon",
},
children: "Guide Soon"
}
},
{
href: "!api!/api/admin#customers_postcustomers",
title: "Option 2: Using the REST APIs",
text: "Create the customers using the REST APIs.",
startIcon: <AcademicCapSolid />,
showLinkIcon: false,
showLinkIcon: false
},
]}
/>
]} />
### Assign Customers to Groups
{/* TODO add links */}
<CardList
items={[
<CardList items={[
{
href: "#",
title: "Option 1: Use Medusa Admin",
@@ -556,18 +551,17 @@ You can do that through the Medusa Admin or Admin REST APIs.
showLinkIcon: false,
badge: {
variant: "blue",
children: "Guide Soon",
},
children: "Guide Soon"
}
},
{
href: "!api!/api/admin#customer-groups_postcustomergroupsidcustomersbatch",
title: "Option 2: Using the REST APIs",
text: "Assign the customers to the B2B customer group using the REST APIs.",
startIcon: <AcademicCapSolid />,
showLinkIcon: false,
showLinkIcon: false
},
]}
/>
]} />
---
@@ -579,8 +573,7 @@ You can create a price list using the Medusa Admin or the Admin REST APIs. Make
{/* TODO add links */}
<CardList
items={[
<CardList items={[
{
href: "#",
title: "Using Medusa Admin",
@@ -589,18 +582,17 @@ You can create a price list using the Medusa Admin or the Admin REST APIs. Make
showLinkIcon: false,
badge: {
variant: "blue",
children: "Guide Soon",
},
children: "Guide Soon"
}
},
{
href: "!api!/api/admin#price-lists_postpricelists",
title: "Using REST APIs",
text: "Create the price list using the REST APIs.",
startIcon: <AcademicCapSolid />,
showLinkIcon: false,
showLinkIcon: false
},
]}
/>
]} />
---
@@ -634,42 +626,34 @@ The API route can check if the customer has any group with an associated company
showLinkIcon={false}
/>
{/\* <Details summaryContent="Example">
{/* <Details summaryContent="Example">
For example, create the API route `src/api/store/b2b/check-customer/route.ts` with the following content:
For example, create the API route `src/api/store/b2b/check-customer/route.ts` with the following content:
export const checkCustomerHighlights = [
["19", "retrieveCustomer", "Retrieve the customer along with its groups."],
[
"26",
"listCompanies",
"List the companies that have a customer group ID matching any of the customer's group IDs.",
],
[
"31",
"",
"Return whether there are any companies associated with the customer's groups.",
],
["26", "listCompanies", "List the companies that have a customer group ID matching any of the customer's group IDs."],
["31", "", "Return whether there are any companies associated with the customer's groups."]
]
```ts title="src/api/store/b2b/check-customer/route.ts" highlights={checkCustomerHighlights} collapsibleLines="1-5" expandButtonLabel="Show Imports"
import type {
```ts title="src/api/store/b2b/check-customer/route.ts" highlights={checkCustomerHighlights} collapsibleLines="1-5" expandButtonLabel="Show Imports"
import type {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "@medusajs/medusa"
import { ModuleRegistrationName } from "@medusajs/utils"
import { ICustomerModuleService } from "@medusajs/types"
import B2bModuleService from "../../../../modules/b2b/service"
} from "@medusajs/medusa"
import { ModuleRegistrationName } from "@medusajs/utils"
import { ICustomerModuleService } from "@medusajs/types"
import B2bModuleService from "../../../../modules/b2b/service"
export async function GET(
export async function GET(
req: AuthenticatedMedusaRequest,
res: MedusaResponse
) {
const customerModuleService: ICustomerModuleService = req.scope.resolve(
ModuleRegistrationName.CUSTOMER
) {
const customerModuleService: ICustomerModuleService = req
.scope.resolve(ModuleRegistrationName.CUSTOMER)
const b2bModuleService: B2bModuleService = req.scope.resolve(
"b2bModuleService"
)
const b2bModuleService: B2bModuleService =
req.scope.resolve("b2bModuleService")
const customer = await customerModuleService.retrieveCustomer(
req.auth_context.actor_id,
@@ -685,75 +669,80 @@ export async function GET(
res.json({
is_b2b: companies.length > 0,
})
}
```
}
```
This creates a `GET` API Route at `/store/b2b/check-customer` that:
This creates a `GET` API Route at `/store/b2b/check-customer` that:
1. Retrieves the customer along with its groups using the Customer Module's main service.
2. Lists the companies that have a customer group ID matching any of the customer's group IDs.
3. Return an `is_b2b` field whose value is `true` if there are any companies associated with the customer's groups.
1. Retrieves the customer along with its groups using the Customer Module's main service.
2. Lists the companies that have a customer group ID matching any of the customer's group IDs.
3. Return an `is_b2b` field whose value is `true` if there are any companies associated with the customer's groups.
Before using the API route, create the file `src/api/middlewares.ts` with the following content:
Before using the API route, create the file `src/api/middlewares.ts` with the following content:
```ts title="src/api/middlewares.ts"
import { MiddlewaresConfig, authenticate } from "@medusajs/medusa"
```ts title="src/api/middlewares.ts"
import {
MiddlewaresConfig,
authenticate,
} from "@medusajs/medusa"
export const config: MiddlewaresConfig = {
export const config: MiddlewaresConfig = {
routes: [
{
matcher: "/store/b2b*",
middlewares: [authenticate("store", ["bearer", "session"])],
middlewares: [
authenticate("store", ["bearer", "session"]),
],
},
],
}
```
}
```
This ensures that only logged-in customers can use the API route.
This ensures that only logged-in customers can use the API route.
### Test API Route
### Test API Route
To test out the API route:
To test out the API route:
1. Start the Medusa application.
2. Obtain an authentication JWT token for a new customer. Do that by sending a `POST` request to the `/auth/store/emailpass` API Route:
1. Start the Medusa application.
2. Obtain an authentication JWT token for a new customer. Do that by sending a `POST` request to the `/auth/store/emailpass` API Route:
```bash
curl -X POST 'http://localhost:9000/auth/store/emailpass' \
-H 'Content-Type: application/json' \
--data-raw '{
```bash
curl -X POST 'http://localhost:9000/auth/store/emailpass' \
-H 'Content-Type: application/json' \
--data-raw '{
"email": "test@medusajs.com",
"password": "supersecret"
}'
```
}'
```
3. Send a `POST` request to the `/store/customers` API route that registers the customer. Make sure to pass the authentication JWT token from the previous token in the header:
3. Send a `POST` request to the `/store/customers` API route that registers the customer. Make sure to pass the authentication JWT token from the previous token in the header:
```bash
curl -X POST 'http://localhost:9000/store/customers' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer {jwt_token}' \
--data-raw '{
```bash
curl -X POST 'http://localhost:9000/store/customers' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer {jwt_token}' \
--data-raw '{
"email": "test@medusajs.com",
"password": "supersecret"
}'
```
}'
```
4. Add the customer to the B2B group as explained in a [previous section](#add-b2b-customers).
5. Send a `GET` request to the `/store/b2b/check-customer` API route you created in this section:
4. Add the customer to the B2B group as explained in a [previous section](#add-b2b-customers).
5. Send a `GET` request to the `/store/b2b/check-customer` API route you created in this section:
```bash
curl 'http://localhost:9000/store/b2b/check-customer' \
--header 'Authorization: Bearer {jwt_token}'
```
```bash
curl 'http://localhost:9000/store/b2b/check-customer' \
--header 'Authorization: Bearer {jwt_token}'
```
You'll receive a JSON response as the following:
You'll receive a JSON response as the following:
```json
{
```json
{
"is_b2b": true
}
```
}
```
</Details> */}
@@ -765,31 +754,29 @@ Based on your use case, you may need to customize the Medusa Admin to add new wi
The Medusa Admin plugin can be extended to add widgets, new pages, and setting pages.
<CardList
items={[
<CardList items={[
{
href: "!docs!/advanced-development/admin/widgets",
title: "Create Admin Widget",
text: "Learn how to add widgets into existing admin pages.",
startIcon: <AcademicCapSolid />,
showLinkIcon: false,
showLinkIcon: false
},
{
href: "!docs!/advanced-development/admin/ui-routes",
title: "Create Admin UI Routes",
text: "Learn how to add new pages to your Medusa Admin.",
startIcon: <AcademicCapSolid />,
showLinkIcon: false,
showLinkIcon: false
},
{
href: "!docs!/advanced-development/admin/setting-pages",
title: "Create Admin Setting Page",
text: "Learn how to add new page to the Medusa Admin settings.",
startIcon: <AcademicCapSolid />,
showLinkIcon: false,
showLinkIcon: false
},
]}
/>
]} />
---
@@ -799,24 +786,22 @@ Medusa provides a Next.js storefront to use with your application. You can eithe
Use the publishable API key you associated with your B2B sales channel in the storefront to ensure only B2B products are retrieved.
<CardList
items={[
<CardList items={[
{
href: "/nextjs-starter",
title: "Next.js Storefront",
text: "Learn how to install and customize the Next.js storefront.",
startIcon: <AcademicCapSolid />,
showLinkIcon: false,
showLinkIcon: false
},
{
href: "/storefront-development",
title: "Storefront Development",
text: "Find guides for your storefront development.",
startIcon: <AcademicCapSolid />,
showLinkIcon: false,
showLinkIcon: false
},
]}
/>
]} />
<Card
href="!api!/api/store#publishable-api-key"
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -37,11 +37,11 @@ Then, resolve the module's main service in other resources, such as API routes o
<Details summaryContent="Example: Create a module integrating an ERP system">
This example showcases how to create a module that integrates to a dummy ERP system.
This example showcases how to create a module that integrates to a dummy ERP system.
Start by creating the directory `src/modules/erp` for your module.
Start by creating the directory `src/modules/erp` for your module.
Then, create the file `src/modules/erp/service.ts` with the following content:
Then, create the file `src/modules/erp/service.ts` with the following content:
export const serviceHighlights = [
["4", "ErpModuleOptions", "The module's expected options."],
@@ -56,12 +56,12 @@ export const serviceHighlights = [
import axios, { AxiosInstance } from "axios"
import { ProductDTO } from "@medusajs/types"
type ErpModuleOptions = {
apiKey: string
}
type ErpModuleOptions = {
apiKey: string
}
class ErpModuleService {
private client\_: AxiosInstance
class ErpModuleService {
private client_: AxiosInstance
constructor({}, { apiKey }: ErpModuleOptions) {
this.client_ = axios.create({
@@ -87,41 +87,40 @@ private client\_: AxiosInstance
async deleteProduct(id: string) {
await this.client_.delete(`/product/${id}`)
}
}
}
export default ErpModuleService
export default ErpModuleService
```
````
This creates the module's main service. Few things to note:
This creates the module's main service. Few things to note:
- The module accepts an `apiKey` option, used to authenticate to the dummy ERP system. The module's main service accesses this option in the second parameter of the constructor.
- The module uses axios to create a client in the constructor. The client is used in the service's methods when connecting to the ERP system. If the system you're integrating has an SDK, you can initialize it in the constructor, instead.
- The `getProductData` method retrieves a product's details from the ERP system by sending a `GET` request using the client.
- The `createProduct` method creates a product in the ERP system by sending a `POST` request using the client.
- The `deleteProduct` method deletes a product in the ERP system by sending a `DELETE` request using the client.
- The module accepts an `apiKey` option, used to authenticate to the dummy ERP system. The module's main service accesses this option in the second parameter of the constructor.
- The module uses axios to create a client in the constructor. The client is used in the service's methods when connecting to the ERP system. If the system you're integrating has an SDK, you can initialize it in the constructor, instead.
- The `getProductData` method retrieves a product's details from the ERP system by sending a `GET` request using the client.
- The `createProduct` method creates a product in the ERP system by sending a `POST` request using the client.
- The `deleteProduct` method deletes a product in the ERP system by sending a `DELETE` request using the client.
<Note title="Tip">
<Note title="Tip">
You can store the product's ID in the external system using the `metadata` property of the `Product` data model in the Product Module. Alternatively, you can create a [data model](!docs!/basics/data-models) in your module to store data related to the external system.
You can store the product's ID in the external system using the `metadata` property of the `Product` data model in the Product Module. Alternatively, you can create a [data model](!docs!/basics/data-models) in your module to store data related to the external system.
</Note>
</Note>
Then, create the module's definition file at `src/modules/erp/index.ts` with the following content:
Then, create the module's definition file at `src/modules/erp/index.ts` with the following content:
```ts title="src/modules/erp/index.ts"
import ErpModuleService from "./service"
```ts title="src/modules/erp/index.ts"
import ErpModuleService from "./service"
export default {
export default {
service: ErpModuleService,
}
````
}
````
Finally, add the module to the `modules` object in `medusa-config.js`:
Finally, add the module to the `modules` object in `medusa-config.js`:
```js title="medusa-config.js" highlights={[["7", "ERP_API_KEY", "The environment variable holding the API key of the ERP system."]]}
module.exports = defineConfig({
```js title="medusa-config.js" highlights={[["7", "ERP_API_KEY", "The environment variable holding the API key of the ERP system."]]}
module.exports = defineConfig({
// ...
modules: {
erpModuleService: {
@@ -131,8 +130,8 @@ module.exports = defineConfig({
},
},
},
})
```
})
```
</Details>
@@ -40,119 +40,113 @@ Module Relationships is coming soon.
</Note>
<CardList
items={[
<CardList items={[
{
href: "!docs!/basics/modules-and-services",
title: "Create a Module",
text: "Learn how to create a module",
startIcon: <AcademicCapSolid />,
showLinkIcon: false,
showLinkIcon: false
},
{
href: "!docs!/advanced-development/modules/module-relationships",
title: "Module Relationships",
text: "Create relationships between modules.",
startIcon: <AcademicCapSolid />,
showLinkIcon: false,
showLinkIcon: false
},
]}
/>
]} />
<Details summaryContent="Example">
In this section, you’ll create a Marketplace Module with the necessary relationships and functionalities in the main service.
In this section, you’ll create a Marketplace Module with the necessary relationships and functionalities in the main service.
Start by creating the directory `src/modules/marketplace`.
Start by creating the directory `src/modules/marketplace`.
Then, create the file `src/modules/marketplace/models/store-user.ts` with the following content:
Then, create the file `src/modules/marketplace/models/store-user.ts` with the following content:
```ts title="src/modules/marketplace/models/store-user.ts"
import { model } from "@medusajs/utils"
```ts title="src/modules/marketplace/models/store-user.ts"
import { model } from "@medusajs/utils"
const StoreUser = model.define("store_user", {
const StoreUser = model.define("store_user", {
id: model.id().primaryKey(),
store_id: model.text(),
user_id: model.text(),
})
})
export default StoreUser
```
export default StoreUser
```
This creates a `StoreUser` data model with the `store_id` and `user_id` properties.
This creates a `StoreUser` data model with the `store_id` and `user_id` properties.
{/* These properties will be used later to establish relationships to the Store and User modules. */}
{/* These properties will be used later to establish relationships to the Store and User modules. */}
Next, create the file `src/modules/marketplace/models/store-product.ts` with the following content:
Next, create the file `src/modules/marketplace/models/store-product.ts` with the following content:
```ts title="src/modules/marketplace/models/store-product.ts"
import { model } from "@medusajs/utils"
```ts title="src/modules/marketplace/models/store-product.ts"
import { model } from "@medusajs/utils"
const StoreProduct = model.define("store_user", {
const StoreProduct = model.define("store_user", {
id: model.id().primaryKey(),
store_id: model.text(),
product_id: model.text(),
})
})
export default StoreProduct
```
export default StoreProduct
```
This creates a `StoreProduct` data model with the `store_id` and `product_id` properties.
This creates a `StoreProduct` data model with the `store_id` and `product_id` properties.
{/* These properties will be used later to establish relationships to the Store and Product modules. */}
{/* These properties will be used later to establish relationships to the Store and Product modules. */}
Finally, create the file `src/modules/marketplace/models/store-order.ts` with the following content:
Finally, create the file `src/modules/marketplace/models/store-order.ts` with the following content:
```ts title="src/modules/marketplace/models/store-order.ts"
import { model } from "@medusajs/utils"
```ts title="src/modules/marketplace/models/store-order.ts"
import { model } from "@medusajs/utils"
const StoreOrder = model.define("store_user", {
const StoreOrder = model.define("store_user", {
id: model.id().primaryKey(),
store_id: model.text(),
order_id: model.text(),
parent_order_id: model.text(),
})
})
export default StoreOrder
```
export default StoreOrder
```
This creates a `StoreOrder` data model with the `store_id`, `order_id`, and `parent_order_id` properties.
This creates a `StoreOrder` data model with the `store_id`, `order_id`, and `parent_order_id` properties.
{/* The `store_id` and `order_id` properties will be used to establish relationships to the Store and Order modules. You’ll learn about the use of `parent_order_id` in a later section. */}
{/* The `store_id` and `order_id` properties will be used to establish relationships to the Store and Order modules. You’ll learn about the use of `parent_order_id` in a later section. */}
To reflect these changes on the database, create the migration `src/modules/marketplace/migrations/Migration20240514143248.ts` with the following content:
To reflect these changes on the database, create the migration `src/modules/marketplace/migrations/Migration20240514143248.ts` with the following content:
```ts title="src/modules/marketplace/migrations/Migration20240514143248.ts"
import { Migration } from "@mikro-orm/migrations"
```ts title="src/modules/marketplace/migrations/Migration20240514143248.ts"
import { Migration } from "@mikro-orm/migrations"
export class Migration20240514143248 extends Migration {
export class Migration20240514143248 extends Migration {
async up(): Promise<void> {
this.addSql(
'create table if not exists "store_order" ("id" varchar(255) not null, "store_id" text not null, "order_id" text not null, "parent_order_id" text not null, constraint "store_order_pkey" primary key ("id"));'
)
this.addSql("create table if not exists \"store_order\" (\"id\" varchar(255) not null, \"store_id\" text not null, \"order_id\" text not null, \"parent_order_id\" text not null, constraint \"store_order_pkey\" primary key (\"id\"));")
this.addSql(
'create table if not exists "store_product" ("id" varchar(255) not null, "store_id" text not null, "product_id" text not null, constraint "store_product_pkey" primary key ("id"));'
)
this.addSql("create table if not exists \"store_product\" (\"id\" varchar(255) not null, \"store_id\" text not null, \"product_id\" text not null, constraint \"store_product_pkey\" primary key (\"id\"));")
this.addSql(
'create table if not exists "store_user" ("id" varchar(255) not null, "store_id" text not null, "user_id" text not null, constraint "store_user_pkey" primary key ("id"));'
)
this.addSql("create table if not exists \"store_user\" (\"id\" varchar(255) not null, \"store_id\" text not null, \"user_id\" text not null, constraint \"store_user_pkey\" primary key (\"id\"));")
}
async down(): Promise<void> {
this.addSql('drop table if exists "store_order" cascade;')
this.addSql("drop table if exists \"store_order\" cascade;")
this.addSql('drop table if exists "store_product" cascade;')
this.addSql("drop table if exists \"store_product\" cascade;")
this.addSql('drop table if exists "store_user" cascade;')
this.addSql("drop table if exists \"store_user\" cascade;")
}
}
```
You’ll run the migration after registering the module in the Medusa configurations.
}
```
Then, create the module’s main service at `src/modules/marketplace/service.ts` with the following content:
You’ll run the migration after registering the module in the Medusa configurations.
Then, create the module’s main service at `src/modules/marketplace/service.ts` with the following content:
export const mainServiceHighlights = [
["6", "MedusaService", "Extends the service factory to generate data management features."]
@@ -164,34 +158,34 @@ export const mainServiceHighlights = [
import StoreProduct from "./models/store-product"
import StoreOrder from "./models/store-order"
class MarketplaceModuleService extends MedusaService({
StoreUser,
StoreProduct,
StoreOrder,
}){
// TODO add custom methods
}
class MarketplaceModuleService extends MedusaService({
StoreUser,
StoreProduct,
StoreOrder,
}){
// TODO add custom methods
}
export default MarketplaceModuleService
export default MarketplaceModuleService
```
````
The module’s main service extends the service factory to generate data management features for the `StoreUser`, `StoreProduct`, and `StoreOrder` data models.
The module’s main service extends the service factory to generate data management features for the `StoreUser`, `StoreProduct`, and `StoreOrder` data models.
Finally, create the module definition at `src/modules/marketplace/index.ts` with the following content:
Finally, create the module definition at `src/modules/marketplace/index.ts` with the following content:
```ts title="src/modules/marketplace/index.ts"
import MarketplaceModuleService from "./service"
import { Module } from "@medusajs/utils"
```ts title="src/modules/marketplace/index.ts"
import MarketplaceModuleService from "./service"
export default {
export default Module("marketplace", {
service: MarketplaceModuleService,
}
````
})
```
To use the module, add it to the `modules` object in `medusa-config.js`:
To use the module, add it to the `modules` object in `medusa-config.js`:
```js title="medusa-config.js"
module.exports = defineConfig({
```js title="medusa-config.js"
module.exports = defineConfig({
// ...
modules: {
marketplaceModuleService: {
@@ -201,14 +195,14 @@ module.exports = defineConfig({
},
},
},
})
```
})
```
Then, run the migrations of the module:
Then, run the migrations of the module:
```bash npm2yarn
npx medusa migrations run
```
```bash npm2yarn
npx medusa migrations run
```
</Details>
@@ -234,9 +228,9 @@ To attach admin users to their own stores, create a subscriber that listens to t
showLinkIcon={false}
/>
{/\* <Details summaryContent="Example">
{/* <Details summaryContent="Example">
Create the file `src/subscribers/user-created.ts` with the following content:
Create the file `src/subscribers/user-created.ts` with the following content:
export const userSubscriberHighlights = [
["13", "data", "The event data payload with the created user's ID."],
@@ -257,20 +251,20 @@ export const userSubscriberHighlights = [
} from "@medusajs/types"
import MarketplaceModuleService from "../modules/marketplace/service"
export default async function userCreatedHandler({
data,
container,
}: SubscriberArgs<{ id: string }>) {
const { id } = "data" in data ? data.data : data
const userModuleService: IUserModuleService = container.resolve(
ModuleRegistrationName.USER
)
const storeModuleService: IStoreModuleService = container.resolve(
ModuleRegistrationName.STORE
)
const marketplaceModuleService: MarketplaceModuleService = container.resolve(
"marketplaceModuleService"
)
export default async function userCreatedHandler({
data,
container,
}: SubscriberArgs<{ id: string }>) {
const { id } = "data" in data ? data.data : data
const userModuleService: IUserModuleService = container.resolve(
ModuleRegistrationName.USER
)
const storeModuleService: IStoreModuleService = container.resolve(
ModuleRegistrationName.STORE
)
const marketplaceModuleService: MarketplaceModuleService = container.resolve(
"marketplaceModuleService"
)
const user = await userModuleService.retrieveUser(id)
@@ -284,28 +278,26 @@ const marketplaceModuleService: MarketplaceModuleService = container.resolve(
})
console.log(`Created StoreUser ${storeUser.id}`)
}
}
export const config: SubscriberConfig = {
event: "user.created",
}
```
export const config: SubscriberConfig = {
event: "user.created",
}
This adds a subscriber to the `user.created` event. In the subscriber, you:
````
- Retrieve the created user. The created user’s ID is passed in the event’s data payload.
- Create a store for that user using the Store Module.
- Create a relationship between the user and the store by creating a `StoreUser` record.
This adds a subscriber to the `user.created` event. In the subscriber, you:
To test it out, use the `medusa user` command to create a user:
- Retrieve the created user. The created user’s ID is passed in the event’s data payload.
- Create a store for that user using the Store Module.
- Create a relationship between the user and the store by creating a `StoreUser` record.
```bash npm2yarn
npx medusa user -e my-admin@medusa-test.com -p supersecret
```
To test it out, use the `medusa user` command to create a user:
```bash npm2yarn
npx medusa user -e my-admin@medusa-test.com -p supersecret
````
At the end of the output, you should see the message `Created StoreUser {store_user_id}` where the `{store_user_id}` is the ID of the created `StoreUser`.
At the end of the output, you should see the message `Created StoreUser {store_user_id}` where the `{store_user_id}` is the ID of the created `StoreUser`.
</Details> */}
@@ -330,9 +322,9 @@ Similar to the previous section, to attach products to stores, create a subscrib
showLinkIcon={false}
/>
{/\* <Details summaryContent="Example">
{/* <Details summaryContent="Example">
Create the file `src/subscribers/product-created.ts` with the following content:
Create the file `src/subscribers/product-created.ts` with the following content:
export const productSubscriberHighlights = [
["24", "retrieveProduct", "Retrieve the created product."],
@@ -351,14 +343,14 @@ export const productSubscriberHighlights = [
} from "@medusajs/types"
import MarketplaceModuleService from "../modules/marketplace/service"
export default async function productCreateHandler({
data,
container,
}: SubscriberArgs<{ id: string }>) {
const { id } = "data" in data ? data.data : data
const productModuleService: IProductModuleService = container.resolve(
ModuleRegistrationName.PRODUCT
)
export default async function productCreateHandler({
data,
container,
}: SubscriberArgs<{ id: string }>) {
const { id } = "data" in data ? data.data : data
const productModuleService: IProductModuleService = container.resolve(
ModuleRegistrationName.PRODUCT
)
const marketplaceModuleService: MarketplaceModuleService = container.resolve(
"marketplaceModuleService"
@@ -374,42 +366,40 @@ ModuleRegistrationName.PRODUCT
store_id: product.metadata.store_id as string,
product_id: id,
})
}
}
export const config: SubscriberConfig = {
event: "product.created",
}
```
export const config: SubscriberConfig = {
event: "product.created",
}
This adds a subscriber to the `product.created` event. In the subscriber, you:
````
- Retrieve the created product.
- This subscriber requires the store ID to be set in `product.metadata.store_id`. If not, the subscriber ends execution.
- If the store ID is found, create a relationship between the product and the store by creating a `StoreProduct` record.
This adds a subscriber to the `product.created` event. In the subscriber, you:
To test it out, start the Medusa application:
- Retrieve the created product.
- This subscriber requires the store ID to be set in `product.metadata.store_id`. If not, the subscriber ends execution.
- If the store ID is found, create a relationship between the product and the store by creating a `StoreProduct` record.
```bash npm2yarn
npm run dev
```
To test it out, start the Medusa application:
Then, send an authenticated `POST` request to `/admin/products`:
```bash npm2yarn
npm run dev
````
Then, send an authenticated `POST` request to `/admin/products`:
```bash
curl -X POST 'http://localhost:9000/admin/products' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer {jwt_token}' \
--data '{
```bash
curl -X POST 'http://localhost:9000/admin/products' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer {jwt_token}' \
--data '{
"title": "My Shirt 13",
"metadata": {
"store_id": "store_01HXV74JCCAHA3F2X3EWZTZG5R"
}
}'
```
}'
```
This returns the created product. In the next section, you’ll implement the API route to fetch the products of a store.
This returns the created product. In the next section, you’ll implement the API route to fetch the products of a store.
</Details> */}
@@ -426,28 +416,26 @@ Retrieving module relationship data using the remote query is coming soon.
</Note>
<CardList
items={[
<CardList items={[
{
href: "!docs!/basics/api-routes",
title: "API Routes",
text: "Learn how to create an API Route in Medusa.",
startIcon: <AcademicCapSolid />,
showLinkIcon: false,
showLinkIcon: false
},
{
href: "!docs!/advanced-development/modules/remote-query",
title: "Remote Query",
text: "Use the remote query to fetch data across modules.",
startIcon: <AcademicCapSolid />,
showLinkIcon: false,
showLinkIcon: false
},
]}
/>
]} />
{/\* <Details summaryContent="Example">
{/* <Details summaryContent="Example">
Create the file `src/api/admin/marketplace/products/route.ts` with the following content:
Create the file `src/api/admin/marketplace/products/route.ts` with the following content:
export const productRoutesHighlights = [
["26", "storeUsers", "Retrieve the store of the logged-in user."],
@@ -469,17 +457,17 @@ export const productRoutesHighlights = [
import MarketplaceModuleService
from "../../../../modules/marketplace/service"
export async function GET(
req: AuthenticatedMedusaRequest,
res: MedusaResponse
): Promise<void> {
const marketplaceModuleService: MarketplaceModuleService =
req.scope.resolve(
"marketplaceModuleService"
)
const remoteQuery: RemoteQueryFunction = req.scope.resolve(
ContainerRegistrationKeys.REMOTE_QUERY
)
export async function GET(
req: AuthenticatedMedusaRequest,
res: MedusaResponse
): Promise<void> {
const marketplaceModuleService: MarketplaceModuleService =
req.scope.resolve(
"marketplaceModuleService"
)
const remoteQuery: RemoteQueryFunction = req.scope.resolve(
ContainerRegistrationKeys.REMOTE_QUERY
)
const storeUsers = await marketplaceModuleService
.listStoreUsers({
@@ -511,26 +499,24 @@ ContainerRegistrationKeys.REMOTE_QUERY
store_id: storeUsers[0].store_id,
products: result.map((data) => data.product),
})
}
```
}
This creates a `GET` API route at `/admin/marketplace/products`. In the API route, you:
````
- Retrieve the store of the logged-in user.
- Build a query that retrieves the products of that store.
- Retrieve the products using remote query and return them.
This creates a `GET` API route at `/admin/marketplace/products`. In the API route, you:
Next, create the file `src/api/middlewares.ts` with the following content:
- Retrieve the store of the logged-in user.
- Build a query that retrieves the products of that store.
- Retrieve the products using remote query and return them.
Next, create the file `src/api/middlewares.ts` with the following content:
```ts title="src/api/middlewares.ts"
import {
```ts title="src/api/middlewares.ts"
import {
MiddlewaresConfig,
authenticate,
} from "@medusajs/medusa"
} from "@medusajs/medusa"
export const config: MiddlewaresConfig = {
export const config: MiddlewaresConfig = {
routes: [
{
matcher: "/admin/marketplace*",
@@ -542,19 +528,19 @@ export const config: MiddlewaresConfig = {
],
},
],
}
````
}
```
This ensures that only authenticated admin users can access your API route.
This ensures that only authenticated admin users can access your API route.
To test it out, start the Medusa application. Then, send a `GET` request to `/admin/marketplace/products`:
To test it out, start the Medusa application. Then, send a `GET` request to `/admin/marketplace/products`:
```bash
curl 'localhost:9000/admin/marketplace/products' \
-H 'Authorization: Bearer {jwt_token}'
```
```bash
curl 'localhost:9000/admin/marketplace/products' \
-H 'Authorization: Bearer {jwt_token}'
```
This will return the product you created in the previous section, if the `{jwt_token}` belongs to the user of the same store ID.
This will return the product you created in the previous section, if the `{jwt_token}` belongs to the user of the same store ID.
</Details> */}
@@ -579,9 +565,9 @@ The `order.placed` event is still not emitted in Medusa V2.
showLinkIcon={false}
/>
{/\* <Details summaryContent="Example">
{/* <Details summaryContent="Example">
Create the file `src/subscribers/order-created.ts` with the following content:
Create the file `src/subscribers/order-created.ts` with the following content:
export const orderSubscriberHighlights = [
["35", "", "Loop over the created order’s items."],
@@ -605,15 +591,15 @@ export const orderSubscriberHighlights = [
from "../modules/marketplace/service"
import { createOrdersWorkflow } from "@medusajs/core-flows"
export default async function orderCreatedHandler({
data,
container,
}: SubscriberArgs<{ id: string }>) {
const { id } = "data" in data ? data.data : data
const orderModuleService: IOrderModuleService =
container.resolve(
ModuleRegistrationName.ORDER
)
export default async function orderCreatedHandler({
data,
container,
}: SubscriberArgs<{ id: string }>) {
const { id } = "data" in data ? data.data : data
const orderModuleService: IOrderModuleService =
container.resolve(
ModuleRegistrationName.ORDER
)
const marketplaceModuleService: MarketplaceModuleService =
container.resolve(
@@ -686,25 +672,23 @@ ModuleRegistrationName.ORDER
})
})
)
}
}
export const config: SubscriberConfig = {
event: "order.placed",
}
```
export const config: SubscriberConfig = {
event: "order.placed",
}
This adds a subscriber to the `order.placed` event. In the subscriber, you:
````
- Loop over the created order’s items.
- Group the items by their store ID.
- If the items have the same store ID, then associate the created order with the store.
- If there are items from more than one store in the order, create child orders and associate each of them with the store. Here, you use the `parent_order_id` property in the `StoreOrder` data model to point to the original order.
This adds a subscriber to the `order.placed` event. In the subscriber, you:
To test this out, create an order in your store. That will run the subscriber and create the child orders.
- Loop over the created order’s items.
- Group the items by their store ID.
- If the items have the same store ID, then associate the created order with the store.
- If there are items from more than one store in the order, create child orders and associate each of them with the store. Here, you use the `parent_order_id` property in the `StoreOrder` data model to point to the original order.
To test this out, create an order in your store. That will run the subscriber and create the child orders.
The next section covers how to retrieve the store’s orders.
The next section covers how to retrieve the store’s orders.
</Details> */}
@@ -722,49 +706,49 @@ Retrieving module relationship data using the remote query is coming soon.
</Note>
<CardList items={[
{
{
href: "!docs!/basics/api-routes",
title: "API Routes",
text: "Learn how to create an API Route in Medusa.",
startIcon: <AcademicCapSolid />,
showLinkIcon: false
},
{
},
{
href: "!docs!/advanced-development/modules/remote-query",
title: "Remote Query",
text: "Use the remote query to fetch data across modules.",
startIcon: <AcademicCapSolid />,
showLinkIcon: false
},
},
]} />
{/* <Details summaryContent="Example">
Create the file `src/api/admin/marketplace/orders/route.ts` with the following content:
Create the file `src/api/admin/marketplace/orders/route.ts` with the following content:
export const orderRoutesHighlights = [
["25", "", "Retrieve the store of the logged-in user."],
["29", "", "Build a query that retrieves the orders of that store."],
["41", "", "Retrieve the orders using remote query."]
["25", "", "Retrieve the store of the logged-in user."],
["29", "", "Build a query that retrieves the orders of that store."],
["41", "", "Retrieve the orders using remote query."]
]
```ts title="src/api/admin/marketplace/orders/route.ts" highlights={orderRoutesHighlights} collapsibleLines="1-12" expandButtonLabel="Show Imports"
import {
```ts title="src/api/admin/marketplace/orders/route.ts" highlights={orderRoutesHighlights} collapsibleLines="1-12" expandButtonLabel="Show Imports"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "@medusajs/medusa"
import { RemoteQueryFunction } from "@medusajs/modules-sdk"
import {
} from "@medusajs/medusa"
import { RemoteQueryFunction } from "@medusajs/modules-sdk"
import {
remoteQueryObjectFromString,
ContainerRegistrationKeys,
} from "@medusajs/utils"
import MarketplaceModuleService
} from "@medusajs/utils"
import MarketplaceModuleService
from "../../../../modules/marketplace/service"
export async function GET(
export async function GET(
req: AuthenticatedMedusaRequest,
res: MedusaResponse
): Promise<void> {
): Promise<void> {
const marketplaceModuleService: MarketplaceModuleService =
req.scope.resolve(
"marketplaceModuleService"
@@ -794,23 +778,23 @@ export async function GET(
res.json({
orders: result.map((data) => data.order),
})
}
````
}
```
This creates a `GET` API route at `/admin/marketplace/orders`. In the API route, you:
This creates a `GET` API route at `/admin/marketplace/orders`. In the API route, you:
- Retrieve the store of the logged-in user.
- Build a query that retrieves the orders of that store.
- Retrieve the orders using remote query and return them.
- Retrieve the store of the logged-in user.
- Build a query that retrieves the orders of that store.
- Retrieve the orders using remote query and return them.
To test it out, start the Medusa application. Then, send a `GET` request to `/admin/marketplace/orders`:
To test it out, start the Medusa application. Then, send a `GET` request to `/admin/marketplace/orders`:
```bash
curl 'localhost:9000/admin/marketplace/orders' \
-H 'Authorization: Bearer {jwt_token}'
```
```bash
curl 'localhost:9000/admin/marketplace/orders' \
-H 'Authorization: Bearer {jwt_token}'
```
This will return the orders you created in the previous section if the `{jwt_token}` belongs to the user of the same store ID.
This will return the orders you created in the previous section if the `{jwt_token}` belongs to the user of the same store ID.
</Details> */}
@@ -822,21 +806,19 @@ Medusa provides a Next.js storefront to use with your application. You can eithe
For example, you can create an API route that retrieves available stores and another API route that retrieves the products of each store using the remote query as done in previous sections.
<CardList
items={[
<CardList items={[
{
href: "/nextjs-starter",
title: "Next.js Storefront",
text: "Learn how to install and customize the Next.js storefront.",
startIcon: <AcademicCapSolid />,
showLinkIcon: false,
showLinkIcon: false
},
{
href: "!docs!/storefront-development/tips",
title: "Storefront Tips",
text: "Find tips on developing a custom storefront.",
startIcon: <AcademicCapSolid />,
showLinkIcon: false,
showLinkIcon: false
},
]}
/>
]} />
@@ -30,6 +30,7 @@ const Navbar = () => {
mobileSidebarOpen,
}}
isLoading={false}
showSearchOpener
/>
)
}
+116 -116
View File
@@ -1,4 +1,8 @@
export const filesMap = [
{
"filePath": "/www/apps/resources/app/_events-reference/page.mdx",
"pathname": "/_events-reference"
},
{
"filePath": "/www/apps/resources/app/admin-widget-injection-zones/page.mdx",
"pathname": "/admin-widget-injection-zones"
@@ -79,18 +83,18 @@ export const filesMap = [
"filePath": "/www/apps/resources/app/architectural-modules/workflow-engine/redis/page.mdx",
"pathname": "/architectural-modules/workflow-engine/redis"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/api-key/_events/_events-table/page.mdx",
"pathname": "/commerce-modules/api-key/_events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/api-key/_events/page.mdx",
"pathname": "/commerce-modules/api-key/_events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/api-key/concepts/page.mdx",
"pathname": "/commerce-modules/api-key/concepts"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/api-key/events/_events-table/page.mdx",
"pathname": "/commerce-modules/api-key/events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/api-key/events/page.mdx",
"pathname": "/commerce-modules/api-key/events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/api-key/examples/page.mdx",
"pathname": "/commerce-modules/api-key/examples"
@@ -103,6 +107,14 @@ export const filesMap = [
"filePath": "/www/apps/resources/app/commerce-modules/api-key/relations-to-other-modules/page.mdx",
"pathname": "/commerce-modules/api-key/relations-to-other-modules"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/auth/_events/_events-table/page.mdx",
"pathname": "/commerce-modules/auth/_events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/auth/_events/page.mdx",
"pathname": "/commerce-modules/auth/_events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/auth/auth-flows/page.mdx",
"pathname": "/commerce-modules/auth/auth-flows"
@@ -131,14 +143,6 @@ export const filesMap = [
"filePath": "/www/apps/resources/app/commerce-modules/auth/create-actor-type/page.mdx",
"pathname": "/commerce-modules/auth/create-actor-type"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/auth/events/_events-table/page.mdx",
"pathname": "/commerce-modules/auth/events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/auth/events/page.mdx",
"pathname": "/commerce-modules/auth/events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/auth/examples/page.mdx",
"pathname": "/commerce-modules/auth/examples"
@@ -151,18 +155,18 @@ export const filesMap = [
"filePath": "/www/apps/resources/app/commerce-modules/auth/page.mdx",
"pathname": "/commerce-modules/auth"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/cart/_events/_events-table/page.mdx",
"pathname": "/commerce-modules/cart/_events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/cart/_events/page.mdx",
"pathname": "/commerce-modules/cart/_events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/cart/concepts/page.mdx",
"pathname": "/commerce-modules/cart/concepts"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/cart/events/_events-table/page.mdx",
"pathname": "/commerce-modules/cart/events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/cart/events/page.mdx",
"pathname": "/commerce-modules/cart/events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/cart/examples/page.mdx",
"pathname": "/commerce-modules/cart/examples"
@@ -184,12 +188,12 @@ export const filesMap = [
"pathname": "/commerce-modules/cart/tax-lines"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/currency/events/_events-table/page.mdx",
"pathname": "/commerce-modules/currency/events/_events-table"
"filePath": "/www/apps/resources/app/commerce-modules/currency/_events/_events-table/page.mdx",
"pathname": "/commerce-modules/currency/_events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/currency/events/page.mdx",
"pathname": "/commerce-modules/currency/events"
"filePath": "/www/apps/resources/app/commerce-modules/currency/_events/page.mdx",
"pathname": "/commerce-modules/currency/_events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/currency/examples/page.mdx",
@@ -203,18 +207,18 @@ export const filesMap = [
"filePath": "/www/apps/resources/app/commerce-modules/currency/relations-to-other-modules/page.mdx",
"pathname": "/commerce-modules/currency/relations-to-other-modules"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/customer/_events/_events-table/page.mdx",
"pathname": "/commerce-modules/customer/_events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/customer/_events/page.mdx",
"pathname": "/commerce-modules/customer/_events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/customer/customer-accounts/page.mdx",
"pathname": "/commerce-modules/customer/customer-accounts"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/customer/events/_events-table/page.mdx",
"pathname": "/commerce-modules/customer/events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/customer/events/page.mdx",
"pathname": "/commerce-modules/customer/events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/customer/examples/page.mdx",
"pathname": "/commerce-modules/customer/examples"
@@ -227,18 +231,18 @@ export const filesMap = [
"filePath": "/www/apps/resources/app/commerce-modules/customer/relations-to-other-modules/page.mdx",
"pathname": "/commerce-modules/customer/relations-to-other-modules"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/fulfillment/_events/_events-table/page.mdx",
"pathname": "/commerce-modules/fulfillment/_events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/fulfillment/_events/page.mdx",
"pathname": "/commerce-modules/fulfillment/_events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/fulfillment/concepts/page.mdx",
"pathname": "/commerce-modules/fulfillment/concepts"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/fulfillment/events/_events-table/page.mdx",
"pathname": "/commerce-modules/fulfillment/events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/fulfillment/events/page.mdx",
"pathname": "/commerce-modules/fulfillment/events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/fulfillment/fulfillment-provider/page.mdx",
"pathname": "/commerce-modules/fulfillment/fulfillment-provider"
@@ -263,18 +267,18 @@ export const filesMap = [
"filePath": "/www/apps/resources/app/commerce-modules/fulfillment/shipping-option/page.mdx",
"pathname": "/commerce-modules/fulfillment/shipping-option"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/inventory/_events/_events-table/page.mdx",
"pathname": "/commerce-modules/inventory/_events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/inventory/_events/page.mdx",
"pathname": "/commerce-modules/inventory/_events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/inventory/concepts/page.mdx",
"pathname": "/commerce-modules/inventory/concepts"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/inventory/events/_events-table/page.mdx",
"pathname": "/commerce-modules/inventory/events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/inventory/events/page.mdx",
"pathname": "/commerce-modules/inventory/events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/inventory/examples/page.mdx",
"pathname": "/commerce-modules/inventory/examples"
@@ -291,18 +295,18 @@ export const filesMap = [
"filePath": "/www/apps/resources/app/commerce-modules/inventory/relations-to-other-modules/page.mdx",
"pathname": "/commerce-modules/inventory/relations-to-other-modules"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/order/_events/_events-table/page.mdx",
"pathname": "/commerce-modules/order/_events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/order/_events/page.mdx",
"pathname": "/commerce-modules/order/_events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/order/concepts/page.mdx",
"pathname": "/commerce-modules/order/concepts"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/order/events/_events-table/page.mdx",
"pathname": "/commerce-modules/order/events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/order/events/page.mdx",
"pathname": "/commerce-modules/order/events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/order/order-change/page.mdx",
"pathname": "/commerce-modules/order/order-change"
@@ -336,12 +340,12 @@ export const filesMap = [
"pathname": "/commerce-modules"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/payment/events/_events-table/page.mdx",
"pathname": "/commerce-modules/payment/events/_events-table"
"filePath": "/www/apps/resources/app/commerce-modules/payment/_events/_events-table/page.mdx",
"pathname": "/commerce-modules/payment/_events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/payment/events/page.mdx",
"pathname": "/commerce-modules/payment/events"
"filePath": "/www/apps/resources/app/commerce-modules/payment/_events/page.mdx",
"pathname": "/commerce-modules/payment/_events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/payment/examples/page.mdx",
@@ -387,18 +391,18 @@ export const filesMap = [
"filePath": "/www/apps/resources/app/commerce-modules/payment/webhook-events/page.mdx",
"pathname": "/commerce-modules/payment/webhook-events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/pricing/_events/_events-table/page.mdx",
"pathname": "/commerce-modules/pricing/_events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/pricing/_events/page.mdx",
"pathname": "/commerce-modules/pricing/_events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/pricing/concepts/page.mdx",
"pathname": "/commerce-modules/pricing/concepts"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/pricing/events/_events-table/page.mdx",
"pathname": "/commerce-modules/pricing/events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/pricing/events/page.mdx",
"pathname": "/commerce-modules/pricing/events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/pricing/examples/page.mdx",
"pathname": "/commerce-modules/pricing/examples"
@@ -420,12 +424,12 @@ export const filesMap = [
"pathname": "/commerce-modules/pricing/relations-to-other-modules"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/product/events/_events-table/page.mdx",
"pathname": "/commerce-modules/product/events/_events-table"
"filePath": "/www/apps/resources/app/commerce-modules/product/_events/_events-table/page.mdx",
"pathname": "/commerce-modules/product/_events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/product/events/page.mdx",
"pathname": "/commerce-modules/product/events"
"filePath": "/www/apps/resources/app/commerce-modules/product/_events/page.mdx",
"pathname": "/commerce-modules/product/_events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/product/examples/page.mdx",
@@ -439,6 +443,14 @@ export const filesMap = [
"filePath": "/www/apps/resources/app/commerce-modules/product/relations-to-other-modules/page.mdx",
"pathname": "/commerce-modules/product/relations-to-other-modules"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/promotion/_events/_events-table/page.mdx",
"pathname": "/commerce-modules/promotion/_events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/promotion/_events/page.mdx",
"pathname": "/commerce-modules/promotion/_events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/promotion/actions/page.mdx",
"pathname": "/commerce-modules/promotion/actions"
@@ -455,14 +467,6 @@ export const filesMap = [
"filePath": "/www/apps/resources/app/commerce-modules/promotion/concepts/page.mdx",
"pathname": "/commerce-modules/promotion/concepts"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/promotion/events/_events-table/page.mdx",
"pathname": "/commerce-modules/promotion/events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/promotion/events/page.mdx",
"pathname": "/commerce-modules/promotion/events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/promotion/examples/page.mdx",
"pathname": "/commerce-modules/promotion/examples"
@@ -476,12 +480,12 @@ export const filesMap = [
"pathname": "/commerce-modules/promotion/relations-to-other-modules"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/region/events/_events-table/page.mdx",
"pathname": "/commerce-modules/region/events/_events-table"
"filePath": "/www/apps/resources/app/commerce-modules/region/_events/_events-table/page.mdx",
"pathname": "/commerce-modules/region/_events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/region/events/page.mdx",
"pathname": "/commerce-modules/region/events"
"filePath": "/www/apps/resources/app/commerce-modules/region/_events/page.mdx",
"pathname": "/commerce-modules/region/_events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/region/examples/page.mdx",
@@ -496,12 +500,12 @@ export const filesMap = [
"pathname": "/commerce-modules/region/relations-to-other-modules"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/sales-channel/events/_events-table/page.mdx",
"pathname": "/commerce-modules/sales-channel/events/_events-table"
"filePath": "/www/apps/resources/app/commerce-modules/sales-channel/_events/_events-table/page.mdx",
"pathname": "/commerce-modules/sales-channel/_events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/sales-channel/events/page.mdx",
"pathname": "/commerce-modules/sales-channel/events"
"filePath": "/www/apps/resources/app/commerce-modules/sales-channel/_events/page.mdx",
"pathname": "/commerce-modules/sales-channel/_events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/sales-channel/examples/page.mdx",
@@ -519,18 +523,18 @@ export const filesMap = [
"filePath": "/www/apps/resources/app/commerce-modules/sales-channel/relations-to-other-modules/page.mdx",
"pathname": "/commerce-modules/sales-channel/relations-to-other-modules"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/stock-location/_events/_events-table/page.mdx",
"pathname": "/commerce-modules/stock-location/_events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/stock-location/_events/page.mdx",
"pathname": "/commerce-modules/stock-location/_events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/stock-location/concepts/page.mdx",
"pathname": "/commerce-modules/stock-location/concepts"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/stock-location/events/_events-table/page.mdx",
"pathname": "/commerce-modules/stock-location/events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/stock-location/events/page.mdx",
"pathname": "/commerce-modules/stock-location/events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/stock-location/examples/page.mdx",
"pathname": "/commerce-modules/stock-location/examples"
@@ -544,12 +548,12 @@ export const filesMap = [
"pathname": "/commerce-modules/stock-location/relations-to-other-modules"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/store/events/_events-table/page.mdx",
"pathname": "/commerce-modules/store/events/_events-table"
"filePath": "/www/apps/resources/app/commerce-modules/store/_events/_events-table/page.mdx",
"pathname": "/commerce-modules/store/_events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/store/events/page.mdx",
"pathname": "/commerce-modules/store/events"
"filePath": "/www/apps/resources/app/commerce-modules/store/_events/page.mdx",
"pathname": "/commerce-modules/store/_events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/store/examples/page.mdx",
@@ -564,12 +568,12 @@ export const filesMap = [
"pathname": "/commerce-modules/store/relations-to-other-modules"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/tax/events/_events-table/page.mdx",
"pathname": "/commerce-modules/tax/events/_events-table"
"filePath": "/www/apps/resources/app/commerce-modules/tax/_events/_events-table/page.mdx",
"pathname": "/commerce-modules/tax/_events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/tax/events/page.mdx",
"pathname": "/commerce-modules/tax/events"
"filePath": "/www/apps/resources/app/commerce-modules/tax/_events/page.mdx",
"pathname": "/commerce-modules/tax/_events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/tax/examples/page.mdx",
@@ -596,12 +600,12 @@ export const filesMap = [
"pathname": "/commerce-modules/tax/tax-region"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/user/events/_events-table/page.mdx",
"pathname": "/commerce-modules/user/events/_events-table"
"filePath": "/www/apps/resources/app/commerce-modules/user/_events/_events-table/page.mdx",
"pathname": "/commerce-modules/user/_events/_events-table"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/user/events/page.mdx",
"pathname": "/commerce-modules/user/events"
"filePath": "/www/apps/resources/app/commerce-modules/user/_events/page.mdx",
"pathname": "/commerce-modules/user/_events"
},
{
"filePath": "/www/apps/resources/app/commerce-modules/user/examples/page.mdx",
@@ -671,10 +675,6 @@ export const filesMap = [
"filePath": "/www/apps/resources/app/deployment/storefront/vercel/page.mdx",
"pathname": "/deployment/storefront/vercel"
},
{
"filePath": "/www/apps/resources/app/events-reference/page.mdx",
"pathname": "/events-reference"
},
{
"filePath": "/www/apps/resources/app/favicon.ico",
"pathname": "/"
-133
View File
@@ -162,13 +162,6 @@ export const generatedSidebar = [
]
}
]
},
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/api-key/events",
"title": "Events Reference",
"children": []
}
]
}
@@ -371,13 +364,6 @@ export const generatedSidebar = [
]
}
]
},
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/auth/events",
"title": "Events Reference",
"children": []
}
]
}
@@ -880,13 +866,6 @@ export const generatedSidebar = [
]
}
]
},
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/cart/events",
"title": "Events Reference",
"children": []
}
]
}
@@ -990,13 +969,6 @@ export const generatedSidebar = [
]
}
]
},
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/currency/events",
"title": "Events Reference",
"children": []
}
]
}
@@ -1275,13 +1247,6 @@ export const generatedSidebar = [
]
}
]
},
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/customer/events",
"title": "Events Reference",
"children": []
}
]
}
@@ -1931,13 +1896,6 @@ export const generatedSidebar = [
]
}
]
},
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/fulfillment/events",
"title": "Events Reference",
"children": []
}
]
}
@@ -2293,13 +2251,6 @@ export const generatedSidebar = [
]
}
]
},
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/inventory/events",
"title": "Events Reference",
"children": []
}
]
}
@@ -3187,13 +3138,6 @@ export const generatedSidebar = [
]
}
]
},
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/order/events",
"title": "Events Reference",
"children": []
}
]
}
@@ -3557,13 +3501,6 @@ export const generatedSidebar = [
]
}
]
},
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/payment/events",
"title": "Events Reference",
"children": []
}
]
}
@@ -3947,13 +3884,6 @@ export const generatedSidebar = [
]
}
]
},
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/pricing/events",
"title": "Events Reference",
"children": []
}
]
}
@@ -4533,13 +4463,6 @@ export const generatedSidebar = [
]
}
]
},
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/product/events",
"title": "Events Reference",
"children": []
}
]
}
@@ -4881,13 +4804,6 @@ export const generatedSidebar = [
]
}
]
},
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/promotion/events",
"title": "Events Reference",
"children": []
}
]
}
@@ -5061,13 +4977,6 @@ export const generatedSidebar = [
]
}
]
},
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/region/events",
"title": "Events Reference",
"children": []
}
]
}
@@ -5220,13 +5129,6 @@ export const generatedSidebar = [
]
}
]
},
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/sales-channel/events",
"title": "Events Reference",
"children": []
}
]
}
@@ -5386,13 +5288,6 @@ export const generatedSidebar = [
]
}
]
},
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/stock-location/events",
"title": "Events Reference",
"children": []
}
]
}
@@ -5545,13 +5440,6 @@ export const generatedSidebar = [
]
}
]
},
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/store/events",
"title": "Events Reference",
"children": []
}
]
}
@@ -5823,13 +5711,6 @@ export const generatedSidebar = [
]
}
]
},
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/tax/events",
"title": "Events Reference",
"children": []
}
]
}
@@ -6052,13 +5933,6 @@ export const generatedSidebar = [
]
}
]
},
{
"loaded": true,
"isPathHref": true,
"path": "/commerce-modules/user/events",
"title": "Events Reference",
"children": []
}
]
}
@@ -7917,13 +7791,6 @@ export const generatedSidebar = [
"title": "Medusa Container Resources",
"children": []
},
{
"loaded": true,
"isPathHref": true,
"path": "/events-reference",
"title": "Events",
"children": []
},
{
"loaded": true,
"isPathHref": true,
+76 -76
View File
@@ -65,10 +65,10 @@ export const sidebar = sidebarAttachHrefCommonOptions([
},
],
},
{
path: "/commerce-modules/api-key/events",
title: "Events Reference",
},
// {
// path: "/commerce-modules/api-key/events",
// title: "Events Reference",
// },
],
},
],
@@ -156,10 +156,10 @@ export const sidebar = sidebarAttachHrefCommonOptions([
},
],
},
{
path: "/commerce-modules/auth/events",
title: "Events Reference",
},
// {
// path: "/commerce-modules/auth/events",
// title: "Events Reference",
// },
],
},
],
@@ -224,10 +224,10 @@ export const sidebar = sidebarAttachHrefCommonOptions([
},
],
},
{
path: "/commerce-modules/cart/events",
title: "Events Reference",
},
// {
// path: "/commerce-modules/cart/events",
// title: "Events Reference",
// },
],
},
],
@@ -280,10 +280,10 @@ export const sidebar = sidebarAttachHrefCommonOptions([
},
],
},
{
path: "/commerce-modules/currency/events",
title: "Events Reference",
},
// {
// path: "/commerce-modules/currency/events",
// title: "Events Reference",
// },
],
},
],
@@ -340,10 +340,10 @@ export const sidebar = sidebarAttachHrefCommonOptions([
},
],
},
{
path: "/commerce-modules/customer/events",
title: "Events Reference",
},
// {
// path: "/commerce-modules/customer/events",
// title: "Events Reference",
// },
],
},
],
@@ -417,10 +417,10 @@ export const sidebar = sidebarAttachHrefCommonOptions([
},
],
},
{
path: "/commerce-modules/fulfillment/events",
title: "Events Reference",
},
// {
// path: "/commerce-modules/fulfillment/events",
// title: "Events Reference",
// },
],
},
],
@@ -482,10 +482,10 @@ export const sidebar = sidebarAttachHrefCommonOptions([
},
],
},
{
path: "/commerce-modules/inventory/events",
title: "Events Reference",
},
// {
// path: "/commerce-modules/inventory/events",
// title: "Events Reference",
// },
],
},
],
@@ -558,10 +558,10 @@ export const sidebar = sidebarAttachHrefCommonOptions([
},
],
},
{
path: "/commerce-modules/order/events",
title: "Events Reference",
},
// {
// path: "/commerce-modules/order/events",
// title: "Events Reference",
// },
],
},
],
@@ -657,10 +657,10 @@ export const sidebar = sidebarAttachHrefCommonOptions([
},
],
},
{
path: "/commerce-modules/payment/events",
title: "Events Reference",
},
// {
// path: "/commerce-modules/payment/events",
// title: "Events Reference",
// },
],
},
],
@@ -725,10 +725,10 @@ export const sidebar = sidebarAttachHrefCommonOptions([
},
],
},
{
path: "/commerce-modules/pricing/events",
title: "Events Reference",
},
// {
// path: "/commerce-modules/pricing/events",
// title: "Events Reference",
// },
],
},
],
@@ -781,10 +781,10 @@ export const sidebar = sidebarAttachHrefCommonOptions([
},
],
},
{
path: "/commerce-modules/product/events",
title: "Events Reference",
},
// {
// path: "/commerce-modules/product/events",
// title: "Events Reference",
// },
],
},
],
@@ -853,10 +853,10 @@ export const sidebar = sidebarAttachHrefCommonOptions([
},
],
},
{
path: "/commerce-modules/promotion/events",
title: "Events Reference",
},
// {
// path: "/commerce-modules/promotion/events",
// title: "Events Reference",
// },
],
},
],
@@ -909,10 +909,10 @@ export const sidebar = sidebarAttachHrefCommonOptions([
},
],
},
{
path: "/commerce-modules/region/events",
title: "Events Reference",
},
// {
// path: "/commerce-modules/region/events",
// title: "Events Reference",
// },
],
},
],
@@ -971,10 +971,10 @@ export const sidebar = sidebarAttachHrefCommonOptions([
},
],
},
{
path: "/commerce-modules/sales-channel/events",
title: "Events Reference",
},
// {
// path: "/commerce-modules/sales-channel/events",
// title: "Events Reference",
// },
],
},
],
@@ -1034,10 +1034,10 @@ export const sidebar = sidebarAttachHrefCommonOptions([
},
],
},
{
path: "/commerce-modules/stock-location/events",
title: "Events Reference",
},
// {
// path: "/commerce-modules/stock-location/events",
// title: "Events Reference",
// },
],
},
],
@@ -1090,10 +1090,10 @@ export const sidebar = sidebarAttachHrefCommonOptions([
},
],
},
{
path: "/commerce-modules/store/events",
title: "Events Reference",
},
// {
// path: "/commerce-modules/store/events",
// title: "Events Reference",
// },
],
},
],
@@ -1162,10 +1162,10 @@ export const sidebar = sidebarAttachHrefCommonOptions([
},
],
},
{
path: "/commerce-modules/tax/events",
title: "Events Reference",
},
// {
// path: "/commerce-modules/tax/events",
// title: "Events Reference",
// },
],
},
],
@@ -1222,10 +1222,10 @@ export const sidebar = sidebarAttachHrefCommonOptions([
},
],
},
{
path: "/commerce-modules/user/events",
title: "Events Reference",
},
// {
// path: "/commerce-modules/user/events",
// title: "Events Reference",
// },
],
},
],
@@ -2104,10 +2104,10 @@ export const sidebar = sidebarAttachHrefCommonOptions([
path: "/medusa-container-resources",
title: "Medusa Container Resources",
},
{
path: "/events-reference",
title: "Events",
},
// {
// path: "/events-reference",
// title: "Events",
// },
{
path: "/admin-widget-injection-zones",
title: "Admin Widget Injection Zones",
-1
View File
@@ -9,4 +9,3 @@ NEXT_PUBLIC_SEGMENT_API_KEY=
NEXT_PUBLIC_AI_ASSISTANT_URL=
NEXT_PUBLIC_AI_WEBSITE_ID=
NEXT_PUBLIC_AI_API_ASSISTANT_RECAPTCHA_SITE_KEY=
NEXT_PUBLIC_SHOW_V2=
+3 -10
View File
@@ -1,10 +1,5 @@
import { ArrowUpRightOnBox } from "@medusajs/icons"
import {
NavbarItem,
getNavbarItems,
legacyMobileSidebarItems,
mobileSidebarItemsV1,
} from "docs-ui"
import { NavbarItem, getNavbarItems, mobileSidebarItemsV1 } from "docs-ui"
import { SidebarSectionItemsType } from "types"
import { siteConfig } from "./site"
@@ -17,7 +12,7 @@ export const docsConfig: DocsConfig = {
mainNav: getNavbarItems({
basePath: siteConfig.baseUrl,
activePath: process.env.NEXT_PUBLIC_BASE_PATH || "/ui",
version: process.env.NEXT_PUBLIC_SHOW_V2 ? "v1" : "legacy",
version: "v1",
}),
sidebar: {
top: [
@@ -285,8 +280,6 @@ export const docsConfig: DocsConfig = {
],
},
],
mobile: process.env.NEXT_PUBLIC_SHOW_V2
? mobileSidebarItemsV1
: legacyMobileSidebarItems,
mobile: mobileSidebarItemsV1,
},
}
+29 -123
View File
@@ -52,22 +52,23 @@ export const navbarItemsV1: NavbarItem[] = [
href: `/ui`,
},
},
{
type: "divider",
},
{
type: "link",
props: {
label: "Learn Medusa v2",
target: "_blank",
rel: "noreferrer",
href: `/v2`,
badge: {
variant: "blue",
children: "New",
},
},
},
// TODO enable them later
// {
// type: "divider",
// },
// {
// type: "link",
// props: {
// label: "Learn Medusa v2",
// target: "_blank",
// rel: "noreferrer",
// href: `/v2`,
// badge: {
// variant: "blue",
// children: "New",
// },
// },
// },
]
export const navbarItemsV2: NavbarItem[] = [
@@ -122,71 +123,10 @@ export const navbarItemsV2: NavbarItem[] = [
{
type: "link",
props: {
label: "Medusa V1",
label: "Medusa v1",
target: "_blank",
rel: "noreferrer",
href: `/`,
badge: {
variant: "neutral",
children: "v1",
},
},
},
]
export const legacyNavbarItems: NavbarItem[] = [
{
type: "link",
props: {
label: "Docs",
target: "_blank",
rel: "noreferrer",
href: `/`,
},
},
{
type: "link",
props: {
label: "Resources",
target: "_blank",
rel: "noreferrer",
href: `/resources`,
},
},
{
type: "link",
props: {
label: "User Guide",
target: "_blank",
rel: "noreferrer",
href: `/user-guide`,
},
},
{
type: "link",
props: {
label: "Store API",
target: "_blank",
rel: "noreferrer",
href: `/api/store`,
},
},
{
type: "link",
props: {
label: "Admin API",
target: "_blank",
rel: "noreferrer",
href: `/api/admin`,
},
},
{
type: "link",
props: {
label: "UI",
target: "_blank",
rel: "noreferrer",
href: `/ui`,
},
},
]
@@ -222,13 +162,13 @@ export const mobileSidebarItemsV1: SidebarItemType[] = [
loaded: true,
isPathHref: true,
},
{
title: "Learn Medusa V2",
path: `/v2`,
loaded: true,
isPathHref: true,
additionalElms: <Badge variant="blue">v2</Badge>,
},
// {
// title: "Learn Medusa V2",
// path: `/v2`,
// loaded: true,
// isPathHref: true,
// additionalElms: <Badge variant="blue">v2</Badge>,
// },
]
export const mobileSidebarItemsV2: SidebarItemType[] = [
@@ -263,51 +203,17 @@ export const mobileSidebarItemsV2: SidebarItemType[] = [
isPathHref: true,
},
{
title: "Docs",
title: "Medusa v1",
path: `/`,
loaded: true,
isPathHref: true,
additionalElms: <Badge variant="neutral">v1</Badge>,
},
]
export const legacyMobileSidebarItems: SidebarItemType[] = [
{
title: "Docs",
path: `/`,
loaded: true,
isPathHref: true,
},
{
title: "User Guide",
path: `/user-guide`,
loaded: true,
isPathHref: true,
},
{
title: "Store API",
path: `/api/store`,
loaded: true,
isPathHref: true,
},
{
title: "Admin API",
path: `/api/admin`,
loaded: true,
isPathHref: true,
},
{
title: "UI",
path: `/ui`,
loaded: true,
isPathHref: true,
},
]
export const searchFiltersV2: OptionType[] = [
{
value: "book",
label: "Docs V2",
label: "Docs v2",
},
{
value: "resources",
@@ -315,11 +221,11 @@ export const searchFiltersV2: OptionType[] = [
},
{
value: "admin-v2",
label: "Admin API",
label: "Admin API (v2)",
},
{
value: "store-v2",
label: "Store API",
label: "Store API (v2)",
},
// TODO add more filters
]
@@ -1,22 +1,17 @@
import { NavbarItem, legacyNavbarItems, navbarItemsV1, navbarItemsV2 } from ".."
import { NavbarItem, navbarItemsV1, navbarItemsV2 } from ".."
type Options = {
basePath: string
activePath: string
version?: "v1" | "v2" | "legacy"
version?: "v1" | "v2"
}
export function getNavbarItems({
basePath,
activePath,
version = "legacy",
version = "v1",
}: Options): NavbarItem[] {
const navbarItems =
version === "v2"
? navbarItemsV2
: version === "v1"
? navbarItemsV1
: legacyNavbarItems
const navbarItems = version === "v2" ? navbarItemsV2 : navbarItemsV1
return navbarItems.map((item) => {
if (item.type === "divider") {
return item