docs: redesigned code blocks (#2745)

* docs: redesigned code blocks to include titles

* docs: added a title where necessary
This commit is contained in:
Shahed Nasser
2022-12-08 18:52:54 +02:00
committed by GitHub
parent 8efae2dfcf
commit a57177ded5
60 changed files with 455 additions and 375 deletions
@@ -43,7 +43,7 @@ Batch job strategies must extend the abstract class `AbstractBatchJobStrategy` a
Add the following content to the file you created:
```tsx
```tsx title=src/strategies/publish.ts
import { AbstractBatchJobStrategy, BatchJobService } from '@medusajs/medusa'
import { EntityManager } from 'typeorm'
@@ -294,9 +294,9 @@ fetch(`<YOUR_SERVER>/admin/batch-jobs`, {
<TabItem value="curl" label="cURL">
```bash
curl --location --request POST '<YOUR_SERVER>/admin/batch-jobs' \
--header 'Authorization: Bearer <API_TOKEN>' \
--header 'Content-Type: application/json' \
curl -L -X POST '<YOUR_SERVER>/admin/batch-jobs' \
-H 'Authorization: Bearer <API_TOKEN>' \
-H 'Content-Type: application/json' \
--data-raw '{
"type": "publish-products",
"context": { },
@@ -342,8 +342,8 @@ fetch(`<YOUR_SERVER>/admin/batch-jobs/${batchJobId}`, {
<TabItem value="curl" label="cURL">
```bash
curl --location --request GET '<YOUR_SERVER>/admin/batch-jobs/<BATCH_JOB_ID>' \
--header 'Authorization: Bearer <API_TOKEN>'
curl -L -X GET '<YOUR_SERVER>/admin/batch-jobs/<BATCH_JOB_ID>' \
-H 'Authorization: Bearer <API_TOKEN>'
# <BATCH_JOB_ID> is the ID of the batch job
```
@@ -352,7 +352,7 @@ curl --location --request GET '<YOUR_SERVER>/admin/batch-jobs/<BATCH_JOB_ID>' \
Based on the batch job strategy implemented in this documentation, the `result` property could be something like this:
```json noHeader
```json noReport
"result": {
"count": 1,
"stat_descriptors": [
@@ -398,8 +398,8 @@ fetch(`<YOUR_SERVER>/admin/batch-jobs/${batchJobId}/confirm`, {
<TabItem value="curl" label="cURL">
```bash
curl --location --request POST '<YOUR_SERVER>/admin/batch-jobs/<BATCH_JOB_ID>/confirm' \
--header 'Authorization: Bearer <API_TOKEN>'
curl -L -X POST '<YOUR_SERVER>/admin/batch-jobs/<BATCH_JOB_ID>/confirm' \
-H 'Authorization: Bearer <API_TOKEN>'
# <BATCH_JOB_ID> is the ID of the batch job
```
@@ -40,7 +40,7 @@ The batch job strategy class must extend the `AbstractBatchJobStrategy` class wh
For example, you can define the following class in the file you created:
```typescript
```typescript title=src/strategies/import.ts
import { AbstractBatchJobStrategy, BatchJobService } from '@medusajs/medusa'
import { EntityManager } from 'typeorm'
@@ -30,7 +30,7 @@ For the example in this tutorial, you can create the file `src/loaders/publish.t
To create a cron job, add the following code in the file you created, which is `src/loaders/publish.ts` in this example:
```ts
```ts title=src/loaders/publish.ts
const publishJob = async (container, options) => {
const eventBus = container.resolve("eventBusService");
eventBus.createCronJob("publish-products", {}, "0 0 * * *", async () => {
@@ -111,7 +111,7 @@ Once it is time to run your cron job based on the cron job expression pattern, t
For example, the above cron job will run at 12 AM and, when it runs, you can see the following logged on your Medusa server:
```bash noHeader
```bash noReport
info: Processing cron job: publish-products
```
@@ -24,7 +24,7 @@ A customer group is stored in the database as a [CustomerGroup](../../../refere
Similar to all entities in Medusa, you can use the `metadata` object attribute to store any custom data you want. For example, you can add some flag or tag to the customer group for a custom use case:
```jsx noHeader
```jsx noReport
metadata: {
is_seller: true
}
@@ -10,7 +10,7 @@ Custom endpoints reside under the `src/api` directory in your Medusa Backend. T
To create a new endpoint, start by creating a new file in `src/api` called `index.ts`. At its basic format, `index.ts` should look something like this:
```ts
```ts title=src/api/index.ts
import { Router } from "express"
export default (rootDirectory, pluginOptions) => {
@@ -86,7 +86,7 @@ router.get("/admin/hello", cors(corsOptions), (req, res) => {
You can add more than one endpoint in `src/api/index.ts`:
```ts
```ts title=src/api/index.ts
router.options("/store/hello", cors(storeCorsOptions))
router.get("/store/hello", cors(storeCorsOptions), (req, res) => {
res.json({
@@ -108,7 +108,7 @@ Alternatively, you can add multiple files for each endpoint or set of endpoints
To do that with the previous example, first, create the file `src/api/store.ts` with the following content:
```ts
```ts title=src/api/store.ts
import cors from "cors"
import { projectConfig } from "../../medusa-config"
@@ -130,7 +130,7 @@ You export a function that receives an Express router as a parameter and adds th
Next, create the file `src/api/admin.ts` with the following content:
```ts
```ts title=src/api/admin.ts
import cors from "cors"
import { projectConfig } from "../../medusa-config"
@@ -152,14 +152,15 @@ Again, you export a function that receives an Express router as a parameter and
Finally, in `src/api/index.ts` import the two functions at the beginning of the file:
```ts
```ts title=src/api/index.ts
import { Router } from "express"
import storeRoutes from "./store"
import adminRoutes from "./admin"
```
and in the exported function, call each of the functions passing them the Express router:
```ts
```ts title=src/api/index.ts
export default () => {
const router = Router()
@@ -6,7 +6,7 @@ In this document, youll learn how you can create an [Entity](overview.md).
To create an entity, create a TypeScript file in `src/models`. For example, heres a `Post` entity defined in the file `src/models/post.ts`:
```tsx
```tsx title=src/models/post.ts
import { BeforeInsert, Column, Entity, PrimaryColumn } from "typeorm";
import { BaseEntity} from "@medusajs/medusa";
import { generateEntityId } from "@medusajs/medusa/dist/utils"
@@ -50,9 +50,9 @@ You can learn more about Migrations, how to create them, and how to run them in
### Create a Repository
Entities data can be easily accessed and modified using Typeorm [Repositories](https://typeorm.io/working-with-repository). To create a repository, create a file in `src/repositories`. For example, heres a repository `PostRepository` that resides in `src/repositories/post.ts`:
Entities data can be easily accessed and modified using Typeorm [Repositories](https://typeorm.io/working-with-repository). To create a repository, create a file in `src/repositories`. For example, heres a repository `PostRepository` created in `src/repositories/post.ts`:
```tsx
```tsx title=src/repositories/post.ts
import { EntityRepository, Repository } from "typeorm"
import { Post } from "../models/post"
@@ -75,7 +75,7 @@ Be careful with your file names as it can cause unclear errors in Typeorm. Make
Before trying this step make sure that youve created and run your migrations. You also need to re-build your code using:
```bash npm2yarn noHeader
```bash npm2yarn noReport
npm run build
```
@@ -44,7 +44,7 @@ You can enable a feature by using the server settings in `medusa-config.js`. You
For example, to enable the Tax-Inclusive Pricing beta feature, add the following to the exported object in `medusa-config.js`:
```jsx
```jsx title=medusa-config.js
module.exports = {
featureFlags: {
tax_inclusive_pricing: true
@@ -20,7 +20,7 @@ Creating a Notification Provider is as simple as creating a TypeScript or JavaS
For example, create the file `src/services/email-sender.ts` with the following content:
```ts
```ts title=src/services/email-sender.ts
import { AbstractNotificationService } from "@medusajs/medusa";
import { EntityManager } from "typeorm";
@@ -89,7 +89,6 @@ class EmailSenderService extends AbstractNotificationService {
static identifier = "email-sender";
protected orderService: OrderService;
// highlight-start
constructor(container, options) {
super(container);
//you can access options here in case you're
@@ -97,7 +96,6 @@ class EmailSenderService extends AbstractNotificationService {
this.orderService = container.orderService;
}
// highlight-end
//...
}
@@ -219,7 +217,7 @@ This section will not cover the basics of Subscribers. You can read the [Subscri
Following the previous example, to make sure the `email-sender` Notification Provider handles the `order.placed` event, create the file `src/subscribers/notification.js` with the following content:
```ts
```ts title=src/subscribers/notification.js
class NotificationSubscriber {
constructor({ notificationService }) {
notificationService.subscribe('order.placed', 'email-sender');
@@ -48,7 +48,7 @@ The first step to create a payment provider is to create a JavaScript or TypeScr
For example, create the file `src/services/my-payment.ts` with the following content:
```ts
```ts title=src/services/my-payment.ts
import { AbstractPaymentService, Cart, Data, Payment, PaymentSession, PaymentSessionStatus, TransactionBaseService } from "@medusajs/medusa"
import { EntityManager } from "typeorm";
+11 -11
View File
@@ -38,7 +38,7 @@ Update the `name` field in the `package.json` file to the name of your plugin. T
A basic Medusa server installed with the `medusa new` command has dependencies similar to this:
```json
```json title=package.json
"dependencies": {
"@medusajs/medusa": "^1.3.1",
"@medusajs/medusa-cli": "^1.3.0",
@@ -60,7 +60,7 @@ For a plugin, a lot of these dependencies are not necessary or should be labeled
The recommended change is the following:
```json
```json title=package.json
"peerDependencies": {
"@medusajs/medusa": "^1.3.1",
"medusa-interfaces": "^1.3.0",
@@ -98,7 +98,7 @@ If you don't make changes to the `build` and `watch` commands, please be aware o
A basic Medusa installation comes with the following scripts:
```json
```json title=package.json
"scripts": {
"seed": "medusa seed -f ./data/seed.json",
"build": "babel src --out-dir . --ignore **/__tests__ --extensions \".ts,.js\"",
@@ -110,7 +110,7 @@ The `seed` and `start` scripts aren't necessary for plugin development so you ca
Its also recommended to add the `watch` script that automatically compiles your files if they are changed:
```json
```json title=package.json
"watch": "babel -w src --out-dir . --ignore **/__tests__ --extensions \".ts,.js\""
```
@@ -124,7 +124,7 @@ Testing the plugin is covered in a [later section](#test-your-plugin).
Another recommended script is the `prepare` script that builds your files under a “production” environment:
```json
```json title=package.json
"prepare": "cross-env NODE_ENV=production npm run build"
```
@@ -161,7 +161,7 @@ If files and directories aren't placed in the root of your plugin, the Medusa se
An example of a plugin's directory before testing or publishing:
```bash noHeader
```bash noReport
medusa-plugin-custom
|
|_ _ _ api
@@ -202,7 +202,7 @@ Plugins often allow developers that will later use them to enter their own confi
To pass a plugin its configurations on a Medusa server, you have to add it to the `plugins` array in `medusa-config.js`:
```jsx
```jsx title=medusa-config.js
const plugins = [
//...
{
@@ -216,7 +216,7 @@ const plugins = [
Then, you can have access to your plugin configuration in the constructor of services in your plugin:
```jsx
```jsx title=src/service/test.ts
//In a service in your plugin
constructor({}, options) {
//options contains plugin configurations
@@ -226,7 +226,7 @@ constructor({}, options) {
You can also have access to the configurations in endpoints in your plugin:
```jsx
```jsx title=src/api/index.ts
//in an endpoint in your plugin
export default (rootDirectory, options) => {
//options contain the plugin configurations
@@ -281,7 +281,7 @@ If youre running the `watch` command, you dont need to run the `build` com
Then, add your plugin into the array of plugins in `medusa-config.js`:
```jsx
```jsx title=medusa-config.js
const plugins = [
//...
{
@@ -364,7 +364,7 @@ So, you can ignore files and directories like `src` from the final published NPM
To do that, create the file `.npmignore` with the following content:
```bash
```bash title=.npmignore
/lib
node_modules
.DS_store
@@ -37,7 +37,7 @@ When you create a price list, you can specify different conditions to control wh
In the body of your request, aside from the required fields, you can send the following fields to apply different conditions:
```js noHeader
```js noReport
{
prices: [
{
@@ -135,9 +135,9 @@ fetch(`<SERVER_URL>/admin/price-lists`, {
<TabItem value="curl" label="cURL">
```bash
curl --location --request POST '<YOUR_SERVER_URL>/admin/price-lists' \
--header 'Authorization: Bearer <API_TOKEN>' \
--header 'Content-Type: application/json' \
curl -L -X POST '<YOUR_SERVER_URL>/admin/price-lists' \
-H 'Authorization: Bearer <API_TOKEN>' \
-H 'Content-Type: application/json' \
--data-raw '{
"name": "New Price List",
"description": "A new price list",
@@ -200,8 +200,8 @@ fetch(`<SERVER_URL>/admin/price-lists/${priceListId}`, {
<TabItem value="curl" label="cURL">
```jsx
curl --location --request GET '<SERVER_URL>/admin/price-lists/{id}' \
--header 'Authorization: Bearer <API_TOKEN>'
curl -L -X GET '<SERVER_URL>/admin/price-lists/{id}' \
-H 'Authorization: Bearer <API_TOKEN>'
```
</TabItem>
@@ -251,9 +251,9 @@ fetch(`<SERVER_URL>/admin/price-lists/${priceListId}`, {
<TabItem value="curl" label="cURL">
```bash
curl --location --request POST '<SERVER_URL>/admin/price-lists/<PRICE_LIST_ID>' \
--header 'Authorization: Bearer <API_TOKEN>' \
--header 'Content-Type: application/json' \
curl -L -X POST '<SERVER_URL>/admin/price-lists/<PRICE_LIST_ID>' \
-H 'Authorization: Bearer <API_TOKEN>' \
-H 'Content-Type: application/json' \
--data-raw '{
"ends_at": "2022-10-11"
}'
@@ -326,9 +326,9 @@ fetch(`<SERVER_URL>/admin/price-lists/${priceListId}/prices/batch`, {
<TabItem value="curl" label="cURL">
```bash
curl --location --request POST '<SERVER_URL>/admin/price-lists/<PRICE_LIST_ID>' \
--header 'Authorization: Bearer <API_TOKEN>' \
--header 'Content-Type: application/json' \
curl -L -X POST '<SERVER_URL>/admin/price-lists/<PRICE_LIST_ID>' \
-H 'Authorization: Bearer <API_TOKEN>' \
-H 'Content-Type: application/json' \
--data-raw '{
"prices": [
{
@@ -379,8 +379,8 @@ fetch(`<SERVER_URL>/admin/price-lists/${priceListId}/products/${productId}/price
<TabItem value="curl" label="cURL">
```bash
curl --location --request DELETE '<SERVER_URL>/admin/price-lists/<PRICE_LIST_ID>/products/<PRODUCT_ID>/prices' \
--header 'Authorization: Bearer <API_TOKEN>'
curl -L -X DELETE '<SERVER_URL>/admin/price-lists/<PRICE_LIST_ID>/products/<PRODUCT_ID>/prices' \
-H 'Authorization: Bearer <API_TOKEN>'
```
</TabItem>
@@ -420,8 +420,8 @@ fetch(`<SERVER_URL>/admin/price-lists/${priceListId}/variants/${variantId}/price
<TabItem value="curl" label="cURL">
```jsx
curl --location --request DELETE '<SERVER_URL>/admin/price-lists/<PRICE_LIST_ID>/variants/<VARIANT_ID>/prices' \
--header 'Authorization: Bearer <API_TOKEN>'
curl -L -X DELETE '<SERVER_URL>/admin/price-lists/<PRICE_LIST_ID>/variants/<VARIANT_ID>/prices' \
-H 'Authorization: Bearer <API_TOKEN>'
```
</TabItem>
@@ -463,8 +463,8 @@ fetch(`<SERVER_URL>/admin/price-lists/${priceListId}`, {
<TabItem value="curl" label="cURL">
```jsx
curl --location --request DELETE '<SERVER_URL>/admin/price-lists/<PRICE_LIST_ID>' \
--header 'Authorization: Bearer <API_TOKEN>'
curl -L -X DELETE '<SERVER_URL>/admin/price-lists/<PRICE_LIST_ID>' \
-H 'Authorization: Bearer <API_TOKEN>'
```
</TabItem>
@@ -12,7 +12,7 @@ If youre interested in learning what a price selection strategy is and how it
Create a TypeScript or JavaScript file in `src/strategies` of your Medusa server project with a class that extends the `AbstractPriceSelectionStrategy` class:
```typescript
```typescript title=src/strategies/price.ts
import { AbstractPriceSelectionStrategy, IPriceSelectionStrategy, PriceSelectionContext, PriceSelectionResult } from "@medusajs/medusa";
import { EntityManager } from "typeorm";
@@ -80,7 +80,7 @@ This method accepts the variant ID as a first parameter and the [context](./inde
This method must return an object having the following fields:
```typescript noHeader
```typescript noReport
{
originalPrice, //number | null
calculatedPrice, //number | null
@@ -90,9 +90,9 @@ fetch(`<SERVER_URL>/admin/sales-channels`, {
<TabItem value="curl" label="cURL">
```bash
curl --location --request POST '<SERVER_URL>/admin/sales-channels' \
--header 'Authorization: Bearer <API_TOKEN>' \
--header 'Content-Type: application/json' \
curl -L -X POST '<SERVER_URL>/admin/sales-channels' \
-H 'Authorization: Bearer <API_TOKEN>' \
-H 'Content-Type: application/json' \
--data-raw '{
name: 'App',
description: 'Mobile app'
@@ -139,8 +139,8 @@ fetch(`<SERVER_URL>/admin/sales-channels`, {
<TabItem value="curl" label="cURL">
```bash
curl --location --request GET '<SERVER_URL>/admin/sales-channels' \
--header 'Authorization: Bearer <API_TOKEN>'
curl -L -X GET '<SERVER_URL>/admin/sales-channels' \
-H 'Authorization: Bearer <API_TOKEN>'
```
</TabItem>
@@ -181,8 +181,8 @@ fetch(`<SERVER_URL>/admin/sales-channels/${salesChannelId}`, {
<TabItem value="curl" label="cURL">
```bash
curl --location --request GET '<SERVER_URL>/admin/sales-channels/<SALES_CHANNEL_ID>' \
--header 'Authorization: Bearer <API_TOKEN>'
curl -L -X GET '<SERVER_URL>/admin/sales-channels/<SALES_CHANNEL_ID>' \
-H 'Authorization: Bearer <API_TOKEN>'
```
</TabItem>
@@ -232,9 +232,9 @@ fetch(`<SERVER_URL>/admin/sales-channels/${salesChannelId}`, {
<TabItem value="curl" label="cURL">
```bash
curl --location --request POST '<SERVER_URL>/admin/sales-channels/<SALES_CHANNEL_ID>' \
--header 'Authorization: Bearer <API_TOKEN>' \
--header 'Content-Type: application/json' \
curl -L -X POST '<SERVER_URL>/admin/sales-channels/<SALES_CHANNEL_ID>' \
-H 'Authorization: Bearer <API_TOKEN>' \
-H 'Content-Type: application/json' \
--data-raw '{
"is_disabled": false
}'
@@ -283,8 +283,8 @@ fetch(`<SERVER_URL>/admin/sales-channels/${salesChannelId}`, {
<TabItem value="curl" label="cURL">
```bash
curl --location --request DELETE '<SERVER_URL>/admin/sales-channels/<SALES_CHANNEL_ID>' \
--header 'Authorization: Bearer <API_TOKEN>'
curl -L -X DELETE '<SERVER_URL>/admin/sales-channels/<SALES_CHANNEL_ID>' \
-H 'Authorization: Bearer <API_TOKEN>'
```
</TabItem>
@@ -344,9 +344,9 @@ fetch(`<SERVER_URL>/admin/sales-channels/${salesChannelId}/products/batch`, {
<TabItem value="curl" label="cURL">
```bash
curl --location --request POST '<SERVER_URL>/admin/sales-channels/<SALES_CHANNEL_ID>/products/batch' \
--header 'Authorization: Bearer <API_TOKEN>' \
--header 'Content-Type: application/json' \
curl -L -X POST '<SERVER_URL>/admin/sales-channels/<SALES_CHANNEL_ID>/products/batch' \
-H 'Authorization: Bearer <API_TOKEN>' \
-H 'Content-Type: application/json' \
--data-raw '{
"product_ids": [
{
@@ -398,8 +398,8 @@ fetch(`<SERVER_URL>/admin/products?sales_channel_id[0]=${salesChannelId}`, {
<TabItem value="curl" label="cURL">
```bash
curl --location --request GET '<SERVER_URL>/admin/products?sales_channel_id[0]=<SALES_CHANNEL_ID>' \
--header 'Authorization: Bearer <API_TOKEN>'
curl -L -X GET '<SERVER_URL>/admin/products?sales_channel_id[0]=<SALES_CHANNEL_ID>' \
-H 'Authorization: Bearer <API_TOKEN>'
```
</TabItem>
@@ -461,9 +461,9 @@ fetch(`<SERVER_URL>/admin/sales-channels/${salesChannelId}/products/batch`, {
<TabItem value="curl" label="cURL">
```jsx
curl --location --request DELETE '<SERVER_URL>/admin/sales-channels/<SALES_CHANNEL_ID>/products/batch' \
--header 'Authorization: Bearer <API_TOKEN>' \
--header 'Content-Type: application/json' \
curl -L -X DELETE '<SERVER_URL>/admin/sales-channels/<SALES_CHANNEL_ID>/products/batch' \
-H 'Authorization: Bearer <API_TOKEN>' \
-H 'Content-Type: application/json' \
--data-raw '{
"product_ids": [
{
@@ -519,8 +519,8 @@ fetch(`<SERVER_URL>/admin/orders?sales_channel_id[0]=${salesChannelId}`, {
<TabItem value="curl" label="cURL">
```jsx
curl --location --request GET '<SERVER_URL>/admin/orders?sales_channel_id[0]=<SALES_CHANNEL_ID>' \
--header 'Authorization: Bearer <API_TOKEN>'
curl -L -X GET '<SERVER_URL>/admin/orders?sales_channel_id[0]=<SALES_CHANNEL_ID>' \
-H 'Authorization: Bearer <API_TOKEN>'
```
</TabItem>
@@ -8,7 +8,7 @@ To create a service, create a TypeScript or JavaScript file in `src/services` to
For example, if you want to create a service `helloService`, create the file `hello.ts` in `src/services` with the following content:
```ts
```ts title=/src/services/hello.ts
import { TransactionBaseService } from '@medusajs/medusa';
import { EntityManager } from 'typeorm';
@@ -54,7 +54,7 @@ In this section, you'll learn how to use services throughout your Medusa server.
Before using your service, make sure you run the `build` command:
```bash npm2yarn noHeader
```bash npm2yarn noReport
npm run build
```
@@ -23,7 +23,7 @@ Fulfillment providers are loaded and installed on the server startup.
The first step is to create a JavaScript or TypeScript file under `src/services`. For example, create the file `src/services/my-fulfillment.ts` with the following content:
```ts
```ts title=src/services/my-fulfillment.ts
import { FulfillmentService } from "medusa-interfaces"
class MyFulfillmentService extends FulfillmentService {
@@ -16,9 +16,9 @@ After creating the file under `src/subscribers`, in the constructor of your subs
The `eventBusService.subscribe` method receives the name of the event as a first parameter and as a second parameter a method in your subscriber that will handle this event.
For example, here is the `OrderNotifierSubscriber` class which is created in `src/subscribers/orderNotifier.js`:
For example, here is the `OrderNotifierSubscriber` class created in `src/subscribers/orderNotifier.js`:
```ts
```ts title=src/subscribers/orderNotifier.js
class OrderNotifierSubscriber {
constructor({ eventBusService }) {
eventBusService.subscribe("order.placed", this.handleOrder);
@@ -58,7 +58,7 @@ The `ShippingMethod` entity also has the `includes_tax` attribute. Its value is
When a price is tax-inclusive, the tax amount is calculated using the following formula:
```jsx noHeader
```jsx noReport
const taxAmount = (taxRate * taxInclusivePrice) / (1 + taxRate)
```
@@ -110,7 +110,7 @@ Price lists include a list of prices that can be used to override the original p
Each variants price in the price list is compared to the variants original price using the following condition:
```jsx noHeader
```jsx noReport
amount < (1 + taxRate) * calculatedPrice
```
@@ -120,7 +120,7 @@ Where `amount` is the amount of the variants price in the price list, `taxRat
Here is an example of these fields when tax inclusivity is enabled for both the currency and the price list:
```jsx noHeader
```jsx noReport
{
original_price: 110,
calculated_price: 100,