docs: general fixes and improvements (#7918)

* docs improvements and changes

* updated module definition

* modules + dml changes

* fix build

* fix vale error

* fix lint errors

* fixes to stripe docs

* fix condition

* fix condition

* fix module defintion

* fix checkout

* disable UI action

* change oas preview action

* flatten provider module options

* fix lint errors

* add module link docs

* pr comments fixes

* fix vale error

* change node engine version

* links -> linkable

* add note about database name

* small fixes

* link fixes

* fix response code in api reference

* added migrations step
This commit is contained in:
Shahed Nasser
2024-07-04 17:26:03 +03:00
committed by GitHub
parent 32982e708a
commit 964927b597
149 changed files with 1676 additions and 3008 deletions
@@ -8,7 +8,9 @@ In this chapter, youll learn about the CORS middleware and how to configure i
## CORS Overview
Cross-Origin Resource Sharing (CORS) allows only configured origins to access your API Routes. For example, if you allow only origins starting with `http://localhost:7001` to access your Admin API Routes, other origins accessing those routes get a CORS error.
Cross-Origin Resource Sharing (CORS) allows only configured origins to access your API Routes.
For example, if you allow only origins starting with `http://localhost:7001` to access your Admin API Routes, other origins accessing those routes get a CORS error.
### CORS Configurations
@@ -30,6 +32,12 @@ module.exports = defineConfig({
This allows the `http://localhost:7001` origin to access the Admin API Routes, and the `http://localhost:8000` origin to access Store API Routes.
<Note title="Tip">
Learn more about the CORS configurations in [this resource guide](!resources!/references/medusa-config#http).
</Note>
---
## CORS in Store and Admin Routes
@@ -70,13 +78,16 @@ You can do that in the exported middlewares configurations in `src/api/middlewar
For example:
export const highlights = [["18", "parseCorsOrigins", "A utility function that parses the CORS configurations in `medusa-config.js`"]]
export const highlights = [["25", "parseCorsOrigins", "A utility function that parses the CORS configurations in `medusa-config.js`"]]
```ts title="src/api/middlewares.ts" highlights={highlights} collapsibleLines="1-7" expandButtonLabel="Show Imports"
```ts title="src/api/middlewares.ts" highlights={highlights} collapsibleLines="1-10" expandButtonLabel="Show Imports"
import {
ConfigModule,
MiddlewaresConfig,
MedusaNextFunction,
MedusaRequest,
MedusaResponse,
} from "@medusajs/medusa"
import { ConfigModule } from "@medusajs/types"
import { parseCorsOrigins } from "@medusajs/utils"
import cors from "cors"
@@ -85,7 +96,11 @@ export const config: MiddlewaresConfig = {
{
matcher: "/custom*",
middlewares: [
(req, res, next) => {
(
req: MedusaRequest,
res: MedusaResponse,
next: MedusaNextFunction
) => {
const configModule: ConfigModule =
req.scope.resolve("configModule")
@@ -6,9 +6,9 @@ export const metadata = {
In this chapter, you'll learn about how to add new API routes for each HTTP method.
## Handlers of HTTP Methods
## HTTP Method Handler
You can export handler functions for more than one HTTP method in a route file. An API route is created for every HTTP method you export a function for.
An API route is created for every HTTP method you export a handler function for in a route file.
Allowed HTTP methods are: `GET`, `POST`, `DELETE`, `PUT`, `PATCH`, `OPTIONS`, and `HEAD`.
@@ -41,5 +41,5 @@ export const POST = (
This adds two API Routes:
- A `GET` route at `localhost:9000/store/hello-world`.
- A `POST` route at `localhost:9000/store/hello-world`.
- A `GET` route at `http://localhost:9000/store/hello-world`.
- A `POST` route at `http://localhost:9000/store/hello-world`.
@@ -8,7 +8,7 @@ In this chapter, youll learn about middlewares and how to create them.
## What is a Middleware?
A middleware is a function executed when a request is sent to an API Route.
A middleware is a function executed when a request is sent to an API Route. It's executed before the route handler function.
---
@@ -19,14 +19,23 @@ Middlewares are defined in the special file `src/api/middlewares.ts`. The file m
For example:
```ts title="src/api/middlewares.ts"
import { MiddlewaresConfig } from "@medusajs/medusa"
import type {
MedusaNextFunction,
MedusaRequest,
MedusaResponse,
MiddlewaresConfig,
} from "@medusajs/medusa"
export const config: MiddlewaresConfig = {
routes: [
{
matcher: "/store*",
middlewares: [
(req, res, next) => {
(
req: MedusaRequest,
res: MedusaResponse,
next: MedusaNextFunction
) => {
console.log("Received a request!")
next()
@@ -37,17 +46,16 @@ export const config: MiddlewaresConfig = {
}
```
The middleware configurations object has the property `routes`. Its value is an array of middleware route objects, where each object is a middleware to apply to a route pattern.
The middleware configurations object has the property `routes`. Its value is an array of middleware route objects, each having the following properties:
- `matcher`: a string or regular expression indicating the API route path to apply the middleware on.
- `middlewares`: An array of middleware functions.
In the example above, you define a middleware that logs the message `Received a request!` whenever a request is sent to an API route path starting with `/store`.
<Note>
---
The `matcher` property can be a string or a regular expression.
</Note>
### Test Middleware
## Test the Middleware
To test the middleware:
@@ -99,10 +107,15 @@ In addition to the `matcher` configuration, you can restrict which HTTP methods
For example:
export const highlights = [["7", "", "Apply the middleware only on `POST` requests"]]
export const highlights = [["12", "method", "Apply the middleware only on `POST` requests"]]
```ts title="src/api/middlewares.ts" highlights={highlights}
import { MiddlewaresConfig } from "@medusajs/medusa"
```ts title="src/api/middlewares.ts" highlights={highlights} collapsibleLines="1-7" expandButtonLabel="Show Imports"
import type {
MedusaNextFunction,
MedusaRequest,
MedusaResponse,
MiddlewaresConfig,
} from "@medusajs/medusa"
export const config: MiddlewaresConfig = {
routes: [
@@ -110,7 +123,11 @@ export const config: MiddlewaresConfig = {
matcher: "/store*",
method: ["POST", "PUT"],
middlewares: [
(req, res, next) => {
(
req: MedusaRequest,
res: MedusaResponse,
next: MedusaNextFunction
) => {
console.log("Received a request!")
next()
@@ -8,7 +8,7 @@ In this chapter, youll learn about path, query, and request body parameters.
## Path Parameters
To create an API route that accepts a path parameter, create a directory within the route's path whose name is of the format `[param]`.
To create an API route that accepts a path parameter, create a directory within the route file's path whose name is of the format `[param]`.
For example, to create an API Route at the path `/message/{id}`, where `{id}` is a path parameter, create the file `src/api/store/hello-world/[id]/route.ts` with the following content:
@@ -16,7 +16,7 @@ export const singlePathHighlights = [
["11", "req.params.id", "Access the path parameter `id`"]
]
```ts title="src/api/store/hello-world/[id]/route.ts" highlights={singlePathHighlights}
```ts title="src/api/store/hello-world/[id]/route.ts" highlights={singlePathHighlights} apiTesting testApiUrl="http://localhost:9000/store/hello-world/{id}" testApiMethod="GET" testPathParams={{ "id": "1" }}
import type {
MedusaRequest,
MedusaResponse,
@@ -45,7 +45,7 @@ export const multiplePathHighlights = [
["13", "req.params.name", "Access the path parameter `name`"]
]
```ts title="src/api/store/hello-world/[id]/name/[name]/route.ts" highlights={multiplePathHighlights}
```ts title="src/api/store/hello-world/[id]/name/[name]/route.ts" highlights={multiplePathHighlights} apiTesting testApiUrl="http://localhost:9000/store/hello-world/{id}/name/{name}" testApiMethod="GET" testPathParams={{ "id": "1", "name": "John" }}
import type {
MedusaRequest,
MedusaResponse,
@@ -77,7 +77,7 @@ export const queryHighlights = [
["11", "req.query.name", "Access the query parameter `name`"],
]
```ts title="src/api/store/hello-world/route.ts" highlights={queryHighlights}
```ts title="src/api/store/hello-world/route.ts" highlights={queryHighlights} apiTesting testApiUrl="http://localhost:9000/store/hello-world" testApiMethod="GET" testQueryParams={{ "name": "John" }}
import type {
MedusaRequest,
MedusaResponse,
@@ -6,10 +6,14 @@ export const metadata = {
In this chapter, youll learn how to create protected routes.
## Default Protected Routes
## What is a Protected Route?
A protected route is a route that requires requests to be user-authenticated before performing the route's functionality. Otherwise, the request fails, and the user is prevented access.
---
## Default Protected Routes
Medusa applies an authentication guard on the following routes:
- Routes starting with `/admin` require an authenticated admin user.
@@ -41,13 +45,13 @@ export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
export const AUTHENTICATE = false
```
Now, any request sent to the `/store/customers/me/custom` API route is allowed, regardless if the customer is authenticated or not.
Now, any request sent to the `/store/customers/me/custom` API route is allowed, regardless if the customer is authenticated.
---
## Access Logged-In Customer
You can access the logged-in customers ID in all API routes starting with `/store` using the `user.customer_id` property of the `MedusaRequest` object.
You can access the logged-in customers ID in all API routes starting with `/store` using the `auth_context.actor_id` property of the `MedusaRequest` object.
For example:
@@ -67,7 +71,7 @@ export const GET = async (
ModuleRegistrationName.CUSTOMER
)
const customer = await customerModuleService.retrieve(
const customer = await customerModuleService.retrieveCustomer(
req.auth_context.actor_id
)
@@ -75,13 +79,13 @@ export const GET = async (
}
```
In the route handler, you resolve the Customer Module's main service, then use it to retrieve the logged-in customer, if available.
In this example, you resolve the Customer Module's main service, then use it to retrieve the logged-in customer, if available.
---
## Access Logged-In Admin User
You can access the logged-in admin users ID in all API Routes starting with `/admin` using the `user.userId` property of the `MedusaRequest` object.
You can access the logged-in admin users ID in all API Routes starting with `/admin` using the `auth_context.actor_id` property of the `MedusaRequest` object.
For example:
@@ -97,17 +101,19 @@ export const GET = async (
req: AuthenticatedMedusaRequest,
res: MedusaResponse
) => {
const userService: IUserModuleService = req.scope.resolve(
const userModuleService: IUserModuleService = req.scope.resolve(
ModuleRegistrationName.USER
)
const user = await userService.retrieve(req.auth_context.actor_id)
const user = await userModuleService.retrieveUser(
req.auth_context.actor_id
)
// ...
}
```
In the route handler, you resolve the User Module's main service, and then use it to retrieve the logged-in admin user.
In the route handler, you resolve the User Module's main service, then use it to retrieve the logged-in admin user.
---
@@ -151,6 +157,5 @@ The `authenticate` middleware function accepts three parameters:
1. The type of user authenticating. Use `user` for authenticating admin users, and `customer` for authenticating customers.
2. An array of the types of authentication methods allowed. Both `user` and `customer` scopes support `session` and `bearer`. The `admin` scope also supports the `api-key` authentication method.
3. An optional object of options having the following properties:
1. `allowUnauthenticated`: (default: `false`) A boolean indicating whether authentication is required. For example, you may have an API route where you want to access the logged-in customer if available, but guest customers can still access it too. In that case, enable the `allowUnauthenticated` option.
2. `allowUnregistered`: (default: `false`) A boolean indicating whether new users can be authenticated.
3. An optional object of configurations accepting the following property:
- `allowUnauthenticated`: (default: `false`) A boolean indicating whether authentication is required. For example, you may have an API route where you want to access the logged-in customer if available, but guest customers can still access it too.