chore: reorganize docs apps (#7228)
* reorganize docs apps * add README * fix directory * add condition for old docs
This commit is contained in:
1 parent
224ebb2154
commit
4fe28f5a95
6187 files changed
+601447
-598226
No files matched your search
@@ -0,0 +1,85 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Create a Plugin`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this chapter, you’ll learn how to create a plugin.
|
||||
|
||||
## Plugin Development Process
|
||||
|
||||
A plugin consists of Medusa application customizations. So, start with a new Medusa application and build your plugin’s resources.
|
||||
|
||||
Once you’re done developing and testing your customizations, you can package them in a plugin to be installed in other Medusa applications.
|
||||
|
||||

|
||||
|
||||
This chapter explains the steps to create the plugin that packages those customizations. The next chapter explains how to publish the plugin to NPM.
|
||||
|
||||
---
|
||||
|
||||
## Changes to package.json
|
||||
|
||||
### Add Prepare Script
|
||||
|
||||
Your plugin’s customizations must be built for production use. So, add a new `prepare` script to your scripts in `package.json`:
|
||||
|
||||
```json title="package.json"
|
||||
"scripts": {
|
||||
// other scripts...
|
||||
"prepare": "cross-env NODE_ENV=production npm run build:server && medusa-admin bundle"
|
||||
}
|
||||
```
|
||||
|
||||
This builds your application resources, such as services and API routes, and creates a production build of your admin customizations. If your plugin doesn’t have any admin customizations, remove the `medusa-admin bundle` part of the script.
|
||||
|
||||
<Note>
|
||||
|
||||
`cross-env` is already a dependency in your Medusa application. If not, make sure to install it.
|
||||
|
||||
</Note>
|
||||
|
||||
### Change Dependencies
|
||||
|
||||
Your Medusa application requires dependencies that are not relevant to a plugin. For example, you can remove other plugins like `@medusajs/file-local` or modules like `@medusajs/cache-inmemory`.
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
Make sure to remove those plugins/modules from `medusa-config.js`.
|
||||
|
||||
</Note>
|
||||
|
||||
In addition, move `@medusajs/medusa` to be a peer dependency:
|
||||
|
||||
```json title="package.json"
|
||||
"peerDependencies": {
|
||||
"@medusajs/medusa": "YOUR_MEDUSA_VERSION",
|
||||
// other peer dependencies...
|
||||
}
|
||||
```
|
||||
|
||||
If your plugin includes admin customizations, add `react` and `react-router-dom` (if you’re using it) to the `peerDependencies` as well:
|
||||
|
||||
```json title="package.json"
|
||||
"peerDependencies": {
|
||||
// other dependencies...
|
||||
"react": "^18.2.0",
|
||||
"react-router-dom": "^6.13.0"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Changes
|
||||
|
||||
Your Medusa application has files that aren’t relevant to your plugin. For example, files like `src/model/onboarding.ts` used for the onboarding process.
|
||||
|
||||
Go through all files under the `src` directory and remove those that aren’t relevant to your plugin.
|
||||
|
||||
---
|
||||
|
||||
## Plugin Structure
|
||||
|
||||
A published plugin must have its customizations built into the `dist` directory or to the root of the package. This is handled by the `prepare` command you added earlier.
|
||||
|
||||
Once your plugin is created, you’re ready to publish and use it in Medusa applications.
|
||||
@@ -0,0 +1,102 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Integration Services`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this chapter, you’ll learn about special service types used when integrating third-party services.
|
||||
|
||||
## Notification Service
|
||||
|
||||
A notification service is used to send notifications, such as email, in your Medusa application.
|
||||
|
||||
For example, the SendGrid plugin contains a notification service. When the plugin is installed, the Medusa application resolves its notification service to send emails using SendGrid.
|
||||
|
||||
A notification service must extend the `AbstractNotificationService` class from the `@medusajs/medusa` package.
|
||||
|
||||
Refer to [this reference](!resources!/notification-service) to learn more about creating a notification service.
|
||||
|
||||
---
|
||||
|
||||
## File Service
|
||||
|
||||
A file service is used to upload and download files in your Medusa application.
|
||||
|
||||
For example, the S3 plugin contains a file service. When the plugin is installed, the Medusa application resolves its file service to upload and download files, such as product images.
|
||||
|
||||
A file service must extend the `AbstractFileService` class from the `@medusajs/medusa` package.
|
||||
|
||||
Refer to [this reference](!resources!/file-service) to learn more about creating a file service.
|
||||
|
||||
---
|
||||
|
||||
## Search Service
|
||||
|
||||
A search service is used to search data in your store, such as products.
|
||||
|
||||
For example, the MeiliSearch plugin contains a search service. When the plugin is installed, the Medusa application resolves its search service when searching for products.
|
||||
|
||||
A search service must extend the `AbstractSearchService` class from the `@medusajs/utils` package.
|
||||
|
||||
Refer to [this reference](!resources!/search-service) to learn more about creating a search service.
|
||||
|
||||
---
|
||||
|
||||
## Other Integration Types
|
||||
|
||||
If you’re integrating other types of services, such as a CMS or an ERP system, you can create a standard service that extends the `TransactionBaseService` class and implements the necessary methods for your integration.
|
||||
|
||||
Then, you can use that service in other resources, such as an API route or a subscriber.
|
||||
|
||||
---
|
||||
|
||||
## Integration Services Tips
|
||||
|
||||
### Client Initialization
|
||||
|
||||
Part of the integration is interacting with the third-party service using a client.
|
||||
|
||||
Some third-party services provide a Node.js SDK that you can use. In those cases, you can install the SDK and initialize the client in the constructor.
|
||||
|
||||
In other cases, you can install [axios](https://www.npmjs.com/package/axios) and use it to create a client in the constructor.
|
||||
|
||||
For example:
|
||||
|
||||
```tsx
|
||||
import { TransactionBaseService } from "@medusajs/medusa"
|
||||
import { Axios } from "axios"
|
||||
|
||||
type Options = {
|
||||
erp_url: string
|
||||
token: string
|
||||
}
|
||||
|
||||
class ErpService extends TransactionBaseService {
|
||||
protected client: Axios
|
||||
|
||||
constructor({}, options: Options) {
|
||||
super(arguments[0], options)
|
||||
|
||||
this.client = new Axios({
|
||||
baseURL: options.erp_url,
|
||||
headers: {
|
||||
Authorization: `Bearer ${options.token}`,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
async retrieveProductErpDetails(productId: string) {
|
||||
const { data } = await this.client.get(
|
||||
`/product/${productId}`
|
||||
)
|
||||
|
||||
return data
|
||||
}
|
||||
}
|
||||
|
||||
export default ErpService
|
||||
```
|
||||
|
||||
In the above example, you create a client with `axios`. You use the plugin’s options to set the client’s options, such as the base URL and the authorization token.
|
||||
|
||||
Then, you can use the client in other methods to send requests to the third-party service.
|
||||
@@ -0,0 +1,127 @@
|
||||
import { Table } from "docs-ui"
|
||||
import { Check, XMark } from "@medusajs/icons"
|
||||
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Plugin Development`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In the next chapters, you’ll learn about plugins, their use in your application, and how to create and publish plugins.
|
||||
|
||||
## What is a Plugin?
|
||||
|
||||
A plugin is an NPM package that consists of Medusa customizations. It adds new functionalities or integrates third-party services, such as a CMS or MeiliSearch.
|
||||
|
||||
Plugins can be added or removed from your Medusa application without causing side effects.
|
||||
|
||||
<Note title="Use plugins when" type="success">
|
||||
|
||||
- You're integrating a third-party service into your Medusa application.
|
||||
- You're creating reusable Medusa application customizations.
|
||||
- You're providing features that are specific to a Medusa application, such as a migration tool from another platform to Medusa.
|
||||
|
||||
</Note>
|
||||
|
||||
---
|
||||
|
||||
## Plugins vs Modules
|
||||
|
||||
Both plugins and modules are NPM packages that can be installed on your Medusa application without affecting the overall system.
|
||||
|
||||
However, there are key differences between plugins and modules:
|
||||
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell className="w-1/3">Criteria</Table.HeaderCell>
|
||||
<Table.HeaderCell className="!text-center">Plugins</Table.HeaderCell>
|
||||
<Table.HeaderCell className="!text-center">Modules</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
<Table.Row>
|
||||
<Table.Cell>Run in isolation of a Medusa application.</Table.Cell>
|
||||
<Table.Cell><XMark className="mx-auto" /></Table.Cell>
|
||||
<Table.Cell><Check className="mx-auto" /></Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>Can consist of Medusa application customizations, such as API routes or admin widgets.</Table.Cell>
|
||||
<Table.Cell><Check className="mx-auto" /></Table.Cell>
|
||||
<Table.Cell><XMark className="mx-auto" /></Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>Link custom data models to those of Medusa's commerce modules.</Table.Cell>
|
||||
<Table.Cell><XMark className="mx-auto" /></Table.Cell>
|
||||
<Table.Cell><Check className="mx-auto" /></Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>Make architectural changes, such as change the pub/sub service used to emit events.</Table.Cell>
|
||||
<Table.Cell><XMark className="mx-auto" /></Table.Cell>
|
||||
<Table.Cell><Check className="mx-auto" /></Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table>
|
||||
|
||||
## Official and Community Plugins
|
||||
|
||||
Medusa provides official plugins that integrate third-party services like Algolia, SendGrid, S3, and more.
|
||||
|
||||
You can also check out the [Plugins Library](https://medusajs.com/plugins/) for a full list of plugins created by the community.
|
||||
|
||||
---
|
||||
|
||||
## How are Plugins Installed?
|
||||
|
||||
Plugins are installed through NPM. Then, you must add them to the `plugins` array exported as part of the configurations in `medusa-config.js`.
|
||||
|
||||
If you check the `plugins` array in your `medusa-config.js`, you'll find a few plugins already installed:
|
||||
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
`medusa-fulfillment-manual`,
|
||||
`medusa-payment-manual`,
|
||||
{
|
||||
resolve: `@medusajs/file-local`,
|
||||
options: {
|
||||
upload_dir: "uploads",
|
||||
},
|
||||
},
|
||||
{
|
||||
resolve: "@medusajs/admin",
|
||||
/** @type {import('@medusajs/admin').PluginOptions} */
|
||||
options: {
|
||||
autoRebuild: true,
|
||||
develop: {
|
||||
open: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
The items in the `plugins` array can either be:
|
||||
|
||||
- A string which is the plugin's name. In this case, the plugin doesn't require any options;
|
||||
- Or an object having the following properties:
|
||||
- `resolve`: the plugin's name.
|
||||
- `options`: An object of options to pass to the plugin.
|
||||
|
||||
### Configure Admin Customizations
|
||||
|
||||
If a plugin provides customizations to the admin dashboard, you can pass a special option `enableUI` whose value is a boolean indicating whether the admin customizations should be enabled. By default, its value is `false`.
|
||||
|
||||
For example:
|
||||
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
resolve: `medusa-plugin-custom`,
|
||||
options: {
|
||||
// other options...
|
||||
enableUI: true,
|
||||
},
|
||||
},
|
||||
]
|
||||
```
|
||||
@@ -0,0 +1,144 @@
|
||||
import { CodeTabs, CodeTab } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Plugin Options`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this chapter, you’ll learn how to access a plugin’s options in different resources.
|
||||
|
||||
## Services
|
||||
|
||||
In a plugin, a service’s constructor accepts a second parameter: an object holding the plugin’s options.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title="src/services/erp.ts" highlights={[["6", "", "The plugin's options are passed as a parameter."], ["9", "", "Set the plugin's options in a class property."]]}
|
||||
import { TransactionBaseService } from "@medusajs/medusa"
|
||||
|
||||
class ErpService extends TransactionBaseService {
|
||||
protected options_: Record<string, unknown>
|
||||
|
||||
constructor(container, options) {
|
||||
super(container, options)
|
||||
|
||||
this.options_ = options
|
||||
}
|
||||
}
|
||||
|
||||
export default ErpService
|
||||
```
|
||||
|
||||
This adds an `options_` property to the `ErpService` and sets its value using the second parameter of the constructor. You can now use the options in other methods.
|
||||
|
||||
---
|
||||
|
||||
## API Routes
|
||||
|
||||
To access a plugin’s options in an API route, it’s recommended to expose a getter method in the service for the `options_` property that the API route can use.
|
||||
|
||||
For example:
|
||||
|
||||
<CodeTabs group="resource-types">
|
||||
<CodeTab label="Service" value="service">
|
||||
|
||||
```ts title="src/services/erp.ts" highlights={[["11"], ["12"], ["13"], ["14"], ["15"], ["16"]]}
|
||||
import { TransactionBaseService } from "@medusajs/medusa"
|
||||
|
||||
class ErpService extends TransactionBaseService {
|
||||
protected options_: Record<string, unknown>
|
||||
// ...
|
||||
|
||||
get options(): Record<string, unknown> {
|
||||
return this.options_
|
||||
}
|
||||
}
|
||||
|
||||
export default ErpService
|
||||
```
|
||||
|
||||
</CodeTab>
|
||||
<CodeTab label="API Route" value="api-route">
|
||||
|
||||
```ts title="src/subscribers/customer-created.ts"
|
||||
import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
|
||||
import ErpService from "../../services/erp"
|
||||
|
||||
export async function GET(
|
||||
req: MedusaRequest,
|
||||
res: MedusaResponse
|
||||
): Promise<void> {
|
||||
const erpService: ErpService = req.scope.resolve("erpService")
|
||||
|
||||
const pluginOptions = erpService.options
|
||||
|
||||
// use plugin options...
|
||||
}
|
||||
```
|
||||
|
||||
</CodeTab>
|
||||
</CodeTabs>
|
||||
|
||||
---
|
||||
|
||||
## Subscribers
|
||||
|
||||
The object parameter that a subscriber handler function accepts has a `pluginOptions` property. When a subscriber is created in a plugin, this property holds the plugin’s options.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title="src/subscribers/product-updated.ts" highlights={[["7", "", "The plugin's options are passed in the object parameter."]]}
|
||||
import {
|
||||
// other imports...
|
||||
SubscriberArgs,
|
||||
} from "@medusajs/medusa"
|
||||
|
||||
export default async function productUpdateHandler({
|
||||
pluginOptions,
|
||||
}: SubscriberArgs) {
|
||||
console.log(`Plugin options: ${pluginOptions}`)
|
||||
}
|
||||
|
||||
// ...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Scheduled Job
|
||||
|
||||
The object parameter that a scheduled job function accepts has a `pluginOptions` property. When a scheduled job is created in a plugin, this property holds the plugin’s options.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title="src/jobs/once-a-day.ts" highlights={[["6", "", "The plugin's options are passed in the object parameter."]]}
|
||||
import {
|
||||
// ...
|
||||
ScheduledJobArgs,
|
||||
} from "@medusajs/medusa"
|
||||
|
||||
export default function ({ pluginOptions }: ScheduledJobArgs) {
|
||||
console.log(`Plugin options: ${pluginOptions}`)
|
||||
}
|
||||
|
||||
// ...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Loaders
|
||||
|
||||
In a plugin, a loader function accepts a second parameter: an object holding the plugin’s options.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title="src/loaders/on-start.ts" highlights={[["5", "", "The plugin's options are passed as a second parameter to the loader."]]}
|
||||
import { MedusaContainer } from "@medusajs/medusa"
|
||||
|
||||
export default function (
|
||||
container: MedusaContainer,
|
||||
options: Record<string, unknown>
|
||||
) {
|
||||
console.log(`Plugin options: ${options}`)
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,184 @@
|
||||
import { Table } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Publish a Plugin`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this chapter, you’ll learn how to publish a plugin. After you publish your plugin, it will also be available in [Medusa’s Plugins Library](https://medusajs.com/plugins/).
|
||||
|
||||
## package.json Checklist
|
||||
|
||||
Update the following meta information in your plugin’s package.json:
|
||||
|
||||
- `name`: The name of your plugin. By convention, all plugin names start with `medusa` followed by a descriptive name of what the plugin does. For example, `medusa-payment-stripe`.
|
||||
- `description`: A short description of what the plugin does.
|
||||
- `author`: Your name or your company's name.
|
||||
- `repository`: Details about the repository that holds the source code of the plugin. It's an object that holds the following properties:
|
||||
- `type`: Should be `git`.
|
||||
- `url`: The URL to the repository (for example, the GitHub repository holding the code of your plugin).
|
||||
|
||||
### Package Keywords
|
||||
|
||||
It's required for all Medusa plugins to use the keywords `medusa-plugin`.
|
||||
|
||||
The following table mentions other keywords that you can use based on your plugin's functionalities.
|
||||
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>Keyword</Table.HeaderCell>
|
||||
<Table.HeaderCell>Description</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
<Table.Row>
|
||||
<Table.Cell>`medusa-plugin-analytics`</Table.Cell>
|
||||
<Table.Cell>Analytics functionalities or integrations.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>`medusa-plugin-cms`</Table.Cell>
|
||||
<Table.Cell>CMS functionalities or integrations.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>`medusa-plugin-notification`</Table.Cell>
|
||||
<Table.Cell>Notification functionalities or integrations.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>`medusa-plugin-payment`</Table.Cell>
|
||||
<Table.Cell>Payment functionalities or integrations.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>`medusa-plugin-search`</Table.Cell>
|
||||
<Table.Cell>Search functionalities or integrations.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>`medusa-plugin-shipping`</Table.Cell>
|
||||
<Table.Cell>Shipping functionalities or integrations.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>`medusa-plugin-storage`</Table.Cell>
|
||||
<Table.Cell>File service or storage integrations.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>`medusa-plugin-source`</Table.Cell>
|
||||
<Table.Cell>Migrate or import data into Medusa from another platform.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>`medusa-plugin-admin`</Table.Cell>
|
||||
<Table.Cell>Plugins that include only admin customizations.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>`medusa-plugin-other`</Table.Cell>
|
||||
<Table.Cell>Any other type of plugin.</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table>
|
||||
|
||||
---
|
||||
|
||||
## Add NPMIgnore File
|
||||
|
||||
Not all files in your Medusa application are relevant to the published plugin.
|
||||
|
||||
Add the following `.npmignore` file in the root of the plugin's directory to ignore unnecessary files from the published plugin:
|
||||
|
||||
```bash title=".npmignore"
|
||||
# directories
|
||||
.cache
|
||||
.DS_store
|
||||
.github
|
||||
.vscode
|
||||
.yarn
|
||||
build
|
||||
data
|
||||
node_modules
|
||||
src
|
||||
uploads
|
||||
|
||||
# files
|
||||
.babelrc
|
||||
.env*
|
||||
.gitignore
|
||||
.eslintrc
|
||||
.prettierrc
|
||||
.yarnrc.yml
|
||||
index.js
|
||||
medusa-config.js
|
||||
yarn.lock
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Publish Plugin
|
||||
|
||||
<Note type="check">
|
||||
|
||||
To publish a plugin, you need an [NPM account](https://www.npmjs.com/signup).
|
||||
|
||||
</Note>
|
||||
|
||||
To publish the plugin:
|
||||
|
||||
1. Run the `prepare` command:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run prepare
|
||||
```
|
||||
|
||||
2. Publish the NPM package:
|
||||
|
||||
```bash
|
||||
npm publish
|
||||
```
|
||||
|
||||
If you haven’t logged in before with NPM, you’ll be asked to log in first.
|
||||
|
||||
Your package is then published to NPM.
|
||||
|
||||
---
|
||||
|
||||
## Install Plugin in Medusa Applications
|
||||
|
||||
To install your published plugin in a Medusa application, run the following command:
|
||||
|
||||
```bash npm2yarn
|
||||
npm install medusa-plugin-custom
|
||||
```
|
||||
|
||||
Where `medusa-plugin-custom` is your plugin’s name.
|
||||
|
||||
Then, add the plugin to `medusa-config.js`:
|
||||
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
resolve: `medusa-plugin-custom`,
|
||||
options: {
|
||||
// plugin options...
|
||||
},
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Update Plugin
|
||||
|
||||
To publish plugin changes, first, run the following command in the plugin’s directory to change the NPM version:
|
||||
|
||||
```bash
|
||||
npm version <type>
|
||||
```
|
||||
|
||||
Where `<type>` indicates the type of version update you’re publishing. For example, `major`. You can see the [full list of types in NPM’s documentation](https://docs.npmjs.com/cli/v8/commands/npm-version).
|
||||
|
||||
Then, publish the new update:
|
||||
|
||||
```bash
|
||||
npm publish
|
||||
```
|
||||
|
||||
You can then update the plugin in the Medusa applications that use it.
|
||||
Reference in new issue
Block a user