From 2ceed66b4d5961499e9449e9562df4bcb312f1d6 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Mon, 15 Sep 2025 14:06:56 +0300 Subject: [PATCH] docs: fix issues in product builder tutorial (#13505) --- www/apps/book/public/llms-full.txt | 287 +++++++++++------- .../tutorials/product-builder/page.mdx | 8 +- www/apps/resources/generated/edit-dates.mjs | 2 +- 3 files changed, 188 insertions(+), 109 deletions(-) diff --git a/www/apps/book/public/llms-full.txt b/www/apps/book/public/llms-full.txt index cd736fb29d..a4d8d098b8 100644 --- a/www/apps/book/public/llms-full.txt +++ b/www/apps/book/public/llms-full.txt @@ -6991,6 +6991,8 @@ The Medusa Admin dashboard is customizable, allowing you to add new pages, calle For example, you can add a new page to show and manage product reviews, which aren't available natively in Medusa. +You can create a UI route directly in your Medusa application, or in a [plugin](https://docs.medusajs.com/learn/fundamentals/plugins/index.html.md) if you want to share the UI route across multiple Medusa applications. + *** ## How to Create a UI Route? @@ -7345,6 +7347,8 @@ The Medusa Admin's pages are customizable for inserting widgets of custom conten You create these widgets as React components that render the content and functionality of the widget. +You can create an admin widget directly in your Medusa application, or in a [plugin](https://docs.medusajs.com/learn/fundamentals/plugins/index.html.md) if you want to share the widget across multiple Medusa applications. + *** ## How to Create a Widget? @@ -24397,13 +24401,15 @@ Learn more about workflows in [this documentation](https://docs.medusajs.com/doc # Authentication Flows with the Auth Main Service -In this document, you'll learn how to use the Auth Module's main service's methods to implement authentication flows and reset a user's password. +In this guide, you'll learn how to use the methods of the Auth Module's service to implement authentication flows and reset a user's password. + +This guide is only recommended for complex cases, where you may need to heavily customize the authentication flows and need to use the Auth Module's service methods directly. For most use cases, you should use the [auth routes](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/auth/authentication-route/index.html.md) instead. ## Authentication Methods ### Register -The [register method of the Auth Module's main service](https://docs.medusajs.com/references/auth/register/index.html.md) creates an auth identity that can be authenticated later. +The [register method of the Auth Module's service](https://docs.medusajs.com/references/auth/register/index.html.md) creates an auth identity that can be authenticated later. For example: @@ -24412,41 +24418,83 @@ const data = await authModuleService.register( "emailpass", // passed to auth provider { - // ... + // pass data from request parameters, such as + url: "example.com", + headers: req.headers, + query: req.query, + // pass in the body the data necessary for the authentication provider + // to register the user, such as email and password + body: { + email: "user@example.com", + password: "supersecret", + }, + protocol: req.protocol, } ) ``` -This method calls the `register` method of the provider specified in the first parameter and returns its data. +This method calls the `register` method of the provider specified in the first parameter. The method passes the second parameter as input for the provider, and returns its data. + +Based on the returned data, you can determine if the registration was successful, and if any further action is required to complete the registration. This is explained further in the auth flows sections below. ### Authenticate -To authenticate a user, you use the [authenticate method of the Auth Module's main service](https://docs.medusajs.com/references/auth/authenticate/index.html.md). For example: +To authenticate or log in a user, you use the [authenticate method of the Auth Module's service](https://docs.medusajs.com/references/auth/authenticate/index.html.md). For example: ```ts const data = await authModuleService.authenticate( "emailpass", // passed to auth provider { - // ... + // pass data from request parameters, such as + url: "example.com", + headers: req.headers, + query: req.query, + // pass in the body the data necessary for the authentication provider + // to authenticate the user, such as email and password + body: { + email: "user@example.com", + password: "supersecret", + }, + protocol: req.protocol, } ) ``` -This method calls the `authenticate` method of the provider specified in the first parameter and returns its data. +This method calls the `authenticate` method of the provider specified in the first parameter. The method passes the second parameter as input for the provider, and returns its data. + +Based on the returned data, you can determine if the authentication was successful, and if any further action is required to complete the authentication. This is explained further in the auth flows sections below. *** ## Auth Flow 1: Basic Authentication -The basic authentication flow requires first using the `register` method, then the `authenticate` method: +The basic authentication flow requires first using the `register` method, then the `authenticate` method. + +![Diagram showcasing the basic authentication flow](https://res.cloudinary.com/dza7lstvk/image/upload/v1711373749/Medusa%20Resources/basic-auth_lgpqsj.jpg) + +### Step 1: Register User ```ts -const { success, authIdentity, error } = await authModuleService.register( +const { + success, + authIdentity, + error +} = await authModuleService.register( "emailpass", // passed to auth provider { - // ... + // pass data from request parameters, such as + url: "example.com", + headers: req.headers, + query: req.query, + // pass in the body the data necessary for the authentication provider + // to register the user, such as email and password + body: { + email: "user@example.com", + password: "supersecret", + }, + protocol: req.protocol, } ) @@ -24455,13 +24503,46 @@ if (error) { // TODO return an error return } +``` -// later (can be another route for log-in) -const { success, authIdentity, location } = await authModuleService.authenticate( +If the `register` method returns an `error` property, the registration failed, and you can return an error message to the user. + +Otherwise, if the `success` property is `true`, the registration was successful, and the user's authentication details are available within the `authIdentity` object. + +Check out the [AuthIdentity](https://docs.medusajs.com/references/auth/models/AuthIdentity/index.html.md) reference for the received properties in `authIdentity`. + +#### Registering Auth Identities with Same Identifier + +If an auth identity, such as a `customer`, tries to register with an email of another auth identity, the `register` method returns an error. This can happen either if another customer is using the same email, or an admin user has the same email. + +There are two ways to handle this: + +- Consider the customer authenticated if the `authenticate` method validates that the email and password are correct. This allows admin users, for example, to authenticate as customers. +- Return an error message to the customer, informing them that the email is already in use. + +### Step 2: Authenticate User + +```ts +// later (can be another route for login) +const { + success, + authIdentity, + location +} = await authModuleService.authenticate( "emailpass", // passed to auth provider { - // ... + // pass data from request parameters, such as + url: "example.com", + headers: req.headers, + query: req.query, + // pass in the body the data necessary for the authentication provider + // to authenticate the user, such as email and password + body: { + email: "user@example.com", + password: "supersecret", + }, + protocol: req.protocol, } ) @@ -24470,22 +24551,9 @@ if (success && !location) { } ``` -If `success` is true and `location` isn't set, the user is authenticated successfully, and their authentication details are available within the `authIdentity` object. +If the `authenticate` method returns a `success` property that is `true`, and the `location` property is not set, the user is authenticated successfully. Their authentication details are available within the `authIdentity` object. -The next section explains the flow if `location` is set. - -Check out the [AuthIdentity](https://docs.medusajs.com/references/auth/models/AuthIdentity/index.html.md) reference for the received properties in `authIdentity`. - -![Diagram showcasing the basic authentication flow](https://res.cloudinary.com/dza7lstvk/image/upload/v1711373749/Medusa%20Resources/basic-auth_lgpqsj.jpg) - -### Auth Identity with Same Identifier - -If an auth identity, such as a `customer`, tries to register with an email of another auth identity, the `register` method returns an error. This can happen either if another customer is using the same email, or an admin user has the same email. - -There are two ways to handle this: - -- Consider the customer authenticated if the `authenticate` method validates that the email and password are correct. This allows admin users, for example, to authenticate as customers. -- Return an error message to the customer, informing them that the email is already in use. +Otherwise, if the `location` property is set, you must follow the [third-party service authentication flow](#auth-flow-2-third-party-service-authentication) to complete the authentication. *** @@ -24498,12 +24566,17 @@ const { success, authIdentity, location } = await authModuleService.authenticate "google", // passed to auth provider { - // ... + // pass data from request parameters, such as + url: "example.com", + headers: req.headers, + query: req.query, + body: req.body, + protocol: req.protocol, } ) if (location) { - // return the location for the front-end to redirect to + // return the location for the frontend to redirect to } if (!success) { @@ -24513,18 +24586,22 @@ if (!success) { // authentication successful ``` -If the `authenticate` method returns a `location` property, the authentication process requires the user to perform an action with a third-party service. So, you return the `location` to the front-end or client to redirect to that URL. +If the `authenticate` method returns a `location` property, the authentication process requires the user to perform an action with a third-party service. So, you return the `location` to the frontend or client to redirect to that URL. -For example, when using the `google` provider, the `location` is the URL that the user is navigated to login. +For example, when using the `google` provider, the `location` is the URL that the user must be redirected to in order to log in with their Google account. ![Diagram showcasing the first part of the third-party authentication flow](https://res.cloudinary.com/dza7lstvk/image/upload/v1711374847/Medusa%20Resources/third-party-auth-1_enyedy.jpg) ### Overriding Callback URL -The Google and GitHub providers allow you to override their `callbackUrl` option during authentication. This is useful when you redirect the user after authentication to a URL based on its actor type. For example, you redirect admin users and customers to different pages. +The Google and GitHub providers allow you to override their `callbackUrl` option during authentication. This is useful when you redirect the user after authentication to a URL based on their actor type. For example, you redirect admin users and customers to different pages. ```ts -const { success, authIdentity, location } = await authModuleService.authenticate( +const { + success, + authIdentity, + location +} = await authModuleService.authenticate( "google", // passed to auth provider { @@ -24538,7 +24615,7 @@ const { success, authIdentity, location } = await authModuleService.authenticate Providers handling this authentication flow must implement the `validateCallback` method. It implements the logic to validate the authentication with the third-party service. -So, once the user performs the required action with the third-party service (for example, log-in with Google), the frontend must redirect to an API route that uses the [validateCallback method of the Auth Module's main service](https://docs.medusajs.com/references/auth/validateCallback/index.html.md). +So, once the user performs the required action with the third-party service (for example, log in with Google), the frontend must redirect to an API route that uses the [validateCallback method of the Auth Module's service](https://docs.medusajs.com/references/auth/validateCallback/index.html.md). The method calls the specified provider’s `validateCallback` method passing it the authentication details it received in the second parameter: @@ -24571,7 +24648,7 @@ If the returned `success` property is `true`, the authentication with the third- ## Reset Password -To update a user's password or other authentication details, use the `updateProvider` method of the Auth Module's main service. It calls the `update` method of the specified authentication provider. +To update a user's password or other authentication details, use the [updateProvider method of the Auth Module's service](https://docs.medusajs.com/references/auth/updateProvider/index.html.md). It calls the `update` method of the specified authentication provider. For example: @@ -24592,20 +24669,20 @@ if (success) { The method accepts as a first parameter the ID of the provider, and as a second parameter the data necessary to reset the password. -In the example above, you use the `emailpass` provider, so you have to pass an object having an `email` and `password` properties. +In the example above, you use the `emailpass` provider, so you have to pass an object having `entity_id` and `password` properties. -If the returned `success` property is `true`, the password has reset successfully. +If the returned `success` property is `true`, the password has been reset successfully. # Auth Identity and Actor Types -In this document, you’ll learn about concepts related to identity and actors in the Auth Module. +In this guide, you’ll learn about concepts related to identity and actors in the Auth Module. ## What is an Auth Identity? The [AuthIdentity data model](https://docs.medusajs.com/references/auth/models/AuthIdentity/index.html.md) represents a user registered by an [authentication provider](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/auth/auth-providers/index.html.md). When a user is registered using an authentication provider, the provider creates a record of `AuthIdentity`. -Then, when the user logs-in in the future with the same authentication provider, the associated auth identity is used to validate their credentials. +Then, when the user logs in with the same authentication provider, the associated auth identity is used to validate their credentials. *** @@ -24613,7 +24690,7 @@ Then, when the user logs-in in the future with the same authentication provider, An actor type is a type of user that can be authenticated. The Auth Module doesn't store or manage any user-like models, such as for customers or users. Instead, the user types are created and managed by other modules. For example, a customer is managed by the [Customer Module](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/customer/index.html.md). -Then, when an auth identity is created for the actor type, the ID of the user is stored in the `app_metadata` property of the auth identity. +When an auth identity is created for an actor type, the ID of the user is stored in the `app_metadata` property of the auth identity. For example, an auth identity of a customer has the following `app_metadata` property: @@ -24631,7 +24708,7 @@ The ID of the user is stored in the key `{actor_type}_id` of the `app_metadata` ## Protect Routes by Actor Type -When you protect routes with the `authenticate` middleware, you specify in its first parameter the actor type that must be authenticated to access the specified API routes. +When you protect routes with the [authenticate middleware](https://docs.medusajs.com/docs/learn/fundamentals/api-routes/protected-routes/index.html.md), you specify in its first parameter the actor type that must be authenticated to access the API routes. For example: @@ -24659,26 +24736,24 @@ By specifying `user` as the first parameter of `authenticate`, only authenticate ## Custom Actor Types -You can define custom actor types that allows a custom user, managed by your custom module, to authenticate into Medusa. +You can define custom actor types that allow a custom user, managed by your custom module, to authenticate into Medusa. For example, if you have a custom module with a `Manager` data model, you can authenticate managers with the `manager` actor type. -Learn how to create a custom actor type in [this guide](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/auth/create-actor-type/index.html.md). +Learn how to create a custom actor type in the [Create Manager Actor Type guide](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/auth/create-actor-type/index.html.md). # Emailpass Auth Module Provider -In this document, you’ll learn about the Emailpass auth module provider and how to install and use it in the Auth Module. +In this guide, you’ll learn about the Emailpass Auth Module Provider and how to configure it. -Using the Emailpass auth module provider, you allow users to register and login with an email and password. - -*** +By using the Emailpass Auth Module Provider, you allow users to register and log in with an email and password. ## Register the Emailpass Auth Module Provider -The Emailpass auth provider is registered by default with the Auth Module. +The Emailpass Auth Module Provider is registered by default with the Auth Module. -If you want to pass options to the provider, add the provider to the `providers` option of the Auth Module: +If you want to pass options to the provider, add the provider to the `providers` option of the Auth Module in your `medusa-config.ts`: ```ts title="medusa-config.ts" import { Modules, ContainerRegistrationKeys } from "@medusajs/framework/utils" @@ -24712,7 +24787,7 @@ module.exports = defineConfig({ |Configuration|Description|Required|Default| |---|---|---|---|---|---|---| -|\`hashConfig\`|An object of configurations to use when hashing the user's +|\`hashConfig\`|An object of configurations for hashing the user's password. Refer to |No|\`\`\`ts const hashConfig = \{ logN: 15, @@ -24730,22 +24805,18 @@ const hashConfig = \{ # GitHub Auth Module Provider -In this document, you’ll learn about the GitHub Auth Module Provider and how to install and use it in the Auth Module. +In this guide, you’ll learn about the GitHub Auth Module Provider and how to configure it. -The Github Auth Module Provider authenticates users with their GitHub account. +The GitHub Auth Module Provider allows you to authenticate users with their GitHub account. -Learn about the authentication flow in [this guide](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/auth/authentication-route/index.html.md). - -*** - -## Register the Github Auth Module Provider +## Register the GitHub Auth Module Provider ### Prerequisites -- [Register GitHub App. When setting the Callback URL, set it to a URL in your frontend that later uses Medusa's callback route to validate the authentication.](https://docs.github.com/en/apps/creating-github-apps/setting-up-a-github-app/creating-a-github-app) +- [Register a GitHub App. When setting the Callback URL, set it to a URL in your frontend that later uses Medusa's callback route to validate the authentication.](https://docs.github.com/en/apps/creating-github-apps/setting-up-a-github-app/creating-a-github-app) - [Retrieve the client ID and client secret of your GitHub App](https://docs.github.com/en/rest/authentication/authenticating-to-the-rest-api?apiVersion=2022-11-28#using-basic-authentication) -Add the module to the array of providers passed to the Auth Module: +To use the GitHub Auth Module Provider, add the module to the array of providers passed to the Auth Module in your `medusa-config.ts`: ```ts title="medusa-config.ts" import { Modules, ContainerRegistrationKeys } from "@medusajs/framework/utils" @@ -24799,26 +24870,22 @@ GITHUB_CALLBACK_URL= ## Override Callback URL During Authentication -In many cases, you may have different callback URL for actor types. For example, you may redirect admin users to a different URL than customers after authentication. +In many cases, you may have different callback URLs for actor types. For example, you may redirect admin users to a different URL than customers after authentication. -The [Authenticate or Login API Route](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/auth/authentication-route#login-route/index.html.md) can accept a `callback_url` body parameter to override the provider's `callbackUrl` option. Learn more in [this documentation](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/auth/authentication-route#login-route/index.html.md). +The [Authenticate or Login API Route](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/auth/authentication-route#login-route/index.html.md) accepts a `callback_url` body parameter to override the provider's `callbackUrl` option. Learn more in the [Auth Flows with Routes guide](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/auth/authentication-route#login-route/index.html.md). *** ## Examples -- [How to implement third-party / social login in the storefront.](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/storefront-development/customers/third-party-login/index.html.md). +- [How to implement third-party / social login in the storefront](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/storefront-development/customers/third-party-login/index.html.md) # Google Auth Module Provider -In this document, you’ll learn about the Google Auth Module Provider and how to install and use it in the Auth Module. +In this guide, you’ll learn about the Google Auth Module Provider and how to install and use it in the Auth Module. -The Google Auth Module Provider authenticates users with their Google account. - -Learn about the authentication flow for third-party providers in [this guide](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/auth/authentication-route#2-third-party-service-authenticate-flow/index.html.md). - -*** +The Google Auth Module Provider allows you to authenticate users with their Google account. ## Register the Google Auth Module Provider @@ -24827,7 +24894,7 @@ Learn about the authentication flow for third-party providers in [this guide](ht - [Create a project in Google Cloud.](https://cloud.google.com/resource-manager/docs/creating-managing-projects) - [Create authorization credentials. When setting the Redirect Uri, set it to a URL in your frontend that later uses Medusa's callback route to validate the authentication.](https://developers.google.com/identity/protocols/oauth2/web-server#creatingcred) -Add the module to the array of providers passed to the Auth Module: +To use the Google Auth Module Provider, add the module to the array of providers passed to the Auth Module in your `medusa-config.ts`: ```ts title="medusa-config.ts" import { Modules, ContainerRegistrationKeys } from "@medusajs/framework/utils" @@ -24882,11 +24949,9 @@ GOOGLE_CALLBACK_URL= *** -*** - ## Override Callback URL During Authentication -In many cases, you may have different callback URL for actor types. For example, you may redirect admin users to a different URL than customers after authentication. +In many cases, you may have different callback URLs for actor types. For example, you may redirect admin users to a different URL than customers after authentication. The [Authenticate or Login API Route](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/auth/authentication-route#login-route/index.html.md) can accept a `callback_url` body parameter to override the provider's `callbackUrl` option. Learn more in [this documentation](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/auth/authentication-route#login-route/index.html.md). @@ -24894,7 +24959,7 @@ The [Authenticate or Login API Route](https://docs.medusajs.com/Users/shahednass ## Examples -- [How to implement Google social login in the storefront](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/storefront-development/customers/third-party-login/index.html.md). +- [How to implement Google social login in the storefront](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/storefront-development/customers/third-party-login/index.html.md) # Auth Module Provider @@ -29023,21 +29088,21 @@ The reserved quantity is associated with a location, so it has a similar relatio # Inventory Module in Medusa Flows -This document explains how the Inventory Module is used within the Medusa application's flows. +In this guide, you'll learn how Medusa uses the Inventory Module in its commerce flows, including product variant creation, adding to cart, order placement, order fulfillment, and order return. ## Product Variant Creation -When a product variant is created and its `manage_inventory` property's value is `true`, the Medusa application creates an inventory item associated with that product variant. +When a product variant is created and its `manage_inventory` property's value is `true` and the variant's `inventory_items` are set, the Medusa application creates an inventory item associated with that product variant. This flow is implemented within the [createProductVariantsWorkflow](https://docs.medusajs.com/references/medusa-workflows/createProductVariantsWorkflow/index.html.md) -![A diagram showcasing how the Inventory Module is used in the product variant creation form](https://res.cloudinary.com/dza7lstvk/image/upload/v1709661511/Medusa%20Resources/inventory-product-create_khz2hk.jpg) +![A diagram showcasing how the Inventory Module is used in the product variant creation flow](https://res.cloudinary.com/dza7lstvk/image/upload/v1709661511/Medusa%20Resources/inventory-product-create_khz2hk.jpg) *** ## Add to Cart -When a product variant with `manage_inventory` set to `true` is added to cart, the Medusa application checks whether there's sufficient stocked quantity. If not, an error is thrown and the product variant won't be added to the cart. +When a product variant with `manage_inventory` set to `true` is added to the cart, the Medusa application checks whether there's sufficient stocked quantity. If not, an error is thrown and the product variant won't be added to the cart. This flow is implemented within the [addToCartWorkflow](https://docs.medusajs.com/references/medusa-workflows/addToCartWorkflow/index.html.md) @@ -29045,13 +29110,13 @@ This flow is implemented within the [addToCartWorkflow](https://docs.medusajs.co *** -## Order Placed +## Order is Placed When an order is placed, the Medusa application creates a reservation item for each product variant with `manage_inventory` set to `true`. This flow is implemented within the [completeCartWorkflow](https://docs.medusajs.com/references/medusa-workflows/completeCartWorkflow/index.html.md) -![A diagram showcasing how the Inventory Module is used in the order placed flow](https://res.cloudinary.com/dza7lstvk/image/upload/v1709712005/Medusa%20Resources/inventory-order-placed_qdxqdn.jpg) +![A diagram showcasing how the Inventory Module is used in the order placement flow](https://res.cloudinary.com/dza7lstvk/image/upload/v1709712005/Medusa%20Resources/inventory-order-placed_qdxqdn.jpg) *** @@ -42225,6 +42290,8 @@ Connection to Redis in module 'workflow-engine-redis' established - [deleteLineItemsStep](https://docs.medusajs.com/references/medusa-workflows/steps/deleteLineItemsStep/index.html.md) - [listLineItemsStep](https://docs.medusajs.com/references/medusa-workflows/steps/listLineItemsStep/index.html.md) - [updateLineItemsStepWithSelector](https://docs.medusajs.com/references/medusa-workflows/steps/updateLineItemsStepWithSelector/index.html.md) +- [acquireLockStep](https://docs.medusajs.com/references/medusa-workflows/steps/acquireLockStep/index.html.md) +- [releaseLockStep](https://docs.medusajs.com/references/medusa-workflows/steps/releaseLockStep/index.html.md) - [notifyOnFailureStep](https://docs.medusajs.com/references/medusa-workflows/steps/notifyOnFailureStep/index.html.md) - [sendNotificationsStep](https://docs.medusajs.com/references/medusa-workflows/steps/sendNotificationsStep/index.html.md) - [addOrderTransactionStep](https://docs.medusajs.com/references/medusa-workflows/steps/addOrderTransactionStep/index.html.md) @@ -43959,11 +44026,11 @@ If you want a separate build to host the admin as a standalone application, such # db Commands - Medusa CLI Reference -Commands starting with `db:` perform actions on the database. +Commands in the Medusa CLI starting with `db:` perform actions on the database. ## db:setup -Creates a database for the Medusa application with the specified name, if it doesn't exit. Then, it runs migrations and syncs links. +Creates a database for the Medusa application with the specified name, if it doesn't exist. Then, it runs migrations and syncs links. It also updates your `.env` file with the database name. @@ -43987,7 +44054,7 @@ Use this command if you're setting up a Medusa project or database manually. ## db:create -Creates a database for the Medusa application with the specified name, if it doesn't exit. +Creates a database for the Medusa application with the specified name, if it doesn't exist. It also updates your `.env` file with the database name. @@ -44018,7 +44085,7 @@ npx medusa db:generate |Argument|Description|Required| |---|---|---|---|---| -|\`module\_names\`|The name of one or more module (separated by spaces) to generate migrations for. For example, |Yes| +|\`module\_names\`|The name of one or more modules (separated by spaces) to generate migrations for. For example, |Yes| *** @@ -44047,7 +44114,7 @@ Use this command if you've updated the Medusa packages, or you've created custom ## db:rollback -Revert the last migrations ran on one or more modules. +Revert the last migrations run on one or more modules. ```bash npx medusa db:rollback @@ -44057,7 +44124,7 @@ npx medusa db:rollback |Argument|Description|Required| |---|---|---|---|---| -|\`module\_names\`|The name of one or more module (separated by spaces) to rollback their migrations for. For example, |Yes| +|\`module\_names\`|The name of one or more modules (separated by spaces) to rollback their migrations for. For example, |Yes| *** @@ -44097,7 +44164,7 @@ npx medusa develop # exec Command - Medusa CLI Reference -Run a custom CLI script. Learn more about it in [this guide](https://docs.medusajs.com/docs/learn/fundamentals/custom-cli-scripts/index.html.md). +Run a custom CLI script using Medusa's CLI tool. Learn more about it in [Custom CLI Scripts guide](https://docs.medusajs.com/docs/learn/fundamentals/custom-cli-scripts/index.html.md). ```bash npx medusa exec [file] [args...] @@ -44107,7 +44174,7 @@ npx medusa exec [file] [args...] |Argument|Description|Required| |---|---|---|---|---| -|\`file\`|The path to the TypeScript or JavaScript file holding the function to execute.|Yes| +|\`file\`|The path to the TypeScript or JavaScript file containing the function to execute.|Yes| |\`args\`|A list of arguments to pass to the function. These arguments are passed in the |No| @@ -44142,7 +44209,7 @@ medusa new [ []] # plugin Commands - Medusa CLI Reference -Commands starting with `plugin:` perform actions related to [plugin](https://docs.medusajs.com/docs/learn/fundamentals/plugins/index.html.md) development. +Commands in the Medusa CLI starting with `plugin:` perform actions related to [plugin development](https://docs.medusajs.com/docs/learn/fundamentals/plugins/index.html.md). These commands are available starting from [Medusa v2.3.0](https://github.com/medusajs/medusa/releases/tag/v2.3.0). @@ -44194,7 +44261,7 @@ npx medusa plugin:db:generate ## plugin:build -Build a plugin before publishing it to NPM. The command will compile an output in the `.medusa/server` directory. +Build a plugin before publishing it to NPM. The command will compile the output in the `.medusa/server` directory. ```bash npx medusa plugin:build @@ -44220,7 +44287,7 @@ npx medusa start # telemetry Command - Medusa CLI Reference -Enable or disable the collection of anonymous data usage. If no option is provided, the command enables the collection of anonymous data usage. +Enable or disable the collection of anonymous usage data. If no option is provided, the command enables the collection of anonymous usage data. ```bash npx medusa telemetry @@ -44326,11 +44393,11 @@ If you want a separate build to host the admin as a standalone application, such # db Commands - Medusa CLI Reference -Commands starting with `db:` perform actions on the database. +Commands in the Medusa CLI starting with `db:` perform actions on the database. ## db:setup -Creates a database for the Medusa application with the specified name, if it doesn't exit. Then, it runs migrations and syncs links. +Creates a database for the Medusa application with the specified name, if it doesn't exist. Then, it runs migrations and syncs links. It also updates your `.env` file with the database name. @@ -44354,7 +44421,7 @@ Use this command if you're setting up a Medusa project or database manually. ## db:create -Creates a database for the Medusa application with the specified name, if it doesn't exit. +Creates a database for the Medusa application with the specified name, if it doesn't exist. It also updates your `.env` file with the database name. @@ -44385,7 +44452,7 @@ npx medusa db:generate |Argument|Description|Required| |---|---|---|---|---| -|\`module\_names\`|The name of one or more module (separated by spaces) to generate migrations for. For example, |Yes| +|\`module\_names\`|The name of one or more modules (separated by spaces) to generate migrations for. For example, |Yes| *** @@ -44414,7 +44481,7 @@ Use this command if you've updated the Medusa packages, or you've created custom ## db:rollback -Revert the last migrations ran on one or more modules. +Revert the last migrations run on one or more modules. ```bash npx medusa db:rollback @@ -44424,7 +44491,7 @@ npx medusa db:rollback |Argument|Description|Required| |---|---|---|---|---| -|\`module\_names\`|The name of one or more module (separated by spaces) to rollback their migrations for. For example, |Yes| +|\`module\_names\`|The name of one or more modules (separated by spaces) to rollback their migrations for. For example, |Yes| *** @@ -44464,7 +44531,7 @@ npx medusa develop # exec Command - Medusa CLI Reference -Run a custom CLI script. Learn more about it in [this guide](https://docs.medusajs.com/docs/learn/fundamentals/custom-cli-scripts/index.html.md). +Run a custom CLI script using Medusa's CLI tool. Learn more about it in [Custom CLI Scripts guide](https://docs.medusajs.com/docs/learn/fundamentals/custom-cli-scripts/index.html.md). ```bash npx medusa exec [file] [args...] @@ -44474,7 +44541,7 @@ npx medusa exec [file] [args...] |Argument|Description|Required| |---|---|---|---|---| -|\`file\`|The path to the TypeScript or JavaScript file holding the function to execute.|Yes| +|\`file\`|The path to the TypeScript or JavaScript file containing the function to execute.|Yes| |\`args\`|A list of arguments to pass to the function. These arguments are passed in the |No| @@ -44509,7 +44576,7 @@ medusa new [ []] # plugin Commands - Medusa CLI Reference -Commands starting with `plugin:` perform actions related to [plugin](https://docs.medusajs.com/docs/learn/fundamentals/plugins/index.html.md) development. +Commands in the Medusa CLI starting with `plugin:` perform actions related to [plugin development](https://docs.medusajs.com/docs/learn/fundamentals/plugins/index.html.md). These commands are available starting from [Medusa v2.3.0](https://github.com/medusajs/medusa/releases/tag/v2.3.0). @@ -44561,7 +44628,7 @@ npx medusa plugin:db:generate ## plugin:build -Build a plugin before publishing it to NPM. The command will compile an output in the `.medusa/server` directory. +Build a plugin before publishing it to NPM. The command will compile the output in the `.medusa/server` directory. ```bash npx medusa plugin:build @@ -44587,7 +44654,7 @@ npx medusa start # telemetry Command - Medusa CLI Reference -Enable or disable the collection of anonymous data usage. If no option is provided, the command enables the collection of anonymous data usage. +Enable or disable the collection of anonymous usage data. If no option is provided, the command enables the collection of anonymous usage data. ```bash npx medusa telemetry @@ -65714,9 +65781,9 @@ You also pass the product builder record to the compensation function, which del The `prepareProductBuilderCustomFieldsStep` receives the custom fields from the workflow's input and returns which custom fields should be created, updated, or deleted. -To create the step, create the file `src/workflows/upsert-product-builder.ts` with the following content: +To create the step, create the file `src/workflows/steps/prepare-product-builder-custom-fields.ts` with the following content: -```ts title="src/workflows/upsert-product-builder.ts" highlights={prepareCustomFieldsStepHighlights} +```ts title="src/workflows/steps/prepare-product-builder-custom-fields.ts" highlights={prepareCustomFieldsStepHighlights} import { createStep, StepResponse } from "@medusajs/framework/workflows-sdk" import { PRODUCT_BUILDER_MODULE } from "../../modules/product-builder" @@ -65760,7 +65827,7 @@ Next, you need to check which custom fields should be created, updated, or delet Replace the `TODO` with the following: -```ts title="src/workflows/upsert-product-builder.ts" highlights={prepareCustomFieldsStepHighlights2} +```ts title="src/workflows/steps/prepare-product-builder-custom-fields.ts" highlights={prepareCustomFieldsStepHighlights2} // Process input fields to determine creates vs updates input.custom_fields?.forEach((fieldData) => { const existingField = existingCustomFields.find((f) => f.id === fieldData.id) @@ -66529,6 +66596,8 @@ when({ .then(() => { dismissRemoteLinkStep(deletedComplementaryProductLinks) }) + +// TODO manage addon products ``` In this portion of the workflow, you: @@ -92587,6 +92656,14 @@ To learn more about the commerce features that Medusa provides, check out Medusa - [me](https://docs.medusajs.com/references/js_sdk/admin/User/methods/js_sdk.admin.User.me/index.html.md) - [retrieve](https://docs.medusajs.com/references/js_sdk/admin/User/methods/js_sdk.admin.User.retrieve/index.html.md) - [update](https://docs.medusajs.com/references/js_sdk/admin/User/methods/js_sdk.admin.User.update/index.html.md) +- [columns](https://docs.medusajs.com/references/js_sdk/admin/Views/methods/js_sdk.admin.Views.columns/index.html.md) +- [createConfiguration](https://docs.medusajs.com/references/js_sdk/admin/Views/methods/js_sdk.admin.Views.createConfiguration/index.html.md) +- [deleteConfiguration](https://docs.medusajs.com/references/js_sdk/admin/Views/methods/js_sdk.admin.Views.deleteConfiguration/index.html.md) +- [listConfigurations](https://docs.medusajs.com/references/js_sdk/admin/Views/methods/js_sdk.admin.Views.listConfigurations/index.html.md) +- [retrieveActiveConfiguration](https://docs.medusajs.com/references/js_sdk/admin/Views/methods/js_sdk.admin.Views.retrieveActiveConfiguration/index.html.md) +- [retrieveConfiguration](https://docs.medusajs.com/references/js_sdk/admin/Views/methods/js_sdk.admin.Views.retrieveConfiguration/index.html.md) +- [setActiveConfiguration](https://docs.medusajs.com/references/js_sdk/admin/Views/methods/js_sdk.admin.Views.setActiveConfiguration/index.html.md) +- [updateConfiguration](https://docs.medusajs.com/references/js_sdk/admin/Views/methods/js_sdk.admin.Views.updateConfiguration/index.html.md) - [list](https://docs.medusajs.com/references/js_sdk/admin/WorkflowExecution/methods/js_sdk.admin.WorkflowExecution.list/index.html.md) - [retrieve](https://docs.medusajs.com/references/js_sdk/admin/WorkflowExecution/methods/js_sdk.admin.WorkflowExecution.retrieve/index.html.md) diff --git a/www/apps/resources/app/how-to-tutorials/tutorials/product-builder/page.mdx b/www/apps/resources/app/how-to-tutorials/tutorials/product-builder/page.mdx index 37669d225b..7b369c4c57 100644 --- a/www/apps/resources/app/how-to-tutorials/tutorials/product-builder/page.mdx +++ b/www/apps/resources/app/how-to-tutorials/tutorials/product-builder/page.mdx @@ -764,7 +764,7 @@ You also pass the product builder record to the compensation function, which del The `prepareProductBuilderCustomFieldsStep` receives the custom fields from the workflow's input and returns which custom fields should be created, updated, or deleted. -To create the step, create the file `src/workflows/upsert-product-builder.ts` with the following content: +To create the step, create the file `src/workflows/steps/prepare-product-builder-custom-fields.ts` with the following content: export const prepareCustomFieldsStepHighlights = [ ["21", "listProductBuilderCustomFields", "Get existing custom fields."], @@ -772,7 +772,7 @@ export const prepareCustomFieldsStepHighlights = [ ["27", "toUpdate", "Custom fields to update."] ] -```ts title="src/workflows/upsert-product-builder.ts" highlights={prepareCustomFieldsStepHighlights} +```ts title="src/workflows/steps/prepare-product-builder-custom-fields.ts" highlights={prepareCustomFieldsStepHighlights} import { createStep, StepResponse } from "@medusajs/framework/workflows-sdk" import { PRODUCT_BUILDER_MODULE } from "../../modules/product-builder" @@ -822,7 +822,7 @@ export const prepareCustomFieldsStepHighlights2 = [ ["26", "toDelete", "Add the custom field to this array if it exists but isn't in the input."] ] -```ts title="src/workflows/upsert-product-builder.ts" highlights={prepareCustomFieldsStepHighlights2} +```ts title="src/workflows/steps/prepare-product-builder-custom-fields.ts" highlights={prepareCustomFieldsStepHighlights2} // Process input fields to determine creates vs updates input.custom_fields?.forEach((fieldData) => { const existingField = existingCustomFields.find((f) => f.id === fieldData.id) @@ -1671,6 +1671,8 @@ when({ .then(() => { dismissRemoteLinkStep(deletedComplementaryProductLinks) }) + +// TODO manage addon products ``` In this portion of the workflow, you: diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index ddc5fec60a..1b3104adff 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -6564,7 +6564,7 @@ export const generatedEditDates = { "app/commerce-modules/order/order-totals/page.mdx": "2025-07-31T15:12:10.633Z", "app/commerce-modules/user/invite-user-subscriber/page.mdx": "2025-08-01T12:01:54.551Z", "app/how-to-tutorials/tutorials/invoice-generator/page.mdx": "2025-08-04T00:00:00.000Z", - "app/how-to-tutorials/tutorials/product-builder/page.mdx": "2025-09-01T14:59:43.128Z", + "app/how-to-tutorials/tutorials/product-builder/page.mdx": "2025-09-15T10:44:37.801Z", "app/integrations/guides/payload/page.mdx": "2025-09-08T15:06:32.588Z", "references/js_sdk/admin/Client/methods/js_sdk.admin.Client.getToken/page.mdx": "2025-08-14T12:59:55.678Z", "app/commerce-modules/order/draft-orders/page.mdx": "2025-08-26T09:21:49.780Z",