From c3f9b97062c8e7e7faea2c77671a5c308bdd356e Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Wed, 25 Dec 2024 12:54:20 +0200 Subject: [PATCH 01/21] revise API Key Module overview --- .../api-key/examples/page.mdx | 306 ------------------ .../app/commerce-modules/api-key/page.mdx | 230 +++++++------ .../CommerceModuleSections/index.tsx | 78 +++++ .../components/MDXComponents/index.tsx | 2 + www/apps/resources/generated/edit-dates.mjs | 3 +- www/apps/resources/generated/files-map.mjs | 4 - www/apps/resources/generated/sidebar.mjs | 111 ++++++- www/apps/resources/sidebars/api-key.mjs | 34 +- .../build-scripts/src/generate-sidebar.ts | 20 +- .../build-scripts/src/utils/parse-tags.ts | 7 +- .../src/components/ChildDocs/index.tsx | 193 +---------- .../src/components/MDXComponents/index.tsx | 2 + www/packages/docs-ui/src/hooks/index.ts | 1 + .../src/hooks/use-child-docs/index.tsx | 216 +++++++++++++ www/packages/tags/src/tags/index.ts | 22 +- 15 files changed, 583 insertions(+), 646 deletions(-) delete mode 100644 www/apps/resources/app/commerce-modules/api-key/examples/page.mdx create mode 100644 www/apps/resources/components/CommerceModuleSections/index.tsx create mode 100644 www/packages/docs-ui/src/hooks/use-child-docs/index.tsx diff --git a/www/apps/resources/app/commerce-modules/api-key/examples/page.mdx b/www/apps/resources/app/commerce-modules/api-key/examples/page.mdx deleted file mode 100644 index 141a434e47229..0000000000000 --- a/www/apps/resources/app/commerce-modules/api-key/examples/page.mdx +++ /dev/null @@ -1,306 +0,0 @@ -import { CodeTabs, CodeTab } from "docs-ui" - -export const metadata = { - title: `Examples of the API Key Module`, -} - -# {metadata.title} - -In this guide, you’ll find common examples of how you can use the API Key Module in your application. - - - -You should only use the API Key Module's main service when implementing complex customizations. For common cases, check out [available workflows instead](../../../medusa-workflows-reference/page.mdx). - - - -## Create an API Key - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST(request: MedusaRequest, res: MedusaResponse) { - const apiKeyModuleService = request.scope.resolve( - Modules.API_KEY - ) - - const apiKey = await apiKeyModuleService.createApiKeys({ - title: "Publishable API key", - type: "publishable", - created_by: "user_123", - }) - - res.json({ - api_key: apiKey, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeApiKeyModule } from "@medusajs/medusa/api-key" - -export async function POST(request: Request) { - const apiKeyModuleService = await initializeApiKeyModule() - - const apiKey = await apiKeyModuleService.createApiKeys({ - title: "Publishable API key", - type: "publishable", - created_by: "user_123", - }) - - return NextResponse.json({ - api_key: apiKey, - }) -} -``` - - - - ---- - -## List API Keys - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET(request: MedusaRequest, res: MedusaResponse) { - const apiKeyModuleService = request.scope.resolve( - Modules.API_KEY - ) - - res.json({ - api_keys: await apiKeyModuleService.listApiKeys(), - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeApiKeyModule } from "@medusajs/medusa/api-key" - -export async function GET(request: Request) { - const apiKeyModuleService = await initializeApiKeyModule() - - return NextResponse.json({ - api_keys: await apiKeyModuleService.listApiKeys(), - }) -} -``` - - - - ---- - -## Revoke an API Key - - - - -```ts collapsibleLines="1-9" expandButtonLabel="Show Imports" -import { AuthenticatedMedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - request: AuthenticatedMedusaRequest, - res: MedusaResponse -) { - const apiKeyModuleService = request.scope.resolve( - Modules.API_KEY - ) - - const revokedKey = await apiKeyModuleService.revoke(request.params.id, { - revoked_by: request.auth_context.actor_id, - }) - - res.json({ - api_key: revokedKey, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeApiKeyModule } from "@medusajs/medusa/api-key" - -type ContextType = { - params: { - id: string - user_id: string - } -} - -export async function POST(request: Request, { params }: ContextType) { - const apiKeyModuleService = await initializeApiKeyModule() - - const revokedKey = await apiKeyModuleService.revoke(params.id, { - revoked_by: params.user_id, - }) - - return NextResponse.json({ - api_key: revokedKey, - }) -} -``` - - - - ---- - -## Verify or Authenticate Token - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST(request: MedusaRequest, res: MedusaResponse) { - const apiKeyModuleService = request.scope.resolve( - Modules.API_KEY - ) - - const authenticatedToken = await apiKeyModuleService.authenticate( - request.params.token - ) - - res.json({ - is_authenticated: !!authenticatedToken, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeApiKeyModule } from "@medusajs/medusa/api-key" - -type ContextType = { - params: { - token: string - } -} - -export async function POST(request: Request, { params }: ContextType) { - const apiKeyModuleService = await initializeApiKeyModule() - - const authenticatedToken = await apiKeyModuleService.authenticate( - request.params.token - ) - - return NextResponse.json({ - is_authenticated: !!authenticatedToken, - }) -} -``` - - - - ---- - -## Roll API Key - - - - -```ts collapsibleLines="1-8" expandButtonLabel="Show Imports" -import { - AuthenticatedMedusaRequest, - MedusaResponse, -} from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - request: AuthenticatedMedusaRequest, - res: MedusaResponse -) { - const apiKeyModuleService = request.scope.resolve( - Modules.API_KEY - ) - - const revokedKey = await apiKeyModuleService.revoke(request.params.id, { - revoked_by: request.auth_context.actor_id, - }) - - const newKey = await apiKeyModuleService.createApiKeys({ - title: revokedKey.title, - type: revokedKey.type, - created_by: revokedKey.created_by, - }) - - res.json({ - api_key: newKey, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeApiKeyModule } from "@medusajs/medusa/api-key" - -type ContextType = { - params: { - id: string - user_id: string - } -} - -export async function POST(request: Request, { params }: ContextType) { - const apiKeyModuleService = await initializeApiKeyModule() - - const revokedKey = await apiKeyModuleService.revoke(params.id, { - revoked_by: params.user_id, - }) - - const newKey = await apiKeyModuleService.createApiKeys({ - title: revokedKey.title, - type: revokedKey.type, - created_by: revokedKey.created_by, - }) - - return NextResponse.json({ - api_key: newKey, - }) -} -``` - - - - ---- - -## More Examples - -The [API Key Module's main service reference](/references/api-key) provides a reference to all the methods available for use with examples for each. diff --git a/www/apps/resources/app/commerce-modules/api-key/page.mdx b/www/apps/resources/app/commerce-modules/api-key/page.mdx index d6166d736d749..140a7d6398918 100644 --- a/www/apps/resources/app/commerce-modules/api-key/page.mdx +++ b/www/apps/resources/app/commerce-modules/api-key/page.mdx @@ -1,4 +1,4 @@ -import { CodeTabs, CodeTab } from "docs-ui" +import { CodeTabs, CodeTab, ChildDocs } from "docs-ui" export const metadata = { title: `API Key Module`, @@ -6,132 +6,148 @@ export const metadata = { # {metadata.title} -The API Key Module provides API-key-related features in your Medusa and Node.js applications. +In this section of the documentation, you will find resources to learn more about the API Key Module and how to use it in your application. -## How to Use API Key Module's Service +Medusa has API-key related features available out-of-the-box through the API Key Module. A [module](!docs!/learn/fundamentals/modules) is a standalone package that provides features for a single domain. Each of Medusa's commerce features are placed in commerce modules, such as this API Key Module. -Use the API Key Module's main service by resolving from the Medusa container the resource `Modules.API_KEY`. + -For example: - - - - -```ts title="src/workflows/hello-world/step1.ts" -import { createStep } from "@medusajs/framework/workflows-sdk" -import { Modules } from "@medusajs/framework/utils" - -const step1 = createStep("step-1", async (_, { container }) => { - const apiKeyModuleService = container.resolve( - Modules.API_KEY - ) - - const apiKeys = await apiKeyModuleService.listApiKeys() -}) -``` - - - - -```ts title="src/api/store/custom/route.ts" -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const apiKeyModuleService = request.scope.resolve( - Modules.API_KEY - ) - - res.json({ - api_keys: await apiKeyModuleService.listApiKeys(), - }) -} -``` - - - - -```ts title="src/subscribers/custom-handler.ts" -import { SubscriberArgs } from "@medusajs/framework" -import { Modules } from "@medusajs/framework/utils" +Learn more about why modules are isolated in [this documentation](!docs!/learn/fundamentals/modules/isolation). -export default async function subscriberHandler({ container }: SubscriberArgs) { - const apiKeyModuleService = container.resolve( - Modules.API_KEY - ) + - const apiKeys = await apiKeyModuleService.listApiKeys() -} -``` +## API Key Features - - +- [API Key Types and Management](./concepts/page.mdx): Manage API keys in your store. You can create both publishable and secret API keys for different use cases. +- [Token Verification](./concepts/page.mdx#token-verification): Verify tokens of secret API keys to authenticate users or actions. +- [Revoke Keys](./concepts/page.mdx#api-key-expiration): Revoke keys to disable their use permanently. +- Roll API Keys: Roll API keys by [revoking](/references/api-key/revoke) a key then [re-creating it](/references/api-key/createApiKeys). --- -## Features - -### API Key Types and Management +## How to Use the API Key Module -Manage API keys in your store. You can create both publishable and secret API keys for different use cases, such as: +In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. -- Publishable API Key associated with resources like sales channels. -- Authentication token for admin users to access Admin API Routes. -- Password reset tokens when a user or customer requests to reset their password. +You can build custom workflows and steps. You can also re-use Medusa's workflows and steps, which are provided by the `@medusajs/medusa/core-flows` package. -```ts -const pubApiKey = await apiKeyModuleService.createApiKeys({ - title: "Publishable API key", - type: "publishable", - created_by: "user_123", -}) - -const secretApiKey = await apiKeyModuleService.createApiKeys({ - title: "Authentication Key", - type: "secret", - created_by: "user_123", -}) -``` - -### Token Verification +For example: -Verify tokens of secret API keys to authenticate users or actions, such as verifying a password reset token. +```ts title="src/workflows/create-api-key.ts" +import { + createWorkflow, + WorkflowResponse, + createStep, + StepResponse, +} from "@medusajs/framework/workflows-sdk" +import { Modules } from "@medusajs/framework/utils" -```ts -const authenticatedToken = await apiKeyModuleService.authenticate("sk_123") -if (!authenticatedToken) { - console.error("Couldn't verify token") -} else { - console.log("Token verified successfully!") -} +const createApiKeyStep = createStep( + "create-api-key", + async ({}, { container }) => { + const apiKeyModuleService = container.resolve(Modules.API_KEY) + + const apiKey = await apiKeyModuleService.createApiKeys({ + title: "Publishable API key", + type: "publishable", + created_by: "user_123", + }) + + return new StepResponse({ apiKey }, apiKey.id) + }, + async (apiKeyId, { container }) => { + const apiKeyModuleService = container.resolve(Modules.API_KEY) + + await apiKeyModuleService.deleteApiKeys([apiKeyId]) + } +) + +export const createApiKeyWorkflow = createWorkflow( + "create-api-key", + () => { + const apiKey = createApiKeyStep() + + return new WorkflowResponse({ + apiKey, + }) + } +) ``` -### Revoke Keys +You can then execute the workflow in your cusotm API routes, scheduled jobs, or subscribers: -Revoke keys to disable their use permenantly. + + + + ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import type { + MedusaRequest, + MedusaResponse, + } from "@medusajs/framework/http" + import myWorkflow from "../../workflows/create-api-key" + + export async function GET( + req: MedusaRequest, + res: MedusaResponse + ) { + const { result } = await createApiKeyWorkflow(req.scope) + .run() + + res.send(result) + } + ``` -```ts -const revokedKey = await apiKeyModuleService.revoke("apk_1", { - revoked_by: "user_123", -}) -``` + + + + ```ts title="src/subscribers/customer-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import { + type SubscriberConfig, + type SubscriberArgs, + } from "@medusajs/framework" + import createApiKeyWorkflow from "../workflows/create-api-key" + + export default async function handleCustomerCreate({ + event: { data }, + container, + }: SubscriberArgs<{ id: string }>) { + const { result } = await createApiKeyWorkflow(container) + .run() + + console.log(result) + } + + export const config: SubscriberConfig = { + event: "user.created", + } + ``` -### Roll API Keys + + + + ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} + import { MedusaContainer } from "@medusajs/framework/types" + import createApiKeyWorkflow from "../workflows/create-api-key" + + export default async function myCustomJob( + container: MedusaContainer + ) { + const { result } = await createApiKeyWorkflow(container) + .run() + + console.log(result.message) + } + + export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, + }; + ``` -Roll API keys by revoking a key then re-creating it. + + -```ts -const revokedKey = await apiKeyModuleService.revoke("apk_1", { - revoked_by: "user_123", -}) +--- -const newKey = await apiKeyModuleService.createApiKeys({ - title: revokedKey.title, - type: revokedKey.type, - created_by: revokedKey.created_by, -}) -``` + \ No newline at end of file diff --git a/www/apps/resources/components/CommerceModuleSections/index.tsx b/www/apps/resources/components/CommerceModuleSections/index.tsx new file mode 100644 index 0000000000000..6ce07aacd1254 --- /dev/null +++ b/www/apps/resources/components/CommerceModuleSections/index.tsx @@ -0,0 +1,78 @@ +"use client" + +import { H2, Hr, useChildDocs } from "docs-ui" +import React from "react" + +type CommerceModuleSectionsProps = { + name: string +} + +export const CommerceModuleSections = ({ + name, +}: CommerceModuleSectionsProps) => { + const components: (JSX.Element | JSX.Element[])[] = [] + const { component: workflowsComponent } = useChildDocs({ + showItems: ["Workflows"], + titleLevel: 3, + }) + const { component: stepsComponent } = useChildDocs({ + showItems: ["Steps"], + titleLevel: 3, + }) + const { items: serverGuideItems, component: serverGuidesComponent } = + useChildDocs({ + showItems: ["Server Guides"], + }) + if (serverGuideItems?.default.length) { + components.push(serverGuidesComponent) + } + const { items: storefrontGuideItems, component: storefrontGuidesComponent } = + useChildDocs({ + showItems: ["Storefront Guides"], + }) + if (storefrontGuideItems?.default.length) { + components.push(storefrontGuidesComponent) + } + const { items: adminGuideItems, component: adminGuidesComponent } = + useChildDocs({ + showItems: ["Admin Guides"], + }) + if (adminGuideItems?.default.length) { + components.push(adminGuidesComponent) + } + const { items: userGuideItems, component: userGuidesComponent } = + useChildDocs({ + showItems: ["User Guides"], + }) + if (userGuideItems?.default.length) { + components.push(userGuidesComponent) + } + const { items: referenceItems, component: referencesComponent } = + useChildDocs({ + showItems: ["References"], + }) + if (referenceItems?.default.length) { + components.push(referencesComponent) + } + + return ( + <> +

Medusa Workflows and Steps

+

+ Medusa provides the following workflows and steps that use the {name}{" "} + Module. You can use these workflows and steps in your customizations: +

+ {workflowsComponent} + {stepsComponent} + + {components.map((component, i) => ( + + <> +
+ {component} + +
+ ))} + + ) +} diff --git a/www/apps/resources/components/MDXComponents/index.tsx b/www/apps/resources/components/MDXComponents/index.tsx index 03d07a1cc69db..2da3e8888189c 100644 --- a/www/apps/resources/components/MDXComponents/index.tsx +++ b/www/apps/resources/components/MDXComponents/index.tsx @@ -5,12 +5,14 @@ import { TypeList, WorkflowDiagram, } from "docs-ui" +import { CommerceModuleSections } from "../CommerceModuleSections" const MDXComponents: MDXComponentsType = { ...UiMdxComponents, a: Link, TypeList, WorkflowDiagram, + CommerceModuleSections, } export default MDXComponents diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index fa08c24c1c7dd..70cf5cfadd9b0 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -209,11 +209,10 @@ export const generatedEditDates = { "app/commerce-modules/auth/auth-flows/page.mdx": "2024-09-05T08:50:11.671Z", "app/commerce-modules/auth/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/auth/auth-identity-and-actor-types/page.mdx": "2024-12-09T13:04:01.129Z", - "app/commerce-modules/api-key/page.mdx": "2024-12-09T14:47:01.509Z", + "app/commerce-modules/api-key/page.mdx": "2024-12-25T09:22:23.514Z", "app/commerce-modules/auth/create-actor-type/page.mdx": "2024-12-09T15:32:07.594Z", "app/architectural-modules/page.mdx": "2024-12-11T10:33:53.064Z", "app/architectural-modules/workflow-engine/redis/page.mdx": "2024-10-15T12:50:59.507Z", - "app/commerce-modules/api-key/examples/page.mdx": "2024-10-15T14:58:58.994Z", "app/architectural-modules/notification/sendgrid/page.mdx": "2024-10-15T12:51:25.569Z", "app/commerce-modules/api-key/concepts/page.mdx": "2024-10-07T13:59:37.529Z", "app/architectural-modules/workflow-engine/page.mdx": "2024-05-28T13:25:03+03:00", diff --git a/www/apps/resources/generated/files-map.mjs b/www/apps/resources/generated/files-map.mjs index 840f7219eb4db..588d28735eb24 100644 --- a/www/apps/resources/generated/files-map.mjs +++ b/www/apps/resources/generated/files-map.mjs @@ -127,10 +127,6 @@ export const filesMap = [ "filePath": "/www/apps/resources/app/commerce-modules/api-key/concepts/page.mdx", "pathname": "/commerce-modules/api-key/concepts" }, - { - "filePath": "/www/apps/resources/app/commerce-modules/api-key/examples/page.mdx", - "pathname": "/commerce-modules/api-key/examples" - }, { "filePath": "/www/apps/resources/app/commerce-modules/api-key/links-to-other-modules/page.mdx", "pathname": "/commerce-modules/api-key/links-to-other-modules" diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs index 1c6b6b6a9d27a..5d87f58cbb6a7 100644 --- a/www/apps/resources/generated/sidebar.mjs +++ b/www/apps/resources/generated/sidebar.mjs @@ -194,15 +194,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "link", - "path": "/commerce-modules/api-key/examples", - "title": "Examples", - "children": [] - }, - { - "loaded": true, - "isPathHref": true, - "type": "sub-category", + "type": "category", "title": "Concepts", "children": [ { @@ -226,7 +218,106 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", + "title": "Storefront Guides", + "autogenerate_tags": "storefront+apiKey", + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "Use a Publishable API Key in the Storefront", + "path": "/app/storefront-development/publishable-api-keys", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Workflows", + "autogenerate_tags": "workflow+apiKey", + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "createApiKeysWorkflow", + "path": "/references/medusa-workflows/createApiKeysWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "deleteApiKeysWorkflow", + "path": "/references/medusa-workflows/deleteApiKeysWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "revokeApiKeysWorkflow", + "path": "/references/medusa-workflows/revokeApiKeysWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "updateApiKeysWorkflow", + "path": "/references/medusa-workflows/updateApiKeysWorkflow", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Steps", + "autogenerate_tags": "step+apiKey", + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "createApiKeysStep", + "path": "/references/medusa-workflows/steps/createApiKeysStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "deleteApiKeysStep", + "path": "/references/medusa-workflows/steps/deleteApiKeysStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "revokeApiKeysStep", + "path": "/references/medusa-workflows/steps/revokeApiKeysStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "updateApiKeysStep", + "path": "/references/medusa-workflows/steps/updateApiKeysStep", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", "title": "References", "children": [ { diff --git a/www/apps/resources/sidebars/api-key.mjs b/www/apps/resources/sidebars/api-key.mjs index aeffd5387cd81..9b23a277414ba 100644 --- a/www/apps/resources/sidebars/api-key.mjs +++ b/www/apps/resources/sidebars/api-key.mjs @@ -11,12 +11,7 @@ export const apiKeySidebar = [ title: "Overview", }, { - type: "link", - path: "/commerce-modules/api-key/examples", - title: "Examples", - }, - { - type: "sub-category", + type: "category", title: "Concepts", children: [ { @@ -32,7 +27,32 @@ export const apiKeySidebar = [ ], }, { - type: "sub-category", + type: "category", + title: "Storefront Guides", + autogenerate_tags: "storefront+apiKey", + }, + { + type: "category", + title: "Admin Guides", + autogenerate_tags: "admin+apiKey", + }, + { + type: "category", + title: "User Guides", + autogenerate_tags: "userGuide+apiKey", + }, + { + type: "category", + title: "Workflows", + autogenerate_tags: "workflow+apiKey", + }, + { + type: "category", + title: "Steps", + autogenerate_tags: "step+apiKey", + }, + { + type: "category", title: "References", children: [ { diff --git a/www/packages/build-scripts/src/generate-sidebar.ts b/www/packages/build-scripts/src/generate-sidebar.ts index 35ff3379c4dc5..b7f924a3e5f8a 100644 --- a/www/packages/build-scripts/src/generate-sidebar.ts +++ b/www/packages/build-scripts/src/generate-sidebar.ts @@ -138,21 +138,29 @@ async function checkItem(item: RawSidebarItem): Promise { ) { item.children = await customGenerators[item.custom_autogenerate]() } else if (item.children) { - item.children = await Promise.all( - item.children.map(async (childItem) => await checkItem(childItem)) - ) + item.children = await checkItems(item.children) } return item } +async function checkItems(items: RawSidebarItem[]): Promise { + return ( + await Promise.all(items.map(async (item) => await checkItem(item))) + ).filter((item) => { + if (item.type !== "category" && item.type !== "sub-category") { + return true + } + + return (item.children?.length || 0) > 0 + }) +} + export async function generateSidebar(sidebar: RawSidebarItem[]) { const path = await import("path") const { writeFileSync } = await import("fs") - const normalizedSidebar = await Promise.all( - sidebar.map(async (item) => await checkItem(item)) - ) + const normalizedSidebar = await checkItems(sidebar) const generatedDirPath = path.resolve("generated") diff --git a/www/packages/build-scripts/src/utils/parse-tags.ts b/www/packages/build-scripts/src/utils/parse-tags.ts index ba4ac77874bed..710ff825edca9 100644 --- a/www/packages/build-scripts/src/utils/parse-tags.ts +++ b/www/packages/build-scripts/src/utils/parse-tags.ts @@ -27,14 +27,11 @@ const getIntersectionTags = (tags: string): Tag => { .map((tagName) => getTagItems(tagName)) .filter((tag) => tag !== undefined) as Tag[] - if (!tagsToIntersect.length) { + if (tagsToIntersect.length < 2) { + // if there are less than 2 tags to intersect, return an empty array return [] } - if (tagsToIntersect.length === 1) { - return tagsToIntersect[0] - } - return tagsToIntersect[0].filter((tagItem) => { return tagsToIntersect .slice(1) diff --git a/www/packages/docs-ui/src/components/ChildDocs/index.tsx b/www/packages/docs-ui/src/components/ChildDocs/index.tsx index 9e3e23563f7cb..724c3748ed381 100644 --- a/www/packages/docs-ui/src/components/ChildDocs/index.tsx +++ b/www/packages/docs-ui/src/components/ChildDocs/index.tsx @@ -1,193 +1,10 @@ "use client" -import React, { useMemo } from "react" -import { Card, CardList, H2, useSidebar } from "../.." -import { InteractiveSidebarItem, SidebarItem, SidebarItemLink } from "types" -import slugify from "slugify" -import { MDXComponents } from "../.." +import React from "react" +import { useChildDocs, UseChildDocsProps } from "../.." -const Hr = MDXComponents["hr"] as () => React.JSX.Element +export const ChildDocs = (props: UseChildDocsProps) => { + const { component } = useChildDocs(props) -type ChildDocsProps = { - onlyTopLevel?: boolean - type?: "sidebar" | "item" - hideItems?: string[] - showItems?: string[] - hideTitle?: boolean - childLevel?: number -} - -export const ChildDocs = ({ - onlyTopLevel = false, - hideItems = [], - showItems, - type = "sidebar", - hideTitle = false, - childLevel = 1, -}: ChildDocsProps) => { - const { currentItems, activeItem } = useSidebar() - const filterType = useMemo(() => { - return showItems !== undefined - ? "show" - : hideItems.length > 0 - ? "hide" - : "all" - }, [showItems, hideItems]) - - const filterCondition = (item: SidebarItem): boolean => { - if (item.type === "separator") { - return false - } - switch (filterType) { - case "hide": - return ( - (item.type !== "link" || !hideItems.includes(item.path)) && - !hideItems.includes(item.title) - ) - case "show": - return ( - (item.type === "link" && showItems!.includes(item.path)) || - showItems!.includes(item.title) - ) - case "all": - return true - } - } - - const filterItems = (items: SidebarItem[]): SidebarItem[] => { - return items - .filter(filterCondition) - .map((item) => Object.assign({}, item)) - .map((item) => { - if ( - item.type !== "separator" && - item.children && - filterType === "hide" - ) { - item.children = filterItems(item.children) - } - - return item - }) - } - - const filteredItems = useMemo(() => { - const targetItems = - type === "sidebar" - ? currentItems - ? Object.assign({}, currentItems) - : undefined - : { - default: [...(activeItem?.children || [])], - } - if (filterType === "all" || !targetItems) { - return targetItems - } - - return { - ...targetItems, - default: filterItems(targetItems.default), - } - }, [currentItems, type, activeItem, filterItems]) - - const filterNonInteractiveItems = ( - items: SidebarItem[] | undefined - ): InteractiveSidebarItem[] => { - return ( - (items?.filter( - (item) => item.type !== "separator" - ) as InteractiveSidebarItem[]) || [] - ) - } - - const getChildrenForLevel = ( - item: InteractiveSidebarItem, - currentLevel = 1 - ): InteractiveSidebarItem[] | undefined => { - if (currentLevel === childLevel) { - return filterNonInteractiveItems(item.children) - } - if (!item.children) { - return - } - - const childrenResult: InteractiveSidebarItem[] = [] - - filterNonInteractiveItems(item.children).forEach((child) => { - const childChildren = getChildrenForLevel(child, currentLevel + 1) - - if (!childChildren) { - return - } - - childrenResult.push(...childChildren) - }) - - return childrenResult - } - - const getTopLevelElms = (items?: SidebarItem[]) => { - return ( - { - const href = - childItem.type === "link" - ? childItem.path - : childItem.children?.length - ? ( - childItem.children.find( - (item) => item.type === "link" - ) as SidebarItemLink - )?.path - : "#" - return { - title: childItem.title, - href, - } - }) || [] - } - /> - ) - } - - const getAllLevelsElms = (items?: SidebarItem[]) => { - const filteredItems = filterNonInteractiveItems(items) - return filteredItems.map((item, key) => { - const itemChildren = getChildrenForLevel(item) - const HeadingComponent = itemChildren?.length ? H2 : undefined - - return ( - - {HeadingComponent && ( - <> - {!hideTitle && ( - - {item.title} - - )} - ({ - title: childItem.title, - href: childItem.type === "link" ? childItem.path : "", - })) || [] - } - /> - {key !== filteredItems.length - 1 &&
} - - )} - {!HeadingComponent && item.type === "link" && ( - - )} -
- ) - }) - } - - const getElms = (items?: SidebarItem[]) => { - return onlyTopLevel ? getTopLevelElms(items) : getAllLevelsElms(items) - } - - return <>{getElms(filteredItems?.default)} + return <>{component} } diff --git a/www/packages/docs-ui/src/components/MDXComponents/index.tsx b/www/packages/docs-ui/src/components/MDXComponents/index.tsx index 39f2b75c1bf3d..c5377fbcb463d 100644 --- a/www/packages/docs-ui/src/components/MDXComponents/index.tsx +++ b/www/packages/docs-ui/src/components/MDXComponents/index.tsx @@ -120,3 +120,5 @@ export const MDXComponents: MDXComponentsType = { return }, } + +export const Hr = MDXComponents["hr"] as () => React.JSX.Element diff --git a/www/packages/docs-ui/src/hooks/index.ts b/www/packages/docs-ui/src/hooks/index.ts index cca8f31263877..42079da035b04 100644 --- a/www/packages/docs-ui/src/hooks/index.ts +++ b/www/packages/docs-ui/src/hooks/index.ts @@ -1,4 +1,5 @@ export * from "./use-active-on-scroll" +export * from "./use-child-docs" export * from "./use-click-outside" export * from "./use-collapsible" export * from "./use-collapsible-code-lines" diff --git a/www/packages/docs-ui/src/hooks/use-child-docs/index.tsx b/www/packages/docs-ui/src/hooks/use-child-docs/index.tsx new file mode 100644 index 0000000000000..2498fa3c6c5dd --- /dev/null +++ b/www/packages/docs-ui/src/hooks/use-child-docs/index.tsx @@ -0,0 +1,216 @@ +"use client" + +import React, { useMemo } from "react" +import { Card, CardList, H2, H3, H4, Hr, useSidebar } from "../.." +import { InteractiveSidebarItem, SidebarItem, SidebarItemLink } from "types" +import slugify from "slugify" +import { MDXComponents } from "../.." + +type HeadingComponent = ( + props: React.HTMLAttributes +) => React.JSX.Element + +export type UseChildDocsProps = { + onlyTopLevel?: boolean + type?: "sidebar" | "item" + hideItems?: string[] + showItems?: string[] + hideTitle?: boolean + titleLevel?: number + childLevel?: number +} + +export const useChildDocs = ({ + onlyTopLevel = false, + hideItems = [], + showItems, + type = "sidebar", + hideTitle = false, + titleLevel = 2, + childLevel = 1, +}: UseChildDocsProps) => { + const { currentItems, activeItem } = useSidebar() + const TitleHeaderComponent: HeadingComponent = useMemo(() => { + switch (titleLevel) { + case 3: + return H3 + case 4: + return H4 + case 5: + return MDXComponents["h5"] as HeadingComponent + case 6: + return MDXComponents["h6"] as HeadingComponent + default: + return H2 + } + }, [titleLevel]) + const filterType = useMemo(() => { + return showItems !== undefined + ? "show" + : hideItems.length > 0 + ? "hide" + : "all" + }, [showItems, hideItems]) + + const filterCondition = (item: SidebarItem): boolean => { + if (item.type === "separator") { + return false + } + switch (filterType) { + case "hide": + return ( + (item.type !== "link" || !hideItems.includes(item.path)) && + !hideItems.includes(item.title) + ) + case "show": + return ( + (item.type === "link" && showItems!.includes(item.path)) || + showItems!.includes(item.title) + ) + case "all": + return true + } + } + + const filterItems = (items: SidebarItem[]): SidebarItem[] => { + return items + .filter(filterCondition) + .map((item) => Object.assign({}, item)) + .map((item) => { + if ( + item.type !== "separator" && + item.children && + filterType === "hide" + ) { + item.children = filterItems(item.children) + } + + return item + }) + } + + const filteredItems = useMemo(() => { + const targetItems = + type === "sidebar" + ? currentItems + ? Object.assign({}, currentItems) + : undefined + : { + default: [...(activeItem?.children || [])], + } + if (filterType === "all" || !targetItems) { + return targetItems + } + + return { + ...targetItems, + default: filterItems(targetItems.default), + } + }, [currentItems, type, activeItem, filterItems]) + + const filterNonInteractiveItems = ( + items: SidebarItem[] | undefined + ): InteractiveSidebarItem[] => { + return ( + (items?.filter( + (item) => item.type !== "separator" + ) as InteractiveSidebarItem[]) || [] + ) + } + + const getChildrenForLevel = ( + item: InteractiveSidebarItem, + currentLevel = 1 + ): InteractiveSidebarItem[] | undefined => { + if (currentLevel === childLevel) { + return filterNonInteractiveItems(item.children) + } + if (!item.children) { + return + } + + const childrenResult: InteractiveSidebarItem[] = [] + + filterNonInteractiveItems(item.children).forEach((child) => { + const childChildren = getChildrenForLevel(child, currentLevel + 1) + + if (!childChildren) { + return + } + + childrenResult.push(...childChildren) + }) + + return childrenResult + } + + const getTopLevelElms = (items?: SidebarItem[]) => { + return ( + { + const href = + childItem.type === "link" + ? childItem.path + : childItem.children?.length + ? ( + childItem.children.find( + (item) => item.type === "link" + ) as SidebarItemLink + )?.path + : "#" + return { + title: childItem.title, + href, + } + }) || [] + } + /> + ) + } + + const getAllLevelsElms = (items?: SidebarItem[]) => { + const filteredItems = filterNonInteractiveItems(items) + return filteredItems.map((item, key) => { + const itemChildren = getChildrenForLevel(item) + const HeadingComponent = itemChildren?.length + ? TitleHeaderComponent + : undefined + + return ( + + {HeadingComponent && ( + <> + {!hideTitle && ( + + {item.title} + + )} + ({ + title: childItem.title, + href: childItem.type === "link" ? childItem.path : "", + })) || [] + } + /> + {key !== filteredItems.length - 1 &&
} + + )} + {!HeadingComponent && item.type === "link" && ( + + )} +
+ ) + }) + } + + const getElms = (items?: SidebarItem[]) => { + return onlyTopLevel ? getTopLevelElms(items) : getAllLevelsElms(items) + } + + return { + items: filteredItems, + component: getElms(filteredItems?.default), + } +} diff --git a/www/packages/tags/src/tags/index.ts b/www/packages/tags/src/tags/index.ts index 3180e8cc416ae..b4437ec5a6957 100644 --- a/www/packages/tags/src/tags/index.ts +++ b/www/packages/tags/src/tags/index.ts @@ -1,31 +1,31 @@ export * from "./product.js" -export * from "./tax.js" +export * from "./cart.js" export * from "./storefront.js" export * from "./order.js" export * from "./payment.js" export * from "./stripe.js" export * from "./fulfillment.js" -export * from "./customer.js" export * from "./auth.js" -export * from "./pricing.js" +export * from "./customer.js" export * from "./product-collection.js" export * from "./inventory.js" export * from "./publishable-api-key.js" -export * from "./region.js" export * from "./api-key.js" -export * from "./step.js" +export * from "./region.js" export * from "./remote-link.js" +export * from "./step.js" export * from "./sales-channel.js" export * from "./workflow.js" -export * from "./remote-query.js" -export * from "./event-bus.js" export * from "./store.js" -export * from "./logger.js" +export * from "./event-bus.js" export * from "./promotion.js" +export * from "./product-category.js" +export * from "./logger.js" +export * from "./remote-query.js" export * from "./locking.js" export * from "./file.js" -export * from "./user.js" -export * from "./product-category.js" export * from "./stock-location.js" -export * from "./cart.js" +export * from "./pricing.js" +export * from "./user.js" export * from "./query.js" +export * from "./tax.js" From afc807f524b0b5decebc8bd61d5bf98e72ad3893 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Wed, 25 Dec 2024 13:34:46 +0200 Subject: [PATCH 02/21] revise auth module --- .../auth/create-actor-type/page.mdx | 7 + .../app/commerce-modules/auth/page.mdx | 179 ++++++++---------- .../auth/reset-password/page.mdx | 7 + .../CommerceModuleSections/index.tsx | 7 + www/apps/resources/generated/edit-dates.mjs | 8 +- www/apps/resources/generated/sidebar.mjs | 162 ++++++++++++++-- .../page.mdx | 3 + www/apps/resources/scripts/prepare.mjs | 3 - www/apps/resources/sidebars/api-key.mjs | 7 + www/apps/resources/sidebars/auth.mjs | 67 ++++--- .../src/hooks/use-child-docs/index.tsx | 4 + www/packages/tags/src/tags/api-key.ts | 2 +- www/packages/tags/src/tags/auth.ts | 24 ++- www/packages/tags/src/tags/cart.ts | 22 +-- www/packages/tags/src/tags/customer.ts | 18 +- www/packages/tags/src/tags/fulfillment.ts | 2 +- www/packages/tags/src/tags/index.ts | 29 +-- www/packages/tags/src/tags/inventory.ts | 2 +- www/packages/tags/src/tags/order.ts | 2 +- www/packages/tags/src/tags/payment.ts | 6 +- www/packages/tags/src/tags/pricing.ts | 12 +- .../tags/src/tags/product-category.ts | 8 +- .../tags/src/tags/product-collection.ts | 6 +- www/packages/tags/src/tags/product.ts | 34 ++-- .../tags/src/tags/publishable-api-key.ts | 2 +- www/packages/tags/src/tags/query.ts | 4 +- www/packages/tags/src/tags/region.ts | 6 +- www/packages/tags/src/tags/server.ts | 14 ++ www/packages/tags/src/tags/storefront.ts | 80 ++++---- www/packages/tags/src/tags/stripe.ts | 2 +- www/packages/tags/src/tags/tax.ts | 4 +- www/packages/tags/src/utils/generate-tags.ts | 56 ++++-- .../merger-custom-options/auth-provider.ts | 1 + 33 files changed, 497 insertions(+), 293 deletions(-) create mode 100644 www/packages/tags/src/tags/server.ts diff --git a/www/apps/resources/app/commerce-modules/auth/create-actor-type/page.mdx b/www/apps/resources/app/commerce-modules/auth/create-actor-type/page.mdx index ef99fc17afb75..9449d4732133f 100644 --- a/www/apps/resources/app/commerce-modules/auth/create-actor-type/page.mdx +++ b/www/apps/resources/app/commerce-modules/auth/create-actor-type/page.mdx @@ -1,3 +1,10 @@ +--- +sidebar_label: "Create an Actor Type" +tags: + - auth + - server +--- + export const metadata = { title: `How to Create an Actor Type`, } diff --git a/www/apps/resources/app/commerce-modules/auth/page.mdx b/www/apps/resources/app/commerce-modules/auth/page.mdx index dc13c8de789c7..c0a95764e4a82 100644 --- a/www/apps/resources/app/commerce-modules/auth/page.mdx +++ b/www/apps/resources/app/commerce-modules/auth/page.mdx @@ -1,4 +1,4 @@ -import { CodeTabs, CodeTab } from "docs-ui" +import { CodeTabs, CodeTab, ChildDocs } from "docs-ui" export const metadata = { title: `Auth Module`, @@ -6,132 +6,103 @@ export const metadata = { # {metadata.title} -The Auth Module provides authentication-related features in your Medusa and Node.js applications. +In this section of the documentation, you will find resources to learn more about the Auth Module and how to use it in your application. -## How to Use Auth Module's Service +Medusa has auth related features available out-of-the-box through the Auth Module. A [module](!docs!/learn/fundamentals/modules) is a standalone package that provides features for a single domain. Each of Medusa's commerce features are placed in commerce modules, such as this Auth Module. -Use the Auth Module's main service by resolving from the Medusa container the resource `Modules.AUTH`. + -For example: +Learn more about why modules are isolated in [this documentation](!docs!/learn/fundamentals/modules/isolation). - - + -```ts title="src/workflows/hello-world/step1.ts" -import { createStep } from "@medusajs/framework/workflows-sdk" -import { Modules } from "@medusajs/framework/utils" +## Auth Features -const step1 = createStep("step-1", async (_, { container }) => { - const authModuleService = container.resolve( - Modules.AUTH - ) - const authIdentitys = await authModuleService.listAuthIdentities() -}) -``` +- [Basic User Authentication](./authentication-route/page.mdx#1-basic-authentication-flow): Authenticate users using their email and password credentials. +- [Third-Party and Social Authentication](./authentication-route/page.mdx#2-third-party-service-authenticate-flow): Authenticate users using third-party services and social platforms, such as [Google](./auth-providers/google/page.mdx) and [GitHub](./auth-providers/github/page.mdx). +- [Authenticate Custom Actor Types](./create-actor-type/page.mdx): Create custom user or actor types, such as managers, authenticate them in your application, and guard routes based on the custom user types. +- [Custom Authentication Providers](/references/auth/provider): Integrate third-party services with custom authentication providors. - - +## How to Use Auth Module's Service -```ts title="src/api/store/custom/route.ts" -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" +In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. -export async function GET( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const authModuleService = req.scope.resolve( - Modules.AUTH - ) +You can build custom workflows and steps. You can also re-use Medusa's workflows and steps, which are provided by the `@medusajs/medusa/core-flows` package. - res.json({ - authIdentitys: await authModuleService.listAuthIdentities(), - }) -} -``` +For example: - - +```ts title="src/workflows/authenticate-user.ts" +import { + createWorkflow, + WorkflowResponse, + createStep, + StepResponse, +} from "@medusajs/framework/workflows-sdk" +import { Modules, MedusaError } from "@medusajs/framework/utils" +import { MedusaRequest } from "@medusajs/framework/http" + +type Input = { + req: MedusaRequest +} -```ts title="src/subscribers/custom-handler.ts" -import { SubscriberArgs } from "@medusajs/framework" -import { Modules } from "@medusajs/framework/utils" +const authenticateUserStep = createStep( + "authenticate-user", + async ({ req }: Input, { container }) => { + const authModuleService = container.resolve(Modules.AUTH) + + const { success, authIdentity, error } = await authModuleService + .authenticate( + "emailpass", + { + url: req.url, + headers: req.headers, + query: req.query, + body: req.body, + authScope: "admin", // or custom actor type + protocol: req.protocol, + } + ) + + if (!success) { + // incorrect authentication details + throw new MedusaError(error) + } + + return new StepResponse({ authIdentity }, authIdentity.id) + }, + async (authIdentityId, { container }) => { + const authModuleService = container.resolve(Modules.AUTH) + + await authModuleService.deleteAuthIdentities([authIdentityId]) + } +) -export default async function subscriberHandler({ container }: SubscriberArgs) { - const authModuleService = container.resolve( - Modules.AUTH - ) +export const authenticateUserWorkflow = createWorkflow( + "authenticate-user", + (input: Input) => { + const authIdentity = authenticateUserStep(input) - const authIdentitys = await authModuleService.listAuthIdentities() -} + return new WorkflowResponse({ + authIdentity, + }) + } +) ``` - - - --- -## Features - -### Basic User Authentication - -Authenticate users using their email and password credentials. - -```ts -const { success, authIdentity, error } = await authModuleService.authenticate( - "emailpass", - { - url: req.url, - headers: req.headers, - query: req.query, - body: req.body, - authScope: "admin", - protocol: req.protocol, - } as AuthenticationInput -) - -if (!success) { - // incorrect authentication details - throw new Error(error) -} -``` +## Configure Auth Module -### Third-Party and Social Authentication +The Auth Module accepts options for further configurations. Refer to [this documentation](./module-options/page.mdx) for details on the module's options. -The Auth Module supports a variety of authentication methods, such as authenticating with third-party services and social platforms. +--- -```ts -// in authentication API route -const { success, authIdentity, location } = - await authModuleService.authenticate("google", { - url: req.url, - headers: req.headers, - query: req.query, - body: req.body, - authScope: "admin", - protocol: req.protocol, - } as AuthenticationInput) +## Providers -if (location) { - return res.json({ location }) -} +Medusa provides the following authentication providers out-of-the-box. You can use them to authenticate admin users, customers, or custom actor types. -// in callback API route -const { success, authIdentity } = await authModuleService.validateCallback( - "google", - { - url: req.url, - headers: req.headers, - query: req.query, - body: req.body, - authScope: "admin", - protocol: req.protocol, - } as AuthenticationInput -) -``` + --- -## Configure Auth Module - -Refer to [this documentation](./module-options/page.mdx) for details on the module's options. + \ No newline at end of file diff --git a/www/apps/resources/app/commerce-modules/auth/reset-password/page.mdx b/www/apps/resources/app/commerce-modules/auth/reset-password/page.mdx index 632e3fb4a6dda..cbb342f523879 100644 --- a/www/apps/resources/app/commerce-modules/auth/reset-password/page.mdx +++ b/www/apps/resources/app/commerce-modules/auth/reset-password/page.mdx @@ -1,3 +1,10 @@ +--- +sidebar_label: "Handle Password Reset Event" +tags: + - auth + - server +--- + import { Prerequisites } from "docs-ui" export const metadata = { diff --git a/www/apps/resources/components/CommerceModuleSections/index.tsx b/www/apps/resources/components/CommerceModuleSections/index.tsx index 6ce07aacd1254..1c83fa1c90722 100644 --- a/www/apps/resources/components/CommerceModuleSections/index.tsx +++ b/www/apps/resources/components/CommerceModuleSections/index.tsx @@ -14,14 +14,17 @@ export const CommerceModuleSections = ({ const { component: workflowsComponent } = useChildDocs({ showItems: ["Workflows"], titleLevel: 3, + itemsPerRow: 2, }) const { component: stepsComponent } = useChildDocs({ showItems: ["Steps"], titleLevel: 3, + itemsPerRow: 2, }) const { items: serverGuideItems, component: serverGuidesComponent } = useChildDocs({ showItems: ["Server Guides"], + itemsPerRow: 2, }) if (serverGuideItems?.default.length) { components.push(serverGuidesComponent) @@ -29,6 +32,7 @@ export const CommerceModuleSections = ({ const { items: storefrontGuideItems, component: storefrontGuidesComponent } = useChildDocs({ showItems: ["Storefront Guides"], + itemsPerRow: 2, }) if (storefrontGuideItems?.default.length) { components.push(storefrontGuidesComponent) @@ -36,6 +40,7 @@ export const CommerceModuleSections = ({ const { items: adminGuideItems, component: adminGuidesComponent } = useChildDocs({ showItems: ["Admin Guides"], + itemsPerRow: 2, }) if (adminGuideItems?.default.length) { components.push(adminGuidesComponent) @@ -43,6 +48,7 @@ export const CommerceModuleSections = ({ const { items: userGuideItems, component: userGuidesComponent } = useChildDocs({ showItems: ["User Guides"], + itemsPerRow: 2, }) if (userGuideItems?.default.length) { components.push(userGuidesComponent) @@ -50,6 +56,7 @@ export const CommerceModuleSections = ({ const { items: referenceItems, component: referencesComponent } = useChildDocs({ showItems: ["References"], + itemsPerRow: 2, }) if (referenceItems?.default.length) { components.push(referencesComponent) diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index 70cf5cfadd9b0..2751648d19776 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -4,7 +4,7 @@ export const generatedEditDates = { "app/commerce-modules/auth/authentication-route/page.mdx": "2024-09-05T12:06:38.155Z", "app/commerce-modules/auth/examples/page.mdx": "2024-10-15T15:02:13.794Z", "app/commerce-modules/auth/module-options/page.mdx": "2024-10-15T12:52:08.930Z", - "app/commerce-modules/auth/page.mdx": "2024-12-09T14:46:55.446Z", + "app/commerce-modules/auth/page.mdx": "2024-12-25T11:16:19.608Z", "app/commerce-modules/cart/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/cart/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/cart/concepts/page.mdx": "2024-10-08T07:49:03.737Z", @@ -210,7 +210,7 @@ export const generatedEditDates = { "app/commerce-modules/auth/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/auth/auth-identity-and-actor-types/page.mdx": "2024-12-09T13:04:01.129Z", "app/commerce-modules/api-key/page.mdx": "2024-12-25T09:22:23.514Z", - "app/commerce-modules/auth/create-actor-type/page.mdx": "2024-12-09T15:32:07.594Z", + "app/commerce-modules/auth/create-actor-type/page.mdx": "2024-12-25T11:06:44.228Z", "app/architectural-modules/page.mdx": "2024-12-11T10:33:53.064Z", "app/architectural-modules/workflow-engine/redis/page.mdx": "2024-10-15T12:50:59.507Z", "app/architectural-modules/notification/sendgrid/page.mdx": "2024-10-15T12:51:25.569Z", @@ -885,7 +885,7 @@ export const generatedEditDates = { "references/auth/IAuthModuleService/methods/auth.IAuthModuleService.authenticate/page.mdx": "2024-12-10T14:54:57.312Z", "references/auth/IAuthModuleService/methods/auth.IAuthModuleService.validateCallback/page.mdx": "2024-12-10T14:54:57.318Z", "references/auth/interfaces/auth.AuthenticationResponse/page.mdx": "2024-12-09T13:21:36.233Z", - "references/auth_provider/classes/auth_provider.AbstractAuthModuleProvider/page.mdx": "2024-12-09T13:21:36.205Z", + "references/auth_provider/classes/auth_provider.AbstractAuthModuleProvider/page.mdx": "2024-12-25T11:08:55.949Z", "references/core_flows/Invite/Workflows_Invite/functions/core_flows.Invite.Workflows_Invite.refreshInviteTokensWorkflow/page.mdx": "2024-12-25T08:43:13.811Z", "references/types/CommonTypes/types/types.CommonTypes.BatchMethodResponse/page.mdx": "2024-12-09T13:21:32.849Z", "references/types/HttpTypes/interfaces/types.HttpTypes.AdminAddReturnShipping/page.mdx": "2024-12-09T13:21:34.545Z", @@ -2145,7 +2145,7 @@ export const generatedEditDates = { "app/admin-components/layouts/single-column/page.mdx": "2024-10-07T11:16:06.435Z", "app/admin-components/layouts/two-column/page.mdx": "2024-10-07T11:16:10.092Z", "app/admin-components/components/forms/page.mdx": "2024-10-09T12:48:04.229Z", - "app/commerce-modules/auth/reset-password/page.mdx": "2024-11-27T13:33:55.940Z", + "app/commerce-modules/auth/reset-password/page.mdx": "2024-12-25T11:17:12.203Z", "app/storefront-development/customers/reset-password/page.mdx": "2024-12-19T16:32:00.724Z", "app/commerce-modules/api-key/links-to-other-modules/page.mdx": "2024-12-24T14:36:06.109Z", "app/commerce-modules/cart/extend/page.mdx": "2024-12-11T09:05:37.041Z", diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs index 5d87f58cbb6a7..ea203970c80bf 100644 --- a/www/apps/resources/generated/sidebar.mjs +++ b/www/apps/resources/generated/sidebar.mjs @@ -196,6 +196,7 @@ export const generatedSidebar = [ "isPathHref": true, "type": "category", "title": "Concepts", + "initialOpen": false, "children": [ { "loaded": true, @@ -220,6 +221,7 @@ export const generatedSidebar = [ "isPathHref": true, "type": "category", "title": "Storefront Guides", + "initialOpen": false, "autogenerate_tags": "storefront+apiKey", "children": [ { @@ -227,7 +229,7 @@ export const generatedSidebar = [ "isPathHref": true, "type": "link", "title": "Use a Publishable API Key in the Storefront", - "path": "/app/storefront-development/publishable-api-keys", + "path": "/storefront-development/publishable-api-keys", "children": [] } ] @@ -237,6 +239,7 @@ export const generatedSidebar = [ "isPathHref": true, "type": "category", "title": "Workflows", + "initialOpen": false, "autogenerate_tags": "workflow+apiKey", "children": [ { @@ -278,6 +281,7 @@ export const generatedSidebar = [ "isPathHref": true, "type": "category", "title": "Steps", + "initialOpen": false, "autogenerate_tags": "step+apiKey", "children": [ { @@ -319,6 +323,7 @@ export const generatedSidebar = [ "isPathHref": true, "type": "category", "title": "References", + "initialOpen": false, "children": [ { "loaded": true, @@ -480,16 +485,9 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "link", - "path": "/commerce-modules/auth/examples", - "title": "Examples", - "children": [] - }, - { - "loaded": true, - "isPathHref": true, - "type": "sub-category", + "type": "category", "title": "Concepts", + "initialOpen": false, "children": [ { "loaded": true, @@ -528,31 +526,33 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "sub-category", - "title": "Guides", + "type": "category", + "title": "Server Guides", + "autogenerate_tags": "server+auth", + "initialOpen": false, "children": [ { "loaded": true, "isPathHref": true, "type": "link", - "path": "/commerce-modules/auth/create-actor-type", "title": "Create an Actor Type", + "path": "/commerce-modules/auth/create-actor-type", "children": [] }, { "loaded": true, "isPathHref": true, "type": "link", - "path": "/commerce-modules/auth/reset-password", "title": "Handle Password Reset Event", + "path": "/commerce-modules/auth/reset-password", "children": [] }, { "loaded": true, "isPathHref": true, "type": "link", + "title": "How to Create an Auth Provider Module", "path": "/references/auth/provider", - "title": "Create Auth Provider Module", "children": [] } ] @@ -560,8 +560,135 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", + "title": "Storefront Guides", + "autogenerate_tags": "storefront+auth", + "initialOpen": false, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "Log-out Customer in Storefront", + "path": "/storefront-development/customers/log-out", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "Login Customer in Storefront", + "path": "/storefront-development/customers/login", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "Register Customer in Storefront", + "path": "/storefront-development/customers/register", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "Reset Customer Password in Storefront", + "path": "/storefront-development/customers/reset-password", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "Retrieve Customer in Storefront", + "path": "/storefront-development/customers/retrieve", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "Third-Party or Social Login in Storefront", + "path": "/storefront-development/customers/third-party-login", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Workflows", + "autogenerate_tags": "workflow+auth", + "initialOpen": false, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "createCustomerAccountWorkflow", + "path": "/references/medusa-workflows/createCustomerAccountWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "removeCustomerAccountWorkflow", + "path": "/references/medusa-workflows/removeCustomerAccountWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "acceptInviteWorkflow", + "path": "/references/medusa-workflows/acceptInviteWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "createUserAccountWorkflow", + "path": "/references/medusa-workflows/createUserAccountWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "removeUserAccountWorkflow", + "path": "/references/medusa-workflows/removeUserAccountWorkflow", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Steps", + "autogenerate_tags": "step+auth", + "initialOpen": false, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "setAuthAppMetadataStep", + "path": "/references/medusa-workflows/steps/setAuthAppMetadataStep", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", "title": "Providers", + "initialOpen": false, "children": [ { "loaded": true, @@ -592,8 +719,9 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", "title": "References", + "initialOpen": false, "children": [ { "loaded": true, diff --git a/www/apps/resources/references/auth_provider/classes/auth_provider.AbstractAuthModuleProvider/page.mdx b/www/apps/resources/references/auth_provider/classes/auth_provider.AbstractAuthModuleProvider/page.mdx index 292f17ace60af..b2c26dfd21494 100644 --- a/www/apps/resources/references/auth_provider/classes/auth_provider.AbstractAuthModuleProvider/page.mdx +++ b/www/apps/resources/references/auth_provider/classes/auth_provider.AbstractAuthModuleProvider/page.mdx @@ -1,5 +1,8 @@ --- slug: /references/auth/provider +tags: + - auth + - server --- import { TypeList } from "docs-ui" diff --git a/www/apps/resources/scripts/prepare.mjs b/www/apps/resources/scripts/prepare.mjs index 78ee2bb6e5ff3..a9ec814a87ea8 100644 --- a/www/apps/resources/scripts/prepare.mjs +++ b/www/apps/resources/scripts/prepare.mjs @@ -1,12 +1,9 @@ import { generateEditedDates, generateSidebar } from "build-scripts" -import { generateTags } from "tags" import { main as generateSlugChanges } from "./generate-slug-changes.mjs" import { main as generateFilesMap } from "./generate-files-map.mjs" import { sidebar } from "../sidebar.mjs" -import path from "path" async function main() { - await generateTags(path.resolve("..", "..", "packages", "tags")) await generateSidebar(sidebar) await generateSlugChanges() await generateFilesMap() diff --git a/www/apps/resources/sidebars/api-key.mjs b/www/apps/resources/sidebars/api-key.mjs index 9b23a277414ba..9a16bb3207641 100644 --- a/www/apps/resources/sidebars/api-key.mjs +++ b/www/apps/resources/sidebars/api-key.mjs @@ -13,6 +13,7 @@ export const apiKeySidebar = [ { type: "category", title: "Concepts", + initialOpen: false, children: [ { type: "link", @@ -29,31 +30,37 @@ export const apiKeySidebar = [ { type: "category", title: "Storefront Guides", + initialOpen: false, autogenerate_tags: "storefront+apiKey", }, { type: "category", title: "Admin Guides", + initialOpen: false, autogenerate_tags: "admin+apiKey", }, { type: "category", title: "User Guides", + initialOpen: false, autogenerate_tags: "userGuide+apiKey", }, { type: "category", title: "Workflows", + initialOpen: false, autogenerate_tags: "workflow+apiKey", }, { type: "category", title: "Steps", + initialOpen: false, autogenerate_tags: "step+apiKey", }, { type: "category", title: "References", + initialOpen: false, children: [ { type: "link", diff --git a/www/apps/resources/sidebars/auth.mjs b/www/apps/resources/sidebars/auth.mjs index 6f4baea84e7de..4f79562d8a933 100644 --- a/www/apps/resources/sidebars/auth.mjs +++ b/www/apps/resources/sidebars/auth.mjs @@ -16,13 +16,9 @@ export const authSidebar = [ title: "Module Options", }, { - type: "link", - path: "/commerce-modules/auth/examples", - title: "Examples", - }, - { - type: "sub-category", + type: "category", title: "Concepts", + initialOpen: false, children: [ { type: "link", @@ -47,29 +43,45 @@ export const authSidebar = [ ], }, { - type: "sub-category", - title: "Guides", - children: [ - { - type: "link", - path: "/commerce-modules/auth/create-actor-type", - title: "Create an Actor Type", - }, - { - type: "link", - path: "/commerce-modules/auth/reset-password", - title: "Handle Password Reset Event", - }, - { - type: "link", - path: "/references/auth/provider", - title: "Create Auth Provider Module", - }, - ], + type: "category", + title: "Server Guides", + autogenerate_tags: "server+auth", + initialOpen: false, + }, + { + type: "category", + title: "Storefront Guides", + autogenerate_tags: "storefront+auth", + initialOpen: false, + }, + { + type: "category", + title: "Admin Guides", + autogenerate_tags: "admin+auth", + initialOpen: false, + }, + { + type: "category", + title: "User Guides", + autogenerate_tags: "userGuides+auth", + initialOpen: false, + }, + { + type: "category", + title: "Workflows", + autogenerate_tags: "workflow+auth", + initialOpen: false, + }, + { + type: "category", + title: "Steps", + autogenerate_tags: "step+auth", + initialOpen: false, }, { - type: "sub-category", + type: "category", title: "Providers", + initialOpen: false, children: [ { type: "link", @@ -89,8 +101,9 @@ export const authSidebar = [ ], }, { - type: "sub-category", + type: "category", title: "References", + initialOpen: false, children: [ { type: "link", diff --git a/www/packages/docs-ui/src/hooks/use-child-docs/index.tsx b/www/packages/docs-ui/src/hooks/use-child-docs/index.tsx index 2498fa3c6c5dd..f130211346716 100644 --- a/www/packages/docs-ui/src/hooks/use-child-docs/index.tsx +++ b/www/packages/docs-ui/src/hooks/use-child-docs/index.tsx @@ -18,6 +18,7 @@ export type UseChildDocsProps = { hideTitle?: boolean titleLevel?: number childLevel?: number + itemsPerRow?: number } export const useChildDocs = ({ @@ -28,6 +29,7 @@ export const useChildDocs = ({ hideTitle = false, titleLevel = 2, childLevel = 1, + itemsPerRow, }: UseChildDocsProps) => { const { currentItems, activeItem } = useSidebar() const TitleHeaderComponent: HeadingComponent = useMemo(() => { @@ -165,6 +167,7 @@ export const useChildDocs = ({ } }) || [] } + itemsPerRow={itemsPerRow} /> ) } @@ -193,6 +196,7 @@ export const useChildDocs = ({ href: childItem.type === "link" ? childItem.path : "", })) || [] } + itemsPerRow={itemsPerRow} /> {key !== filteredItems.length - 1 &&
} diff --git a/www/packages/tags/src/tags/api-key.ts b/www/packages/tags/src/tags/api-key.ts index 413887972854b..c0f4ea5571aa1 100644 --- a/www/packages/tags/src/tags/api-key.ts +++ b/www/packages/tags/src/tags/api-key.ts @@ -1,7 +1,7 @@ export const apiKey = [ { "title": "Use a Publishable API Key in the Storefront", - "path": "/app/storefront-development/publishable-api-keys" + "path": "/storefront-development/publishable-api-keys" }, { "title": "createApiKeysStep", diff --git a/www/packages/tags/src/tags/auth.ts b/www/packages/tags/src/tags/auth.ts index ee8b6fad16ff2..c508f122f6aba 100644 --- a/www/packages/tags/src/tags/auth.ts +++ b/www/packages/tags/src/tags/auth.ts @@ -1,27 +1,39 @@ export const auth = [ + { + "title": "Create an Actor Type", + "path": "/commerce-modules/auth/create-actor-type" + }, + { + "title": "Handle Password Reset Event", + "path": "/commerce-modules/auth/reset-password" + }, { "title": "Log-out Customer in Storefront", - "path": "/app/storefront-development/customers/log-out" + "path": "/storefront-development/customers/log-out" }, { "title": "Login Customer in Storefront", - "path": "/app/storefront-development/customers/login" + "path": "/storefront-development/customers/login" }, { "title": "Register Customer in Storefront", - "path": "/app/storefront-development/customers/register" + "path": "/storefront-development/customers/register" }, { "title": "Reset Customer Password in Storefront", - "path": "/app/storefront-development/customers/reset-password" + "path": "/storefront-development/customers/reset-password" }, { "title": "Retrieve Customer in Storefront", - "path": "/app/storefront-development/customers/retrieve" + "path": "/storefront-development/customers/retrieve" }, { "title": "Third-Party or Social Login in Storefront", - "path": "/app/storefront-development/customers/third-party-login" + "path": "/storefront-development/customers/third-party-login" + }, + { + "title": "How to Create an Auth Provider Module", + "path": "/references/auth/provider" }, { "title": "setAuthAppMetadataStep", diff --git a/www/packages/tags/src/tags/cart.ts b/www/packages/tags/src/tags/cart.ts index bd506612ddb96..2777e5dcab162 100644 --- a/www/packages/tags/src/tags/cart.ts +++ b/www/packages/tags/src/tags/cart.ts @@ -1,47 +1,47 @@ export const cart = [ { "title": "Create Cart Context in Storefront", - "path": "/app/storefront-development/cart/context" + "path": "/storefront-development/cart/context" }, { "title": "Create Cart in Storefront", - "path": "/app/storefront-development/cart/create" + "path": "/storefront-development/cart/create" }, { "title": "Manage Cart's Items in Storefront", - "path": "/app/storefront-development/cart/manage-items" + "path": "/storefront-development/cart/manage-items" }, { "title": "Retrieve Cart in Storefront", - "path": "/app/storefront-development/cart/retrieve" + "path": "/storefront-development/cart/retrieve" }, { "title": "Update Cart in Storefront", - "path": "/app/storefront-development/cart/update" + "path": "/storefront-development/cart/update" }, { "title": "Checkout Step 2: Enter Address", - "path": "/app/storefront-development/checkout/address" + "path": "/storefront-development/checkout/address" }, { "title": "Checkout Step 5: Complete Cart", - "path": "/app/storefront-development/checkout/complete-cart" + "path": "/storefront-development/checkout/complete-cart" }, { "title": "Checkout Step 1: Enter Email", - "path": "/app/storefront-development/checkout/email" + "path": "/storefront-development/checkout/email" }, { "title": "Checkout Step 4: Choose Payment Provider", - "path": "/app/storefront-development/checkout/payment" + "path": "/storefront-development/checkout/payment" }, { "title": "Payment with Stripe in React Storefront", - "path": "/app/storefront-development/checkout/payment/stripe" + "path": "/storefront-development/checkout/payment/stripe" }, { "title": "Checkout Step 3: Choose Shipping Method", - "path": "/app/storefront-development/checkout/shipping" + "path": "/storefront-development/checkout/shipping" }, { "title": "addShippingMethodToCartStep", diff --git a/www/packages/tags/src/tags/customer.ts b/www/packages/tags/src/tags/customer.ts index e1cd6e0bc79f4..c5dcc39568e79 100644 --- a/www/packages/tags/src/tags/customer.ts +++ b/www/packages/tags/src/tags/customer.ts @@ -1,39 +1,39 @@ export const customer = [ { "title": "Manage Customer Addresses in Storefront", - "path": "/app/storefront-development/customers/addresses" + "path": "/storefront-development/customers/addresses" }, { "title": "Customer Context in Storefront", - "path": "/app/storefront-development/customers/context" + "path": "/storefront-development/customers/context" }, { "title": "Log-out Customer in Storefront", - "path": "/app/storefront-development/customers/log-out" + "path": "/storefront-development/customers/log-out" }, { "title": "Login Customer in Storefront", - "path": "/app/storefront-development/customers/login" + "path": "/storefront-development/customers/login" }, { "title": "Edit Customer Profile in Storefront", - "path": "/app/storefront-development/customers/profile" + "path": "/storefront-development/customers/profile" }, { "title": "Register Customer in Storefront", - "path": "/app/storefront-development/customers/register" + "path": "/storefront-development/customers/register" }, { "title": "Reset Customer Password in Storefront", - "path": "/app/storefront-development/customers/reset-password" + "path": "/storefront-development/customers/reset-password" }, { "title": "Retrieve Customer in Storefront", - "path": "/app/storefront-development/customers/retrieve" + "path": "/storefront-development/customers/retrieve" }, { "title": "Third-Party or Social Login in Storefront", - "path": "/app/storefront-development/customers/third-party-login" + "path": "/storefront-development/customers/third-party-login" }, { "title": "findOrCreateCustomerStep", diff --git a/www/packages/tags/src/tags/fulfillment.ts b/www/packages/tags/src/tags/fulfillment.ts index 03d85179c72ca..f7915835f7f13 100644 --- a/www/packages/tags/src/tags/fulfillment.ts +++ b/www/packages/tags/src/tags/fulfillment.ts @@ -1,7 +1,7 @@ export const fulfillment = [ { "title": "Checkout Step 3: Choose Shipping Method", - "path": "/app/storefront-development/checkout/shipping" + "path": "/storefront-development/checkout/shipping" }, { "title": "validateCartShippingOptionsStep", diff --git a/www/packages/tags/src/tags/index.ts b/www/packages/tags/src/tags/index.ts index b4437ec5a6957..3f7ce51451a7c 100644 --- a/www/packages/tags/src/tags/index.ts +++ b/www/packages/tags/src/tags/index.ts @@ -1,31 +1,32 @@ -export * from "./product.js" +export * from "./auth.js" +export * from "./query.js" export * from "./cart.js" -export * from "./storefront.js" +export * from "./tax.js" export * from "./order.js" +export * from "./storefront.js" export * from "./payment.js" +export * from "./customer.js" export * from "./stripe.js" +export * from "./product-category.js" export * from "./fulfillment.js" -export * from "./auth.js" -export * from "./customer.js" export * from "./product-collection.js" export * from "./inventory.js" -export * from "./publishable-api-key.js" -export * from "./api-key.js" export * from "./region.js" -export * from "./remote-link.js" +export * from "./api-key.js" +export * from "./publishable-api-key.js" export * from "./step.js" export * from "./sales-channel.js" +export * from "./remote-link.js" +export * from "./remote-query.js" export * from "./workflow.js" -export * from "./store.js" export * from "./event-bus.js" export * from "./promotion.js" -export * from "./product-category.js" -export * from "./logger.js" -export * from "./remote-query.js" +export * from "./store.js" export * from "./locking.js" export * from "./file.js" export * from "./stock-location.js" -export * from "./pricing.js" +export * from "./logger.js" export * from "./user.js" -export * from "./query.js" -export * from "./tax.js" +export * from "./pricing.js" +export * from "./server.js" +export * from "./product.js" diff --git a/www/packages/tags/src/tags/inventory.ts b/www/packages/tags/src/tags/inventory.ts index 5ff02e0c2077d..afb302f775936 100644 --- a/www/packages/tags/src/tags/inventory.ts +++ b/www/packages/tags/src/tags/inventory.ts @@ -1,7 +1,7 @@ export const inventory = [ { "title": "Retrieve Product Variant's Inventory in Storefront", - "path": "/app/storefront-development/products/inventory" + "path": "/storefront-development/products/inventory" }, { "title": "confirmInventoryStep", diff --git a/www/packages/tags/src/tags/order.ts b/www/packages/tags/src/tags/order.ts index 947d59f35769f..2f975e940151a 100644 --- a/www/packages/tags/src/tags/order.ts +++ b/www/packages/tags/src/tags/order.ts @@ -1,7 +1,7 @@ export const order = [ { "title": "Checkout Step 5: Complete Cart", - "path": "/app/storefront-development/checkout/complete-cart" + "path": "/storefront-development/checkout/complete-cart" }, { "title": "addOrderTransactionStep", diff --git a/www/packages/tags/src/tags/payment.ts b/www/packages/tags/src/tags/payment.ts index 77a35378c6457..5212a2544e6af 100644 --- a/www/packages/tags/src/tags/payment.ts +++ b/www/packages/tags/src/tags/payment.ts @@ -1,15 +1,15 @@ export const payment = [ { "title": "Checkout Step 5: Complete Cart", - "path": "/app/storefront-development/checkout/complete-cart" + "path": "/storefront-development/checkout/complete-cart" }, { "title": "Checkout Step 4: Choose Payment Provider", - "path": "/app/storefront-development/checkout/payment" + "path": "/storefront-development/checkout/payment" }, { "title": "Payment with Stripe in React Storefront", - "path": "/app/storefront-development/checkout/payment/stripe" + "path": "/storefront-development/checkout/payment/stripe" }, { "title": "createPaymentCollectionsStep", diff --git a/www/packages/tags/src/tags/pricing.ts b/www/packages/tags/src/tags/pricing.ts index d309be07b26e5..7ff9fae2b33b8 100644 --- a/www/packages/tags/src/tags/pricing.ts +++ b/www/packages/tags/src/tags/pricing.ts @@ -1,27 +1,27 @@ export const pricing = [ { "title": "Get Variant Prices", - "path": "/app/commerce-modules/product/guides/price" + "path": "/commerce-modules/product/guides/price" }, { "title": "Get Variant Price with Taxes", - "path": "/app/commerce-modules/product/guides/price-with-taxes" + "path": "/commerce-modules/product/guides/price-with-taxes" }, { "title": "Example: Show Sale Price", - "path": "/app/storefront-development/products/price/examples/sale-price" + "path": "/storefront-development/products/price/examples/sale-price" }, { "title": "Example: Show Variant's Price", - "path": "/app/storefront-development/products/price/examples/show-price" + "path": "/storefront-development/products/price/examples/show-price" }, { "title": "Example: Show Price with Taxes", - "path": "/app/storefront-development/products/price/examples/tax-price" + "path": "/storefront-development/products/price/examples/tax-price" }, { "title": "Retrieve Product Variant's Prices in Storefront", - "path": "/app/storefront-development/products/price" + "path": "/storefront-development/products/price" }, { "title": "createShippingOptionsPriceSetsStep", diff --git a/www/packages/tags/src/tags/product-category.ts b/www/packages/tags/src/tags/product-category.ts index 0cbb9575019db..6e8622c36a105 100644 --- a/www/packages/tags/src/tags/product-category.ts +++ b/www/packages/tags/src/tags/product-category.ts @@ -1,18 +1,18 @@ export const productCategory = [ { "title": "List Product Categories in Storefront", - "path": "/app/storefront-development/products/categories/list" + "path": "/storefront-development/products/categories/list" }, { "title": "Retrieve Nested Categories in Storefront", - "path": "/app/storefront-development/products/categories/nested-categories" + "path": "/storefront-development/products/categories/nested-categories" }, { "title": "Retrieve a Category's Products in Storefront", - "path": "/app/storefront-development/products/categories/products" + "path": "/storefront-development/products/categories/products" }, { "title": "Retrieve a Category in Storefront", - "path": "/app/storefront-development/products/categories/retrieve" + "path": "/storefront-development/products/categories/retrieve" } ] \ No newline at end of file diff --git a/www/packages/tags/src/tags/product-collection.ts b/www/packages/tags/src/tags/product-collection.ts index 964c0683a6e76..3d1d0c916de0a 100644 --- a/www/packages/tags/src/tags/product-collection.ts +++ b/www/packages/tags/src/tags/product-collection.ts @@ -1,14 +1,14 @@ export const productCollection = [ { "title": "List Product Collections in Storefront", - "path": "/app/storefront-development/products/collections/list" + "path": "/storefront-development/products/collections/list" }, { "title": "Retrieve a Collection's Products in Storefront", - "path": "/app/storefront-development/products/collections/products" + "path": "/storefront-development/products/collections/products" }, { "title": "Retrieve a Collection in Storefront", - "path": "/app/storefront-development/products/collections/retrieve" + "path": "/storefront-development/products/collections/retrieve" } ] \ No newline at end of file diff --git a/www/packages/tags/src/tags/product.ts b/www/packages/tags/src/tags/product.ts index d5f21ec0dc7ca..6038da105e74f 100644 --- a/www/packages/tags/src/tags/product.ts +++ b/www/packages/tags/src/tags/product.ts @@ -1,71 +1,71 @@ export const product = [ { "title": "Get Variant Prices", - "path": "/app/commerce-modules/product/guides/price" + "path": "/commerce-modules/product/guides/price" }, { "title": "Get Variant Price with Taxes", - "path": "/app/commerce-modules/product/guides/price-with-taxes" + "path": "/commerce-modules/product/guides/price-with-taxes" }, { "title": "List Product Categories in Storefront", - "path": "/app/storefront-development/products/categories/list" + "path": "/storefront-development/products/categories/list" }, { "title": "Retrieve Nested Categories in Storefront", - "path": "/app/storefront-development/products/categories/nested-categories" + "path": "/storefront-development/products/categories/nested-categories" }, { "title": "Retrieve a Category's Products in Storefront", - "path": "/app/storefront-development/products/categories/products" + "path": "/storefront-development/products/categories/products" }, { "title": "Retrieve a Category in Storefront", - "path": "/app/storefront-development/products/categories/retrieve" + "path": "/storefront-development/products/categories/retrieve" }, { "title": "List Product Collections in Storefront", - "path": "/app/storefront-development/products/collections/list" + "path": "/storefront-development/products/collections/list" }, { "title": "Retrieve a Collection's Products in Storefront", - "path": "/app/storefront-development/products/collections/products" + "path": "/storefront-development/products/collections/products" }, { "title": "Retrieve a Collection in Storefront", - "path": "/app/storefront-development/products/collections/retrieve" + "path": "/storefront-development/products/collections/retrieve" }, { "title": "Retrieve Product Variant's Inventory in Storefront", - "path": "/app/storefront-development/products/inventory" + "path": "/storefront-development/products/inventory" }, { "title": "List Products in Storefront", - "path": "/app/storefront-development/products/list" + "path": "/storefront-development/products/list" }, { "title": "Example: Show Sale Price", - "path": "/app/storefront-development/products/price/examples/sale-price" + "path": "/storefront-development/products/price/examples/sale-price" }, { "title": "Example: Show Variant's Price", - "path": "/app/storefront-development/products/price/examples/show-price" + "path": "/storefront-development/products/price/examples/show-price" }, { "title": "Example: Show Price with Taxes", - "path": "/app/storefront-development/products/price/examples/tax-price" + "path": "/storefront-development/products/price/examples/tax-price" }, { "title": "Retrieve Product Variant's Prices in Storefront", - "path": "/app/storefront-development/products/price" + "path": "/storefront-development/products/price" }, { "title": "Retrieve a Product in Storefront", - "path": "/app/storefront-development/products/retrieve" + "path": "/storefront-development/products/retrieve" }, { "title": "Select Product Variants in Storefront", - "path": "/app/storefront-development/products/variants" + "path": "/storefront-development/products/variants" }, { "title": "batchLinkProductsToCollectionStep", diff --git a/www/packages/tags/src/tags/publishable-api-key.ts b/www/packages/tags/src/tags/publishable-api-key.ts index 44f281ed34cad..560223940d697 100644 --- a/www/packages/tags/src/tags/publishable-api-key.ts +++ b/www/packages/tags/src/tags/publishable-api-key.ts @@ -1,6 +1,6 @@ export const publishableApiKey = [ { "title": "Use a Publishable API Key in the Storefront", - "path": "/app/storefront-development/publishable-api-keys" + "path": "/storefront-development/publishable-api-keys" } ] \ No newline at end of file diff --git a/www/packages/tags/src/tags/query.ts b/www/packages/tags/src/tags/query.ts index ae0b73e8ebeae..c41850749a7f6 100644 --- a/www/packages/tags/src/tags/query.ts +++ b/www/packages/tags/src/tags/query.ts @@ -1,11 +1,11 @@ export const query = [ { "title": "Get Variant Prices", - "path": "/app/commerce-modules/product/guides/price" + "path": "/commerce-modules/product/guides/price" }, { "title": "Get Variant Price with Taxes", - "path": "/app/commerce-modules/product/guides/price-with-taxes" + "path": "/commerce-modules/product/guides/price-with-taxes" }, { "title": "addShippingMethodToCartWorkflow", diff --git a/www/packages/tags/src/tags/region.ts b/www/packages/tags/src/tags/region.ts index 6f69b6c97b093..58868e4db6746 100644 --- a/www/packages/tags/src/tags/region.ts +++ b/www/packages/tags/src/tags/region.ts @@ -1,15 +1,15 @@ export const region = [ { "title": "Region Context in Storefront", - "path": "/app/storefront-development/regions/context" + "path": "/storefront-development/regions/context" }, { "title": "List Regions in Storefront", - "path": "/app/storefront-development/regions/list" + "path": "/storefront-development/regions/list" }, { "title": "Store and Retrieve Region", - "path": "/app/storefront-development/regions/store-retrieve-region" + "path": "/storefront-development/regions/store-retrieve-region" }, { "title": "findOneOrAnyRegionStep", diff --git a/www/packages/tags/src/tags/server.ts b/www/packages/tags/src/tags/server.ts new file mode 100644 index 0000000000000..5c65e12e37edd --- /dev/null +++ b/www/packages/tags/src/tags/server.ts @@ -0,0 +1,14 @@ +export const server = [ + { + "title": "Create an Actor Type", + "path": "/commerce-modules/auth/create-actor-type" + }, + { + "title": "Handle Password Reset Event", + "path": "/commerce-modules/auth/reset-password" + }, + { + "title": "How to Create an Auth Provider Module", + "path": "/references/auth/provider" + } +] \ No newline at end of file diff --git a/www/packages/tags/src/tags/storefront.ts b/www/packages/tags/src/tags/storefront.ts index 828634946f41d..b10f22863a3b9 100644 --- a/www/packages/tags/src/tags/storefront.ts +++ b/www/packages/tags/src/tags/storefront.ts @@ -1,162 +1,162 @@ export const storefront = [ { "title": "Create Cart Context in Storefront", - "path": "/app/storefront-development/cart/context" + "path": "/storefront-development/cart/context" }, { "title": "Create Cart in Storefront", - "path": "/app/storefront-development/cart/create" + "path": "/storefront-development/cart/create" }, { "title": "Manage Cart's Items in Storefront", - "path": "/app/storefront-development/cart/manage-items" + "path": "/storefront-development/cart/manage-items" }, { "title": "Retrieve Cart in Storefront", - "path": "/app/storefront-development/cart/retrieve" + "path": "/storefront-development/cart/retrieve" }, { "title": "Update Cart in Storefront", - "path": "/app/storefront-development/cart/update" + "path": "/storefront-development/cart/update" }, { "title": "Checkout Step 2: Enter Address", - "path": "/app/storefront-development/checkout/address" + "path": "/storefront-development/checkout/address" }, { "title": "Checkout Step 5: Complete Cart", - "path": "/app/storefront-development/checkout/complete-cart" + "path": "/storefront-development/checkout/complete-cart" }, { "title": "Checkout Step 1: Enter Email", - "path": "/app/storefront-development/checkout/email" + "path": "/storefront-development/checkout/email" }, { "title": "Checkout Step 4: Choose Payment Provider", - "path": "/app/storefront-development/checkout/payment" + "path": "/storefront-development/checkout/payment" }, { "title": "Payment with Stripe in React Storefront", - "path": "/app/storefront-development/checkout/payment/stripe" + "path": "/storefront-development/checkout/payment/stripe" }, { "title": "Checkout Step 3: Choose Shipping Method", - "path": "/app/storefront-development/checkout/shipping" + "path": "/storefront-development/checkout/shipping" }, { "title": "Manage Customer Addresses in Storefront", - "path": "/app/storefront-development/customers/addresses" + "path": "/storefront-development/customers/addresses" }, { "title": "Customer Context in Storefront", - "path": "/app/storefront-development/customers/context" + "path": "/storefront-development/customers/context" }, { "title": "Log-out Customer in Storefront", - "path": "/app/storefront-development/customers/log-out" + "path": "/storefront-development/customers/log-out" }, { "title": "Login Customer in Storefront", - "path": "/app/storefront-development/customers/login" + "path": "/storefront-development/customers/login" }, { "title": "Edit Customer Profile in Storefront", - "path": "/app/storefront-development/customers/profile" + "path": "/storefront-development/customers/profile" }, { "title": "Register Customer in Storefront", - "path": "/app/storefront-development/customers/register" + "path": "/storefront-development/customers/register" }, { "title": "Reset Customer Password in Storefront", - "path": "/app/storefront-development/customers/reset-password" + "path": "/storefront-development/customers/reset-password" }, { "title": "Retrieve Customer in Storefront", - "path": "/app/storefront-development/customers/retrieve" + "path": "/storefront-development/customers/retrieve" }, { "title": "Third-Party or Social Login in Storefront", - "path": "/app/storefront-development/customers/third-party-login" + "path": "/storefront-development/customers/third-party-login" }, { "title": "List Product Categories in Storefront", - "path": "/app/storefront-development/products/categories/list" + "path": "/storefront-development/products/categories/list" }, { "title": "Retrieve Nested Categories in Storefront", - "path": "/app/storefront-development/products/categories/nested-categories" + "path": "/storefront-development/products/categories/nested-categories" }, { "title": "Retrieve a Category's Products in Storefront", - "path": "/app/storefront-development/products/categories/products" + "path": "/storefront-development/products/categories/products" }, { "title": "Retrieve a Category in Storefront", - "path": "/app/storefront-development/products/categories/retrieve" + "path": "/storefront-development/products/categories/retrieve" }, { "title": "List Product Collections in Storefront", - "path": "/app/storefront-development/products/collections/list" + "path": "/storefront-development/products/collections/list" }, { "title": "Retrieve a Collection's Products in Storefront", - "path": "/app/storefront-development/products/collections/products" + "path": "/storefront-development/products/collections/products" }, { "title": "Retrieve a Collection in Storefront", - "path": "/app/storefront-development/products/collections/retrieve" + "path": "/storefront-development/products/collections/retrieve" }, { "title": "Retrieve Product Variant's Inventory in Storefront", - "path": "/app/storefront-development/products/inventory" + "path": "/storefront-development/products/inventory" }, { "title": "List Products in Storefront", - "path": "/app/storefront-development/products/list" + "path": "/storefront-development/products/list" }, { "title": "Example: Show Sale Price", - "path": "/app/storefront-development/products/price/examples/sale-price" + "path": "/storefront-development/products/price/examples/sale-price" }, { "title": "Example: Show Variant's Price", - "path": "/app/storefront-development/products/price/examples/show-price" + "path": "/storefront-development/products/price/examples/show-price" }, { "title": "Example: Show Price with Taxes", - "path": "/app/storefront-development/products/price/examples/tax-price" + "path": "/storefront-development/products/price/examples/tax-price" }, { "title": "Retrieve Product Variant's Prices in Storefront", - "path": "/app/storefront-development/products/price" + "path": "/storefront-development/products/price" }, { "title": "Retrieve a Product in Storefront", - "path": "/app/storefront-development/products/retrieve" + "path": "/storefront-development/products/retrieve" }, { "title": "Select Product Variants in Storefront", - "path": "/app/storefront-development/products/variants" + "path": "/storefront-development/products/variants" }, { "title": "Use a Publishable API Key in the Storefront", - "path": "/app/storefront-development/publishable-api-keys" + "path": "/storefront-development/publishable-api-keys" }, { "title": "Region Context in Storefront", - "path": "/app/storefront-development/regions/context" + "path": "/storefront-development/regions/context" }, { "title": "List Regions in Storefront", - "path": "/app/storefront-development/regions/list" + "path": "/storefront-development/regions/list" }, { "title": "Store and Retrieve Region", - "path": "/app/storefront-development/regions/store-retrieve-region" + "path": "/storefront-development/regions/store-retrieve-region" }, { "title": "Storefront Development Tips", - "path": "/app/storefront-development/tips" + "path": "/storefront-development/tips" } ] \ No newline at end of file diff --git a/www/packages/tags/src/tags/stripe.ts b/www/packages/tags/src/tags/stripe.ts index 11f08bb59572e..8542ad6c3f290 100644 --- a/www/packages/tags/src/tags/stripe.ts +++ b/www/packages/tags/src/tags/stripe.ts @@ -1,6 +1,6 @@ export const stripe = [ { "title": "Payment with Stripe in React Storefront", - "path": "/app/storefront-development/checkout/payment/stripe" + "path": "/storefront-development/checkout/payment/stripe" } ] \ No newline at end of file diff --git a/www/packages/tags/src/tags/tax.ts b/www/packages/tags/src/tags/tax.ts index 2fecd0eabb18e..99cfbce592e07 100644 --- a/www/packages/tags/src/tags/tax.ts +++ b/www/packages/tags/src/tags/tax.ts @@ -1,11 +1,11 @@ export const tax = [ { "title": "Get Variant Price with Taxes", - "path": "/app/commerce-modules/product/guides/price-with-taxes" + "path": "/commerce-modules/product/guides/price-with-taxes" }, { "title": "Example: Show Price with Taxes", - "path": "/app/storefront-development/products/price/examples/tax-price" + "path": "/storefront-development/products/price/examples/tax-price" }, { "title": "createCartWorkflow", diff --git a/www/packages/tags/src/utils/generate-tags.ts b/www/packages/tags/src/utils/generate-tags.ts index 1b7d6b04abaa8..a75f9eefecfad 100644 --- a/www/packages/tags/src/utils/generate-tags.ts +++ b/www/packages/tags/src/utils/generate-tags.ts @@ -6,25 +6,51 @@ import { findPageTitle, getFrontMatterSync } from "docs-utils" type ConfigItem = { path: string - contentPaths: string[] + contentPaths: { + path: string + omitFromPath?: boolean + }[] } const config: ConfigItem[] = [ { path: path.resolve("..", "..", "apps", "book"), - contentPaths: ["app"], + contentPaths: [ + { + path: "app", + omitFromPath: true, + }, + ], }, { path: path.resolve("..", "..", "apps", "resources"), - contentPaths: ["app", "references"], + contentPaths: [ + { + path: "app", + omitFromPath: true, + }, + { + path: "references", + }, + ], }, { path: path.resolve("..", "..", "apps", "ui"), - contentPaths: [path.join("src", "content", "docs")], + contentPaths: [ + { + path: path.join("src", "content", "docs"), + omitFromPath: true, + }, + ], }, { path: path.resolve("..", "..", "apps", "user-guide"), - contentPaths: ["app"], + contentPaths: [ + { + path: "app", + omitFromPath: true, + }, + ], }, ] @@ -47,20 +73,21 @@ export async function generateTags(basePath?: string) { basePath = basePath || path.resolve() const tags: Tags = {} async function getTags(item: ConfigItem) { - async function scanDirectory(dirPath: string) { - const files = await readdir(dirPath) + async function scanDirectory(currentDirPath: string, omitPath?: string) { + const files = await readdir(currentDirPath) for (const file of files) { - const fullPath = path.join(dirPath, file) + const fullPath = path.join(currentDirPath, file) if (!file.endsWith(".mdx") || file.startsWith("_")) { if (statSync(fullPath).isDirectory()) { - await scanDirectory(fullPath) + await scanDirectory(fullPath, omitPath) } continue } const frontmatter = getFrontMatterSync(fullPath) const fileBasename = path.basename(file) + const itemBasePath = path.join(item.path, omitPath || "") frontmatter.tags?.forEach((tag) => { if (!Object.hasOwn(tags, tag)) { @@ -73,16 +100,21 @@ export async function generateTags(basePath?: string) { ), path: frontmatter.slug || - fullPath.replace(item.path, "").replace(`/${fileBasename}`, ""), + fullPath + .replace(itemBasePath, "") + .replace(`/${fileBasename}`, ""), }) }) } } for (const contentPath of item.contentPaths) { - const basePath = path.join(item.path, contentPath) + const basePath = path.join(item.path, contentPath.path) - await scanDirectory(basePath) + await scanDirectory( + basePath, + !contentPath.omitFromPath ? "" : contentPath.path + ) } } diff --git a/www/utils/packages/typedoc-generate-references/src/constants/merger-custom-options/auth-provider.ts b/www/utils/packages/typedoc-generate-references/src/constants/merger-custom-options/auth-provider.ts index c723bf4b8b0c3..30c41453e81a4 100644 --- a/www/utils/packages/typedoc-generate-references/src/constants/merger-custom-options/auth-provider.ts +++ b/www/utils/packages/typedoc-generate-references/src/constants/merger-custom-options/auth-provider.ts @@ -9,6 +9,7 @@ const authProviderOptions: FormattingOptionsType = { reflectionDescription: `In this document, you’ll learn how to create an auth provider module and the methods you must implement in its main service.`, frontmatterData: { slug: "/references/auth/provider", + tags: ["auth", "server"], }, reflectionTitle: { fullReplacement: "How to Create an Auth Provider Module", From 531c3b7699bfdb7608b5b3c1b5730b77a5a63202 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Wed, 25 Dec 2024 14:16:17 +0200 Subject: [PATCH 03/21] support ref sidebar items --- www/apps/resources/generated/sidebar.mjs | 55 ++++++++------- www/apps/resources/sidebars/api-key.mjs | 5 ++ www/apps/resources/sidebars/auth.mjs | 6 ++ .../build-scripts/src/generate-sidebar.ts | 8 ++- .../src/components/Breadcrumbs/index.tsx | 39 ++++++----- .../src/components/Sidebar/Item/index.tsx | 1 + .../docs-ui/src/components/Sidebar/index.tsx | 4 +- .../src/hooks/use-child-docs/index.tsx | 38 ++++++---- .../src/providers/Pagination/index.tsx | 25 ++++--- .../docs-ui/src/providers/Sidebar/index.tsx | 69 ++++++++++++------- www/packages/tags/src/tags/index.ts | 30 ++++---- www/packages/types/src/sidebar.ts | 13 +++- 12 files changed, 178 insertions(+), 115 deletions(-) diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs index ea203970c80bf..56f802c4d1d14 100644 --- a/www/apps/resources/generated/sidebar.mjs +++ b/www/apps/resources/generated/sidebar.mjs @@ -223,11 +223,12 @@ export const generatedSidebar = [ "title": "Storefront Guides", "initialOpen": false, "autogenerate_tags": "storefront+apiKey", + "autogenerate_as_ref": true, "children": [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "title": "Use a Publishable API Key in the Storefront", "path": "/storefront-development/publishable-api-keys", "children": [] @@ -241,11 +242,12 @@ export const generatedSidebar = [ "title": "Workflows", "initialOpen": false, "autogenerate_tags": "workflow+apiKey", + "autogenerate_as_ref": true, "children": [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "title": "createApiKeysWorkflow", "path": "/references/medusa-workflows/createApiKeysWorkflow", "children": [] @@ -253,7 +255,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "title": "deleteApiKeysWorkflow", "path": "/references/medusa-workflows/deleteApiKeysWorkflow", "children": [] @@ -261,7 +263,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "title": "revokeApiKeysWorkflow", "path": "/references/medusa-workflows/revokeApiKeysWorkflow", "children": [] @@ -269,7 +271,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "title": "updateApiKeysWorkflow", "path": "/references/medusa-workflows/updateApiKeysWorkflow", "children": [] @@ -283,11 +285,12 @@ export const generatedSidebar = [ "title": "Steps", "initialOpen": false, "autogenerate_tags": "step+apiKey", + "autogenerate_as_ref": true, "children": [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "title": "createApiKeysStep", "path": "/references/medusa-workflows/steps/createApiKeysStep", "children": [] @@ -295,7 +298,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "title": "deleteApiKeysStep", "path": "/references/medusa-workflows/steps/deleteApiKeysStep", "children": [] @@ -303,7 +306,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "title": "revokeApiKeysStep", "path": "/references/medusa-workflows/steps/revokeApiKeysStep", "children": [] @@ -311,7 +314,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "title": "updateApiKeysStep", "path": "/references/medusa-workflows/steps/updateApiKeysStep", "children": [] @@ -530,11 +533,12 @@ export const generatedSidebar = [ "title": "Server Guides", "autogenerate_tags": "server+auth", "initialOpen": false, + "autogenerate_as_ref": true, "children": [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "title": "Create an Actor Type", "path": "/commerce-modules/auth/create-actor-type", "children": [] @@ -542,7 +546,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "title": "Handle Password Reset Event", "path": "/commerce-modules/auth/reset-password", "children": [] @@ -550,7 +554,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "title": "How to Create an Auth Provider Module", "path": "/references/auth/provider", "children": [] @@ -564,11 +568,12 @@ export const generatedSidebar = [ "title": "Storefront Guides", "autogenerate_tags": "storefront+auth", "initialOpen": false, + "autogenerate_as_ref": true, "children": [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "title": "Log-out Customer in Storefront", "path": "/storefront-development/customers/log-out", "children": [] @@ -576,7 +581,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "title": "Login Customer in Storefront", "path": "/storefront-development/customers/login", "children": [] @@ -584,7 +589,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "title": "Register Customer in Storefront", "path": "/storefront-development/customers/register", "children": [] @@ -592,7 +597,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "title": "Reset Customer Password in Storefront", "path": "/storefront-development/customers/reset-password", "children": [] @@ -600,7 +605,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "title": "Retrieve Customer in Storefront", "path": "/storefront-development/customers/retrieve", "children": [] @@ -608,7 +613,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "title": "Third-Party or Social Login in Storefront", "path": "/storefront-development/customers/third-party-login", "children": [] @@ -622,11 +627,12 @@ export const generatedSidebar = [ "title": "Workflows", "autogenerate_tags": "workflow+auth", "initialOpen": false, + "autogenerate_as_ref": true, "children": [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "title": "createCustomerAccountWorkflow", "path": "/references/medusa-workflows/createCustomerAccountWorkflow", "children": [] @@ -634,7 +640,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "title": "removeCustomerAccountWorkflow", "path": "/references/medusa-workflows/removeCustomerAccountWorkflow", "children": [] @@ -642,7 +648,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "title": "acceptInviteWorkflow", "path": "/references/medusa-workflows/acceptInviteWorkflow", "children": [] @@ -650,7 +656,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "title": "createUserAccountWorkflow", "path": "/references/medusa-workflows/createUserAccountWorkflow", "children": [] @@ -658,7 +664,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "title": "removeUserAccountWorkflow", "path": "/references/medusa-workflows/removeUserAccountWorkflow", "children": [] @@ -672,11 +678,12 @@ export const generatedSidebar = [ "title": "Steps", "autogenerate_tags": "step+auth", "initialOpen": false, + "autogenerate_as_ref": true, "children": [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "title": "setAuthAppMetadataStep", "path": "/references/medusa-workflows/steps/setAuthAppMetadataStep", "children": [] diff --git a/www/apps/resources/sidebars/api-key.mjs b/www/apps/resources/sidebars/api-key.mjs index 9a16bb3207641..fb153cff6a490 100644 --- a/www/apps/resources/sidebars/api-key.mjs +++ b/www/apps/resources/sidebars/api-key.mjs @@ -32,30 +32,35 @@ export const apiKeySidebar = [ title: "Storefront Guides", initialOpen: false, autogenerate_tags: "storefront+apiKey", + autogenerate_as_ref: true, }, { type: "category", title: "Admin Guides", initialOpen: false, autogenerate_tags: "admin+apiKey", + autogenerate_as_ref: true, }, { type: "category", title: "User Guides", initialOpen: false, autogenerate_tags: "userGuide+apiKey", + autogenerate_as_ref: true, }, { type: "category", title: "Workflows", initialOpen: false, autogenerate_tags: "workflow+apiKey", + autogenerate_as_ref: true, }, { type: "category", title: "Steps", initialOpen: false, autogenerate_tags: "step+apiKey", + autogenerate_as_ref: true, }, { type: "category", diff --git a/www/apps/resources/sidebars/auth.mjs b/www/apps/resources/sidebars/auth.mjs index 4f79562d8a933..780e7b2b5deb9 100644 --- a/www/apps/resources/sidebars/auth.mjs +++ b/www/apps/resources/sidebars/auth.mjs @@ -47,36 +47,42 @@ export const authSidebar = [ title: "Server Guides", autogenerate_tags: "server+auth", initialOpen: false, + autogenerate_as_ref: true, }, { type: "category", title: "Storefront Guides", autogenerate_tags: "storefront+auth", initialOpen: false, + autogenerate_as_ref: true, }, { type: "category", title: "Admin Guides", autogenerate_tags: "admin+auth", initialOpen: false, + autogenerate_as_ref: true, }, { type: "category", title: "User Guides", autogenerate_tags: "userGuides+auth", initialOpen: false, + autogenerate_as_ref: true, }, { type: "category", title: "Workflows", autogenerate_tags: "workflow+auth", initialOpen: false, + autogenerate_as_ref: true, }, { type: "category", title: "Steps", autogenerate_tags: "step+auth", initialOpen: false, + autogenerate_as_ref: true, }, { type: "category", diff --git a/www/packages/build-scripts/src/generate-sidebar.ts b/www/packages/build-scripts/src/generate-sidebar.ts index b7f924a3e5f8a..0904581f46d03 100644 --- a/www/packages/build-scripts/src/generate-sidebar.ts +++ b/www/packages/build-scripts/src/generate-sidebar.ts @@ -88,7 +88,8 @@ async function getAutogeneratedSidebarItems( } async function getAutogeneratedTagSidebarItems( - tags: string + tags: string, + type: "link" | "ref" ): Promise { const items: ItemsToAdd[] = [] @@ -98,7 +99,7 @@ async function getAutogeneratedTagSidebarItems( ...parsedTags.map( (tagItem) => ({ - type: "link", + type, ...tagItem, }) as ItemsToAdd ) @@ -130,7 +131,8 @@ async function checkItem(item: RawSidebarItem): Promise { }) } else if (item.autogenerate_tags) { item.children = await getAutogeneratedTagSidebarItems( - item.autogenerate_tags + item.autogenerate_tags, + item.autogenerate_as_ref ? "ref" : "link" ) } else if ( item.custom_autogenerate && diff --git a/www/packages/docs-ui/src/components/Breadcrumbs/index.tsx b/www/packages/docs-ui/src/components/Breadcrumbs/index.tsx index 4c5476abef5e5..e794c9f34c5ea 100644 --- a/www/packages/docs-ui/src/components/Breadcrumbs/index.tsx +++ b/www/packages/docs-ui/src/components/Breadcrumbs/index.tsx @@ -4,7 +4,12 @@ import React, { useMemo } from "react" import clsx from "clsx" import Link from "next/link" import { SidebarItemLink } from "types" -import { CurrentItemsState, useSidebar, useSiteConfig } from "../../providers" +import { + CurrentItemsState, + isSidebarItemLink, + useSidebar, + useSiteConfig, +} from "../../providers" import { Button } from "../Button" import { TriangleRightMini } from "@medusajs/icons" @@ -29,22 +34,20 @@ export const Breadcrumbs = () => { tempBreadcrumbItems = getBreadcrumbsOfItem(item.previousSidebar) } - const parentPath = - item.parentItem?.type === "link" - ? getLinkPath(item.parentItem) - : (item.parentItem?.type === "category" && - breadcrumbOptions?.showCategories) || - item.parentItem?.type === "sub-category" - ? "#" - : undefined - const firstItemPath = - item.default[0].type === "link" - ? getLinkPath(item.default[0]) - : (item.default[0].type === "category" && - breadcrumbOptions?.showCategories) || - item.default[0].type === "sub-category" - ? "#" - : undefined + const parentPath = isSidebarItemLink(item.parentItem) + ? getLinkPath(item.parentItem) + : (item.parentItem?.type === "category" && + breadcrumbOptions?.showCategories) || + item.parentItem?.type === "sub-category" + ? "#" + : undefined + const firstItemPath = isSidebarItemLink(item.default[0]) + ? getLinkPath(item.default[0]) + : (item.default[0].type === "category" && + breadcrumbOptions?.showCategories) || + item.default[0].type === "sub-category" + ? "#" + : undefined const breadcrumbPath = parentPath || firstItemPath || "/" @@ -76,7 +79,7 @@ export const Breadcrumbs = () => { breadcrumbOptions?.showCategories) ) { tempBreadcrumbItems.set( - sidebarActiveItem.parentItem.type === "link" + isSidebarItemLink(sidebarActiveItem.parentItem) ? getLinkPath(sidebarActiveItem.parentItem) || "#" : "#", sidebarActiveItem.parentItem.chapterTitle || diff --git a/www/packages/docs-ui/src/components/Sidebar/Item/index.tsx b/www/packages/docs-ui/src/components/Sidebar/Item/index.tsx index 943e08b7181b0..0072d1690b79e 100644 --- a/www/packages/docs-ui/src/components/Sidebar/Item/index.tsx +++ b/www/packages/docs-ui/src/components/Sidebar/Item/index.tsx @@ -30,6 +30,7 @@ export const SidebarItem = ({ case "sub-category": return case "link": + case "ref": return case "separator": return diff --git a/www/packages/docs-ui/src/components/Sidebar/index.tsx b/www/packages/docs-ui/src/components/Sidebar/index.tsx index e0c82fa82e01a..cdde5f23ec436 100644 --- a/www/packages/docs-ui/src/components/Sidebar/index.tsx +++ b/www/packages/docs-ui/src/components/Sidebar/index.tsx @@ -1,7 +1,7 @@ "use client" import React, { Suspense, useMemo, useRef } from "react" -import { useSidebar } from "@/providers" +import { isSidebarItemLink, useSidebar } from "@/providers" import clsx from "clsx" import { Loading } from "@/components" import { SidebarItem } from "./Item" @@ -139,7 +139,7 @@ export const Sidebar = ({ const itemKey = item.type === "separator" ? index - : item.type === "link" + : isSidebarItemLink(item) ? `${item.path}-${index}` : `${item.title}-${index}` return ( diff --git a/www/packages/docs-ui/src/hooks/use-child-docs/index.tsx b/www/packages/docs-ui/src/hooks/use-child-docs/index.tsx index f130211346716..0c677173a49c8 100644 --- a/www/packages/docs-ui/src/hooks/use-child-docs/index.tsx +++ b/www/packages/docs-ui/src/hooks/use-child-docs/index.tsx @@ -1,7 +1,16 @@ "use client" import React, { useMemo } from "react" -import { Card, CardList, H2, H3, H4, Hr, useSidebar } from "../.." +import { + Card, + CardList, + H2, + H3, + H4, + Hr, + isSidebarItemLink, + useSidebar, +} from "../.." import { InteractiveSidebarItem, SidebarItem, SidebarItemLink } from "types" import slugify from "slugify" import { MDXComponents } from "../.." @@ -61,12 +70,12 @@ export const useChildDocs = ({ switch (filterType) { case "hide": return ( - (item.type !== "link" || !hideItems.includes(item.path)) && + (!isSidebarItemLink(item) || !hideItems.includes(item.path)) && !hideItems.includes(item.title) ) case "show": return ( - (item.type === "link" && showItems!.includes(item.path)) || + (isSidebarItemLink(item) && showItems!.includes(item.path)) || showItems!.includes(item.title) ) case "all": @@ -151,16 +160,15 @@ export const useChildDocs = ({ { - const href = - childItem.type === "link" - ? childItem.path - : childItem.children?.length - ? ( - childItem.children.find( - (item) => item.type === "link" - ) as SidebarItemLink - )?.path - : "#" + const href = isSidebarItemLink(childItem) + ? childItem.path + : childItem.children?.length + ? ( + childItem.children.find((item) => + isSidebarItemLink(item) + ) as SidebarItemLink + )?.path + : "#" return { title: childItem.title, href, @@ -193,7 +201,7 @@ export const useChildDocs = ({ items={ itemChildren?.map((childItem) => ({ title: childItem.title, - href: childItem.type === "link" ? childItem.path : "", + href: isSidebarItemLink(childItem) ? childItem.path : "", })) || [] } itemsPerRow={itemsPerRow} @@ -201,7 +209,7 @@ export const useChildDocs = ({ {key !== filteredItems.length - 1 &&
} )} - {!HeadingComponent && item.type === "link" && ( + {!HeadingComponent && isSidebarItemLink(item) && ( )} diff --git a/www/packages/docs-ui/src/providers/Pagination/index.tsx b/www/packages/docs-ui/src/providers/Pagination/index.tsx index f8211b21efd31..8788edbfc6ac9 100644 --- a/www/packages/docs-ui/src/providers/Pagination/index.tsx +++ b/www/packages/docs-ui/src/providers/Pagination/index.tsx @@ -7,7 +7,7 @@ import React, { useMemo, useState, } from "react" -import { useSidebar } from "../Sidebar" +import { isSidebarItemLink, useSidebar } from "../Sidebar" import { usePrevious } from "@uidotdev/usehooks" import { InteractiveSidebarItem, SidebarItem } from "types" @@ -56,7 +56,7 @@ export const PaginationProvider = ({ children }: PaginationProviderProps) => { return undefined } - return children[0].type === "link" + return isSidebarItemLink(children[0]) ? { ...children[0], parent: item, @@ -69,7 +69,7 @@ export const PaginationProvider = ({ children }: PaginationProviderProps) => { ): SidebarItemWithParent[] | undefined => { return item.children?.filter( (childItem) => - childItem.type === "link" || + isSidebarItemLink(childItem) || (childItem.type !== "separator" && getChildrenWithPages(childItem)?.length) ) as SidebarItemWithParent[] @@ -95,7 +95,7 @@ export const PaginationProvider = ({ children }: PaginationProviderProps) => { parent: item, } } - } else if (item.type === "link") { + } else if (isSidebarItemLink(item)) { foundItem = item } @@ -115,7 +115,7 @@ export const PaginationProvider = ({ children }: PaginationProviderProps) => { return false } - if (item.type === "link") { + if (isSidebarItemLink(item)) { foundItem = item } else if (item.children?.length) { const childItem = getNextItem(item.children, -1) @@ -139,7 +139,7 @@ export const PaginationProvider = ({ children }: PaginationProviderProps) => { } result.foundActive = currentItems.some((item, index) => { - if (item.type === "link" && item.path === activePath) { + if (isSidebarItemLink(item) && item.path === activePath) { if (index !== 0) { result.prevItem = getPrevItem(currentItems, index) } @@ -161,8 +161,9 @@ export const PaginationProvider = ({ children }: PaginationProviderProps) => { result.prevItem = childrenResult.prevItem result.nextItem = childrenResult.nextItem if (!result.prevItem) { - result.prevItem = - item.type === "link" ? item : getPrevItem(currentItems, index) + result.prevItem = isSidebarItemLink(item) + ? item + : getPrevItem(currentItems, index) } if (!result.nextItem && index !== currentItems.length - 1) { @@ -186,7 +187,9 @@ export const PaginationProvider = ({ children }: PaginationProviderProps) => { result.prevItem ? { title: result.prevItem.title, - link: result.prevItem.type === "link" ? result.prevItem.path : "", + link: isSidebarItemLink(result.prevItem) + ? result.prevItem.path + : "", parentTitle: result.prevItem.parent?.type !== "separator" ? result.prevItem.parent?.title @@ -198,7 +201,9 @@ export const PaginationProvider = ({ children }: PaginationProviderProps) => { result.nextItem ? { title: result.nextItem.title, - link: result.nextItem.type === "link" ? result.nextItem.path : "", + link: isSidebarItemLink(result.nextItem) + ? result.nextItem.path + : "", parentTitle: result.nextItem.parent?.type !== "separator" ? result.nextItem.parent?.title diff --git a/www/packages/docs-ui/src/providers/Sidebar/index.tsx b/www/packages/docs-ui/src/providers/Sidebar/index.tsx index 13cae0aa2ec84..b3b7bc1e6a43d 100644 --- a/www/packages/docs-ui/src/providers/Sidebar/index.tsx +++ b/www/packages/docs-ui/src/providers/Sidebar/index.tsx @@ -95,13 +95,26 @@ export type ActionType = type LinksMap = Map +export const isSidebarItemLink = ( + item: SidebarItem | undefined, + checkRef = true +): item is SidebarItemLink => { + return ( + item !== undefined && + (item.type === "link" || (checkRef && item.type === "ref")) + ) +} + const areItemsEqual = (itemA: SidebarItem, itemB: SidebarItem): boolean => { if (itemA.type === "separator" || itemB.type === "separator") { return false } const hasSameTitle = itemA.title === itemB.title const hasSamePath = - itemA.type === "link" && itemB.type === "link" && itemA.path === itemB.path + isSidebarItemLink(itemA) && + isSidebarItemLink(itemB) && + itemA.type === itemB.type && + itemA.path === itemB.path return hasSameTitle || hasSamePath } @@ -116,8 +129,8 @@ const findItem = ( if (i.type === "separator") { return false } - if (areItemsEqual(item as SidebarItem, i) && i.type === "link") { - foundItem = i + if (areItemsEqual(item as SidebarItem, i)) { + foundItem = i as SidebarItemLink } else if (checkChildren && i.children) { foundItem = findItem(i.children, item) if (foundItem && !foundItem.parentItem) { @@ -143,7 +156,7 @@ const getLinksMap = ( return } - if (item.type === "link") { + if (isSidebarItemLink(item)) { map.set(item.path, { ...item, parentItem, @@ -246,7 +259,7 @@ export const reducer = ( : [...(i.children || []), ...items], loaded: parent.changeLoaded ? true - : i.type === "link" + : isSidebarItemLink(i) ? i.loaded : true, } @@ -355,8 +368,8 @@ export const SidebarProvider = ({ } const isLinkActive = useCallback( - (item: SidebarItem, checkChildren = false): boolean => { - if (item.type !== "link") { + (item: SidebarItem, checkChildren = false, checkRef = true): boolean => { + if (!isSidebarItemLink(item, checkRef)) { return false } @@ -399,25 +412,29 @@ export const SidebarProvider = ({ if (item.type === "separator") { return false } - if (item.isChildSidebar && isLinkActive(item)) { + if (item.isChildSidebar && isLinkActive(item, false, false)) { currentSidebar = item + return true } - - if (!currentSidebar && item.children?.length) { - const childSidebar = - getCurrentSidebar(item.children) || - (activePath - ? findItem(item.children, { - path: activePath || undefined, - type: "link", - }) - : undefined) - - if (childSidebar) { - currentSidebar = childSidebar.isChildSidebar ? childSidebar : item - } + if (!item.children?.length) { + return false } + const childSidebar = + getCurrentSidebar(item.children) || + (activePath + ? findItem(item.children, { + path: activePath, + type: "link", + }) + : undefined) + + currentSidebar = childSidebar + ? childSidebar.isChildSidebar + ? childSidebar + : item + : undefined + return currentSidebar !== undefined }) @@ -434,7 +451,7 @@ export const SidebarProvider = ({ const previousSidebar = currentItems.previousSidebar || items const backItem = previousSidebar.default.find( - (item) => item.type === "link" && !item.isChildSidebar + (item) => isSidebarItemLink(item) && !item.isChildSidebar ) as SidebarItemLink if (!backItem) { @@ -472,7 +489,7 @@ export const SidebarProvider = ({ const handleScroll = () => { if (getScrolledTop(resolvedScrollableElement) === 0) { const firstItemPath = - items.default.length && items.default[0].type === "link" + items.default.length && isSidebarItemLink(items.default[0]) ? items.default[0].path : "" setActivePath(firstItemPath) @@ -548,8 +565,8 @@ export const SidebarProvider = ({ ) { const { children, ...parentItem } = currentSidebar const hasPreviousSidebar = - currentItems?.previousSidebar?.parentItem?.type === "link" && - parentItem.type === "link" && + isSidebarItemLink(currentItems?.previousSidebar?.parentItem) && + isSidebarItemLink(parentItem) && currentItems.previousSidebar.parentItem.path !== parentItem.path setCurrentItems({ diff --git a/www/packages/tags/src/tags/index.ts b/www/packages/tags/src/tags/index.ts index 3f7ce51451a7c..209621ad05e3f 100644 --- a/www/packages/tags/src/tags/index.ts +++ b/www/packages/tags/src/tags/index.ts @@ -1,32 +1,32 @@ export * from "./auth.js" -export * from "./query.js" +export * from "./server.js" +export * from "./product.js" export * from "./cart.js" -export * from "./tax.js" -export * from "./order.js" export * from "./storefront.js" -export * from "./payment.js" -export * from "./customer.js" +export * from "./order.js" export * from "./stripe.js" export * from "./product-category.js" -export * from "./fulfillment.js" -export * from "./product-collection.js" +export * from "./pricing.js" +export * from "./payment.js" +export * from "./customer.js" +export * from "./tax.js" export * from "./inventory.js" +export * from "./query.js" +export * from "./product-collection.js" export * from "./region.js" +export * from "./fulfillment.js" export * from "./api-key.js" -export * from "./publishable-api-key.js" export * from "./step.js" -export * from "./sales-channel.js" export * from "./remote-link.js" +export * from "./event-bus.js" export * from "./remote-query.js" +export * from "./publishable-api-key.js" +export * from "./file.js" export * from "./workflow.js" -export * from "./event-bus.js" +export * from "./sales-channel.js" export * from "./promotion.js" export * from "./store.js" -export * from "./locking.js" -export * from "./file.js" export * from "./stock-location.js" +export * from "./locking.js" export * from "./logger.js" export * from "./user.js" -export * from "./pricing.js" -export * from "./server.js" -export * from "./product.js" diff --git a/www/packages/types/src/sidebar.ts b/www/packages/types/src/sidebar.ts index 043ffb193b342..86454469f6b8e 100644 --- a/www/packages/types/src/sidebar.ts +++ b/www/packages/types/src/sidebar.ts @@ -16,7 +16,7 @@ export type SidebarItemCommon = { } export type SidebarItemLink = SidebarItemCommon & { - type: "link" + type: "link" | "ref" path: string isPathHref?: boolean linkProps?: React.AllHTMLAttributes @@ -59,9 +59,18 @@ export type SidebarSectionItems = { export type RawSidebarItem = SidebarItem & { autogenerate_path?: string autogenerate_tags?: string + autogenerate_as_ref?: boolean custom_autogenerate?: string number?: string -} +} & ( + | { + type: "category" | "sub-category" | "link" | "ref" + children?: RawSidebarItem[] + } + | { + type: "separator" + } + ) export type PersistedSidebarCategoryState = { [k: string]: { From b98f8c117f8aded4eff24782d28395c0b764b08e Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Wed, 25 Dec 2024 14:16:45 +0200 Subject: [PATCH 04/21] remove examples --- .../commerce-modules/auth/examples/page.mdx | 444 ------------------ 1 file changed, 444 deletions(-) delete mode 100644 www/apps/resources/app/commerce-modules/auth/examples/page.mdx diff --git a/www/apps/resources/app/commerce-modules/auth/examples/page.mdx b/www/apps/resources/app/commerce-modules/auth/examples/page.mdx deleted file mode 100644 index cfbc6170a66d0..0000000000000 --- a/www/apps/resources/app/commerce-modules/auth/examples/page.mdx +++ /dev/null @@ -1,444 +0,0 @@ -import { CodeTabs, CodeTab } from "docs-ui" - -export const metadata = { - title: `Examples of the Auth Module`, -} - -# {metadata.title} - -In this guide, you’ll find common examples of how you can use the Auth Module in your application. - - - -You should only use the Auth Module's main service when implementing complex customizations. For common cases, check out [available workflows instead](../../../medusa-workflows-reference/page.mdx). - - - -## Authenticate User - - - -This example uses the [jsonwebtoken NPM package](https://www.npmjs.com/package/jsonwebtoken) to create the authentication token. - - - - - - -```ts collapsibleLines="1-10" expandButtonLabel="Show Imports" -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { - IAuthModuleService, - AuthenticationInput, -} from "@medusajs/framework/types" -import { Modules } from "@medusajs/framework/utils" -import { MedusaError } from "@medusajs/framework/utils" -import jwt from "jsonwebtoken" - -export async function POST( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const authModuleService = req.scope.resolve( - Modules.AUTH - ) - - const { success, authIdentity, location, error } = - await authModuleService.authenticate("emailpass", { - url: req.url, - headers: req.headers, - query: req.query, - body: req.body, - authScope: "admin", - protocol: req.protocol, - } as AuthenticationInput) - - if (!success) { - throw new MedusaError(MedusaError.Types.UNAUTHORIZED, error) - } - - if (location) { - res.json({ location }) - return - } - - const { jwtSecret } = req.scope.resolve("configModule").projectConfig.http - const token = jwt.sign(authIdentity, jwtSecret) - - res.status(200).json({ token }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeAuthModule } from "@medusajs/medusa/auth" - -export async function POST(request: Request) { - const authModuleService = await initializeAuthModule() - const url = new URL(request.url) - - const { success, authIdentity, location, error } = - await authModuleService.authenticate("emailpass", { - url: request.url, - headers: Object.fromEntries(request.headers), - query: Object.fromEntries(url.searchParams), - body: await request.json(), - authScope: "admin", - protocol: url.protocol, - } as AuthenticationInput) - - if (!success) { - throw new Error(error) - } - - if (location) { - return NextResponse.json({ location }) - } - - const token = jwt.sign(authIdentity, "supersecret") - - return NextResponse.json( - { - token, - }, - { - status: 200, - } - ) -} -``` - - - - ---- - -## Validate Callback - - - -This example uses the [jsonwebtoken NPM package](https://www.npmjs.com/package/jsonwebtoken) to create the authentication token. - - - - - - -```ts collapsibleLines="1-10" expandButtonLabel="Show Imports" -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { - IAuthModuleService, - AuthenticationInput, -} from "@medusajs/framework/types" -import { Modules } from "@medusajs/framework/utils" -import { MedusaError } from "@medusajs/framework/utils" -import jwt from "jsonwebtoken" - -export async function POST( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const authModuleService = req.scope.resolve( - Modules.AUTH - ) - - const { success, authIdentity, error, successRedirectUrl } = - await authModuleService.validateCallback("google", { - url: req.url, - headers: req.headers, - query: req.query, - body: req.body, - authScope: "admin", - protocol: req.protocol, - } as AuthenticationInput) - - if (!success) { - throw new MedusaError(MedusaError.Types.UNAUTHORIZED, error) - } - - const { jwtSecret } = req.scope.resolve("configModule").projectConfig.http - const token = jwt.sign(authIdentity, jwtSecret) - - if (successRedirectUrl) { - const url = new URL(successRedirectUrl!) - url.searchParams.append("auth_token", token) - - return res.redirect(url.toString()) - } - - res.status(200).json({ token }) -} -``` - - - - -```ts collapsibleLines="1-7" expandButtonLabel="Show Imports" -import { NextResponse } from "next/server" - -import { initialize as initializeAuthModule } from "@medusajs/medusa/auth" - -export async function POST(request: Request) { - const authModuleService = await initializeAuthModule() - const url = new URL(request.url) - - const { success, authIdentity, location, error } = - await authModuleService.authenticate("google", { - url: request.url, - headers: Object.fromEntries(request.headers), - query: Object.fromEntries(url.searchParams), - body: await request.json(), - authScope: "admin", - protocol: url.protocol, - } as AuthenticationInput) - - if (!success) { - throw new Error(error) - } - - const token = jwt.sign(authIdentity, "supersecret") - - if (successRedirectUrl) { - const url = new URL(successRedirectUrl!) - url.searchParams.append("auth_token", token) - - return NextResponse.redirect(url.toString()) - } - - return NextResponse.json( - { - token, - }, - { - status: 200, - } - ) -} -``` - - - - ---- - -## Create Auth Identity - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const authModuleService = req.scope.resolve( - Modules.AUTH - ) - - const authIdentity = await authModuleService.createAuthIdentities({ - provider: "emailpass", - entity_id: "user@example.com", - scope: "admin", - }) - - res.json({ auth_identity: authIdentity }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeAuthModule } from "@medusajs/medusa/auth" - -export async function POST(request: Request) { - const authModuleService = await initializeAuthModule() - - const authIdentity = await authModuleService.createAuthIdentities({ - provider: "emailpass", - entity_id: "user@example.com", - scope: "admin", - }) - - return NextResponse.json({ - auth_identity: authIdentity, - }) -} -``` - - - - ---- - -## List Auth Identities - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const authModuleService = req.scope.resolve( - Modules.AUTH - ) - - res.json({ - auth_identitys: await authModuleService.listAuthIdentities(), - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeAuthModule } from "@medusajs/medusa/auth" - -export async function GET(request: Request) { - const authModuleService = await initializeAuthModule() - - return NextResponse.json({ - auth_identities: await authModuleService.listAuthIdentities(), - }) -} -``` - - - - ---- - -## Update an Auth Identity - - - - - ```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const authModuleService = req.scope.resolve( - Modules.AUTH - ) - - const authIdentity = await authModuleService.updateAuthIdentites({ - id: "authusr_123", - provider_metadata: { - test: true, - }, - }) - - res.json({ - auth_identity: authIdentity, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeAuthModule } from "@medusajs/medusa/auth" - -type ContextType = { - params: { - id: string - } -} - -export async function POST(request: Request, { params }: ContextType) { - const authModuleService = await initializeAuthModule() - - const authIdentity = await authModuleService.updateAuthIdentites({ - id: "authusr_123", - provider_metadata: { - test: true, - }, - }) - - return NextResponse.json({ - auth_identity: authIdentity, - }) -} -``` - - - - ---- - -## Delete an Auth Identity - - - - - ```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function DELETE( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const authModuleService = req.scope.resolve( - Modules.AUTH - ) - - await authModuleService.deleteAuthIdentities(["authusr_123"]) - - res.status(200) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeAuthModule } from "@medusajs/medusa/auth" - -type ContextType = { - params: { - id: string - } -} - -export async function DELETE(request: Request, { params }: ContextType) { - const authModuleService = await initializeAuthModule() - - await authModuleService.deleteAuthIdentities(["authusr_123"]) -} -``` - - - - ---- - -## More Examples - -The [Auth Module's main service reference](/references/auth) provides a reference to all the methods available for use with examples for each. From 7c3c79e78cd2da55f122ff8d7a633e4cf2c910be Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Wed, 25 Dec 2024 15:29:54 +0200 Subject: [PATCH 05/21] revise cart module --- .../app/commerce-modules/api-key/page.mdx | 6 +- .../auth/create-actor-type/page.mdx | 7 - .../app/commerce-modules/auth/page.mdx | 26 + .../auth/reset-password/page.mdx | 7 - .../commerce-modules/cart/examples/page.mdx | 463 ------------------ .../app/commerce-modules/cart/page.mdx | 224 +++++---- www/apps/resources/generated/edit-dates.mjs | 15 +- www/apps/resources/generated/files-map.mjs | 8 - www/apps/resources/generated/sidebar.mjs | 356 +++++++++++++- .../page.mdx | 3 - www/apps/resources/sidebars/auth.mjs | 17 + www/apps/resources/sidebars/cart.mjs | 63 ++- .../build-scripts/src/generate-sidebar.ts | 8 +- www/packages/tags/src/tags/auth.ts | 12 - www/packages/tags/src/tags/index.ts | 31 +- www/packages/tags/src/tags/server.ts | 14 - .../merger-custom-options/auth-provider.ts | 1 - 17 files changed, 588 insertions(+), 673 deletions(-) delete mode 100644 www/apps/resources/app/commerce-modules/cart/examples/page.mdx delete mode 100644 www/packages/tags/src/tags/server.ts diff --git a/www/apps/resources/app/commerce-modules/api-key/page.mdx b/www/apps/resources/app/commerce-modules/api-key/page.mdx index 140a7d6398918..97e600d7195f6 100644 --- a/www/apps/resources/app/commerce-modules/api-key/page.mdx +++ b/www/apps/resources/app/commerce-modules/api-key/page.mdx @@ -75,7 +75,7 @@ export const createApiKeyWorkflow = createWorkflow( ) ``` -You can then execute the workflow in your cusotm API routes, scheduled jobs, or subscribers: +You can then execute the workflow in your custom API routes, scheduled jobs, or subscribers: @@ -85,7 +85,7 @@ You can then execute the workflow in your cusotm API routes, scheduled jobs, or MedusaRequest, MedusaResponse, } from "@medusajs/framework/http" - import myWorkflow from "../../workflows/create-api-key" + import createApiKeyWorkflow from "../../workflows/create-api-key" export async function GET( req: MedusaRequest, @@ -148,6 +148,8 @@ You can then execute the workflow in your cusotm API routes, scheduled jobs, or +Learn more about workflows in [this documentation](!docs!/learn/fundamentals/workflows). + --- \ No newline at end of file diff --git a/www/apps/resources/app/commerce-modules/auth/create-actor-type/page.mdx b/www/apps/resources/app/commerce-modules/auth/create-actor-type/page.mdx index 9449d4732133f..ef99fc17afb75 100644 --- a/www/apps/resources/app/commerce-modules/auth/create-actor-type/page.mdx +++ b/www/apps/resources/app/commerce-modules/auth/create-actor-type/page.mdx @@ -1,10 +1,3 @@ ---- -sidebar_label: "Create an Actor Type" -tags: - - auth - - server ---- - export const metadata = { title: `How to Create an Actor Type`, } diff --git a/www/apps/resources/app/commerce-modules/auth/page.mdx b/www/apps/resources/app/commerce-modules/auth/page.mdx index c0a95764e4a82..f1c684882499e 100644 --- a/www/apps/resources/app/commerce-modules/auth/page.mdx +++ b/www/apps/resources/app/commerce-modules/auth/page.mdx @@ -23,6 +23,8 @@ Learn more about why modules are isolated in [this documentation](!docs!/learn/f - [Authenticate Custom Actor Types](./create-actor-type/page.mdx): Create custom user or actor types, such as managers, authenticate them in your application, and guard routes based on the custom user types. - [Custom Authentication Providers](/references/auth/provider): Integrate third-party services with custom authentication providors. +--- + ## How to Use Auth Module's Service In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. @@ -89,6 +91,30 @@ export const authenticateUserWorkflow = createWorkflow( ) ``` +You can then execute the workflow in your custom API routes, scheduled jobs, or subscribers: + +```ts title="API Route" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import type { + MedusaRequest, + MedusaResponse, +} from "@medusajs/framework/http" +import authenticateUserWorkflow from "../../workflows/authenticate-user" + +export async function GET( + req: MedusaRequest, + res: MedusaResponse +) { + const { result } = await authenticateUserWorkflow(req.scope) + .run({ + req + }) + + res.send(result) +} +``` + +Learn more about workflows in [this documentation](!docs!/learn/fundamentals/workflows). + --- ## Configure Auth Module diff --git a/www/apps/resources/app/commerce-modules/auth/reset-password/page.mdx b/www/apps/resources/app/commerce-modules/auth/reset-password/page.mdx index cbb342f523879..632e3fb4a6dda 100644 --- a/www/apps/resources/app/commerce-modules/auth/reset-password/page.mdx +++ b/www/apps/resources/app/commerce-modules/auth/reset-password/page.mdx @@ -1,10 +1,3 @@ ---- -sidebar_label: "Handle Password Reset Event" -tags: - - auth - - server ---- - import { Prerequisites } from "docs-ui" export const metadata = { diff --git a/www/apps/resources/app/commerce-modules/cart/examples/page.mdx b/www/apps/resources/app/commerce-modules/cart/examples/page.mdx deleted file mode 100644 index 17c296bf869db..0000000000000 --- a/www/apps/resources/app/commerce-modules/cart/examples/page.mdx +++ /dev/null @@ -1,463 +0,0 @@ -import { CodeTabs, CodeTab } from "docs-ui" - -export const metadata = { - title: `Examples of the Cart Module`, -} - -# {metadata.title} - -In this guide, you’ll find common examples of how you can use the Cart Module in your application. - - - -You should only use the Cart Module's main service when implementing complex customizations. For common cases, check out [available workflows instead](../../../medusa-workflows-reference/page.mdx). - - - -## Create a Cart - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const cartModuleService = req.scope.resolve( - Modules.CART - ) - - const cart = await cartModuleService.createCarts({ - currency_code: "usd", - shipping_address: { - address_1: "1512 Barataria Blvd", - country_code: "us", - }, - items: [ - { - title: "Shirt", - unit_price: 1000, - quantity: 1, - }, - ], - }) - - res.json({ cart }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeCartModule } from "@medusajs/medusa/cart" - -export async function POST(request: Request) { - const cartModuleService = await initializeCartModule() - - const cart = await cartModuleService.createCarts({ - currency_code: "usd", - shipping_address: { - address_1: "1512 Barataria Blvd", - country_code: "us", - }, - items: [ - { - title: "Shirt", - unit_price: 1000, - quantity: 1, - }, - ], - }) - - return NextResponse.json({ - cart, - }) -} -``` - - - - ---- - -## Retrieve Cart by ID - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const cartModuleService = req.scope.resolve( - Modules.CART - ) - - const cart = await cartModuleService.retrieveCart("cart_123") - - res.json({ cart }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeCartModule } from "@medusajs/medusa/cart" - -export async function GET(request: Request) { - const cartModuleService = await initializeCartModule() - - const cart = await cartModuleService.retrieveCart("cart_123") - - return NextResponse.json({ - cart, - }) -} -``` - - - - ---- - -## Add Item to Cart - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const cartModuleService = req.scope.resolve( - Modules.CART - ) - - const lineItem = await cartModuleService.addLineItems({ - cart_id: "cart_123", - title: "Shirt", - quantity: 2, - unit_price: 5000, - }) - - res.json({ - line_item: lineItem, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeCartModule } from "@medusajs/medusa/cart" - -export async function POST(request: Request) { - const cartModuleService = await initializeCartModule() - - const lineItem = await cartModuleService.addLineItems({ - cart_id: "cart_123", - title: "Shirt", - quantity: 2, - unit_price: 5000, - }) - - return NextResponse.json({ - line_item: lineItem, - }) -} -``` - - - - ---- - -## Add Shipping Method to Cart - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const cartModuleService = req.scope.resolve( - Modules.CART - ) - - const shippingMethod = await cartModuleService.addShippingMethods({ - cart_id: "cart_123", - name: "Custom shipping", - amount: 1000, - }) - - res.json({ - shipping_method: shippingMethod, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeCartModule } from "@medusajs/medusa/cart" - -export async function POST(request: Request) { - const cartModuleService = await initializeCartModule() - - const shippingMethod = await cartModuleService.addShippingMethods({ - cart_id: "cart_123", - name: "Custom shipping", - amount: 1000, - }) - - return NextResponse.json({ - shipping_method: shippingMethod, - }) -} -``` - - - - ---- - -## Add Item Adjustment Line - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const cartModuleService = req.scope.resolve( - Modules.CART - ) - - const itemAdjustment = await cartModuleService.addLineItemAdjustments({ - item_id: "cali_123", - amount: 500, - code: "50%OFF", - }) - - res.json({ - adjustment: itemAdjustment, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeCartModule } from "@medusajs/medusa/cart" - -export async function POST(request: Request) { - const cartModuleService = await initializeCartModule() - - const itemAdjustment = await cartModuleService.addLineItemAdjustments({ - item_id: "cali_123", - amount: 500, - code: "50%OFF", - }) - - return NextResponse.json({ - adjustment: itemAdjustment, - }) -} -``` - - - - ---- - -## Add Shipping Method Adjustment Line - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const cartModuleService = req.scope.resolve( - Modules.CART - ) - - const shippingMethodAdjustment = - await cartModuleService.addShippingMethodAdjustments({ - shipping_method_id: "casm_123", - amount: 500, - code: "FREESHIPPING", - }) - - res.json({ - adjustment: shippingMethodAdjustment, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeCartModule } from "@medusajs/medusa/cart" - -export async function POST(request: Request) { - const cartModuleService = await initializeCartModule() - - const shippingMethodAdjustment = - await cartModuleService.addShippingMethodAdjustments({ - shipping_method_id: "casm_123", - amount: 500, - code: "FREESHIPPING", - }) - - return NextResponse.json({ - adjustment: shippingMethodAdjustment, - }) -} -``` - - - - ---- - -## Remove Line Item from Cart - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function DELETE( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const cartModuleService = req.scope.resolve( - Modules.CART - ) - - await cartModuleService.deleteLineItems(["cali_123"]) - - res.status(200) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeCartModule } from "@medusajs/medusa/cart" - -export async function DELETE(request: Request) { - const cartModuleService = await initializeCartModule() - - await cartModuleService.deleteLineItems(["cali_123"]) -} -``` - - - - ---- - -## Remove Shipping Method from Cart - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function DELETE( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const cartModuleService = req.scope.resolve( - Modules.CART - ) - - await cartModuleService.deleteShippingMethods(["casm_123"]) - - res.status(200) -} -``` - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function DELETE( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const cartModuleService = req.scope.resolve( - Modules.CART - ) - - await cartModuleService.deleteShippingMethods(["casm_123"]) - - res.status(200) -} -``` - - - - ---- - -## More Examples - -The [Cart Module's main service reference](/references/cart) provides a reference to all the methods available for use with examples for each. diff --git a/www/apps/resources/app/commerce-modules/cart/page.mdx b/www/apps/resources/app/commerce-modules/cart/page.mdx index 4c90a550a302a..2dd4b094a25ff 100644 --- a/www/apps/resources/app/commerce-modules/cart/page.mdx +++ b/www/apps/resources/app/commerce-modules/cart/page.mdx @@ -6,120 +6,158 @@ export const metadata = { # {metadata.title} -The Cart Module provides cart-related features in your Medusa and Node.js applications. +In this section of the documentation, you will find resources to learn more about the Cart Module and how to use it in your application. -## How to Use Cart Module's Service +Medusa has cart related features available out-of-the-box through the Cart Module. A [module](!docs!/learn/fundamentals/modules) is a standalone package that provides features for a single domain. Each of Medusa's commerce features are placed in commerce modules, such as this Cart Module. -You can use the Cart Module's main service by resolving from the Medusa container the resource `Modules.CART`. + -For example: +Learn more about why modules are isolated in [this documentation](!docs!/learn/fundamentals/modules/isolation). - - + -```ts title="src/workflows/hello-world/step1.ts" -import { createStep } from "@medusajs/framework/workflows-sdk" -import { Modules } from "@medusajs/framework/utils" +## Cart Features -const step1 = createStep("step-1", async (_, { container }) => { - const cartModuleService = container.resolve( - Modules.CART - ) +- [Cart Management](./concepts/page.mdx): Store and manage carts, including their addresses, line items, shipping methods, and more. +- [Apply Promotion Adjustments](./promotions/page.mdx): Apply promotions or discounts to line items and shipping methods by adding adjustment lines that are factored into their subtotals. +- [Apply Tax Lines](./tax-lines/page.mdx): Apply tax lines to line items and shipping methods. +- [Cart Scoping](./links-to-other-modules/page.mdx): When used in the Medusa application, Medusa creates links to other commerce modules, scoping a cart to a sales channel, region, and a customer. - const carts = await cartModuleService.listCarts() -}) -``` +--- - - +## How to Use Cart Module's Service -```ts title="src/api/store/custom/route.ts" -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" +In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. -export async function GET( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const cartModuleService = req.scope.resolve( - Modules.CART - ) - - res.json({ - carts: await cartModuleService.listCarts(), - }) -} -``` +You can build custom workflows and steps. You can also re-use Medusa's workflows and steps, which are provided by the `@medusajs/medusa/core-flows` package. - - +For example: -```ts title="src/subscribers/custom-handler.ts" -import { SubscriberArgs } from "@medusajs/framework" +```ts title="src/workflows/create-cart.ts" +import { + createWorkflow, + WorkflowResponse, + createStep, + StepResponse, +} from "@medusajs/framework/workflows-sdk" import { Modules } from "@medusajs/framework/utils" -export default async function subscriberHandler({ container }: SubscriberArgs) { - const cartModuleService = container.resolve( - Modules.CART - ) - - const carts = await cartModuleService.listCarts() -} -``` - - - - ---- - -## Features - -### Cart Management - -Store and manage carts, including their addresses, line items, shipping methods, and more. - -```ts -const cart = await cartModuleService.createCarts({ - currency_code: "usd", - shipping_address: { - address_1: "1512 Barataria Blvd", - country_code: "us", +const createCartStep = createStep( + "create-cart", + async ({}, { container }) => { + const cartModuleService = container.resolve(Modules.CART) + + const cart = await cartModuleService.createCarts({ + currency_code: "usd", + shipping_address: { + address_1: "1512 Barataria Blvd", + country_code: "us", + }, + items: [ + { + title: "Shirt", + unit_price: 1000, + quantity: 1, + }, + ], + }) + + return new StepResponse({ cart }, cart.id) }, - items: [ - { - title: "Shirt", - unit_price: 1000, - quantity: 1, - }, - ], -}) + async (cartId, { container }) => { + const cartModuleService = container.resolve(Modules.CART) + + await cartModuleService.deleteCarts([cartId]) + } +) + +export const createCartWorkflow = createWorkflow( + "create-cart", + () => { + const cart = createCartStep() + + return new WorkflowResponse({ + cart, + }) + } +) ``` -### Apply Promotions +You can then execute the workflow in your custom API routes, scheduled jobs, or subscribers: -Apply promotions or discounts to line items and shipping methods by adding adjustment lines that are factored into their subtotals. + + + + ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import type { + MedusaRequest, + MedusaResponse, + } from "@medusajs/framework/http" + import createCartWorkflow from "../../workflows/create-workflow" + + export async function GET( + req: MedusaRequest, + res: MedusaResponse + ) { + const { result } = await createCartWorkflow(req.scope) + .run() + + res.send(result) + } + ``` -```ts -const lineAdjustments = await cartModuleService.addLineItemAdjustments({ - item_id: "cali_123", - code: "50OFF", - amount: 500, -}) + + + + ```ts title="src/subscribers/customer-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import { + type SubscriberConfig, + type SubscriberArgs, + } from "@medusajs/framework" + import createCartWorkflow from "../workflows/create-workflow" + + export default async function handleCustomerCreate({ + event: { data }, + container, + }: SubscriberArgs<{ id: string }>) { + const { result } = await createCartWorkflow(container) + .run() + + console.log(result) + } + + export const config: SubscriberConfig = { + event: "user.created", + } + ``` -const shippingAdjustments = - await cartModuleService.addShippingMethodAdjustments({ - shipping_method_id: "casm_123", - code: "FREESHIPPING", - amount: 1000, - }) -``` + + + + ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} + import { MedusaContainer } from "@medusajs/framework/types" + import createCartWorkflow from "../workflows/create-workflow" + + export default async function myCustomJob( + container: MedusaContainer + ) { + const { result } = await createCartWorkflow(container) + .run() + + console.log(result.message) + } + + export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, + }; + ``` -### Cart Context and Scoping + + -A cart is scoped to a sales channel, region, and a customer. +Learn more about workflows in [this documentation](!docs!/learn/fundamentals/workflows). -The Medusa application links the Cart Module to each of their respective modules, providing features like: +--- -- Checking product availability in a sales channel. -- Retrieving pricing per region. -- Applying promotions based on the customer's group. + \ No newline at end of file diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index 2751648d19776..b3a6be0aca471 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -4,14 +4,13 @@ export const generatedEditDates = { "app/commerce-modules/auth/authentication-route/page.mdx": "2024-09-05T12:06:38.155Z", "app/commerce-modules/auth/examples/page.mdx": "2024-10-15T15:02:13.794Z", "app/commerce-modules/auth/module-options/page.mdx": "2024-10-15T12:52:08.930Z", - "app/commerce-modules/auth/page.mdx": "2024-12-25T11:16:19.608Z", + "app/commerce-modules/auth/page.mdx": "2024-12-25T12:42:47.543Z", "app/commerce-modules/cart/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/cart/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/cart/concepts/page.mdx": "2024-10-08T07:49:03.737Z", - "app/commerce-modules/cart/examples/page.mdx": "2024-10-15T14:59:11.331Z", "app/commerce-modules/cart/promotions/page.mdx": "2024-10-08T07:54:31.120Z", "app/commerce-modules/cart/tax-lines/page.mdx": "2024-10-08T07:57:19.168Z", - "app/commerce-modules/cart/page.mdx": "2024-12-09T14:47:07.204Z", + "app/commerce-modules/cart/page.mdx": "2024-12-25T12:48:02.661Z", "app/commerce-modules/currency/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/currency/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/currency/examples/page.mdx": "2024-10-15T14:59:18.466Z", @@ -209,8 +208,8 @@ export const generatedEditDates = { "app/commerce-modules/auth/auth-flows/page.mdx": "2024-09-05T08:50:11.671Z", "app/commerce-modules/auth/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/auth/auth-identity-and-actor-types/page.mdx": "2024-12-09T13:04:01.129Z", - "app/commerce-modules/api-key/page.mdx": "2024-12-25T09:22:23.514Z", - "app/commerce-modules/auth/create-actor-type/page.mdx": "2024-12-25T11:06:44.228Z", + "app/commerce-modules/api-key/page.mdx": "2024-12-25T12:42:50.276Z", + "app/commerce-modules/auth/create-actor-type/page.mdx": "2024-12-25T13:26:27.176Z", "app/architectural-modules/page.mdx": "2024-12-11T10:33:53.064Z", "app/architectural-modules/workflow-engine/redis/page.mdx": "2024-10-15T12:50:59.507Z", "app/architectural-modules/notification/sendgrid/page.mdx": "2024-10-15T12:51:25.569Z", @@ -885,7 +884,7 @@ export const generatedEditDates = { "references/auth/IAuthModuleService/methods/auth.IAuthModuleService.authenticate/page.mdx": "2024-12-10T14:54:57.312Z", "references/auth/IAuthModuleService/methods/auth.IAuthModuleService.validateCallback/page.mdx": "2024-12-10T14:54:57.318Z", "references/auth/interfaces/auth.AuthenticationResponse/page.mdx": "2024-12-09T13:21:36.233Z", - "references/auth_provider/classes/auth_provider.AbstractAuthModuleProvider/page.mdx": "2024-12-25T11:08:55.949Z", + "references/auth_provider/classes/auth_provider.AbstractAuthModuleProvider/page.mdx": "2024-12-25T13:27:05.376Z", "references/core_flows/Invite/Workflows_Invite/functions/core_flows.Invite.Workflows_Invite.refreshInviteTokensWorkflow/page.mdx": "2024-12-25T08:43:13.811Z", "references/types/CommonTypes/types/types.CommonTypes.BatchMethodResponse/page.mdx": "2024-12-09T13:21:32.849Z", "references/types/HttpTypes/interfaces/types.HttpTypes.AdminAddReturnShipping/page.mdx": "2024-12-09T13:21:34.545Z", @@ -2145,10 +2144,10 @@ export const generatedEditDates = { "app/admin-components/layouts/single-column/page.mdx": "2024-10-07T11:16:06.435Z", "app/admin-components/layouts/two-column/page.mdx": "2024-10-07T11:16:10.092Z", "app/admin-components/components/forms/page.mdx": "2024-10-09T12:48:04.229Z", - "app/commerce-modules/auth/reset-password/page.mdx": "2024-12-25T11:17:12.203Z", + "app/commerce-modules/auth/reset-password/page.mdx": "2024-12-25T13:26:32.595Z", "app/storefront-development/customers/reset-password/page.mdx": "2024-12-19T16:32:00.724Z", "app/commerce-modules/api-key/links-to-other-modules/page.mdx": "2024-12-24T14:36:06.109Z", - "app/commerce-modules/cart/extend/page.mdx": "2024-12-11T09:05:37.041Z", + "app/commerce-modules/cart/extend/page.mdx": "2024-12-25T12:48:59.149Z", "app/commerce-modules/cart/links-to-other-modules/page.mdx": "2024-12-24T14:46:49.847Z", "app/commerce-modules/customer/extend/page.mdx": "2024-12-16T14:11:47.517Z", "app/commerce-modules/fulfillment/links-to-other-modules/page.mdx": "2024-12-24T14:49:54.535Z", diff --git a/www/apps/resources/generated/files-map.mjs b/www/apps/resources/generated/files-map.mjs index 588d28735eb24..80b8a018e889c 100644 --- a/www/apps/resources/generated/files-map.mjs +++ b/www/apps/resources/generated/files-map.mjs @@ -175,10 +175,6 @@ export const filesMap = [ "filePath": "/www/apps/resources/app/commerce-modules/auth/events/page.mdx", "pathname": "/commerce-modules/auth/events" }, - { - "filePath": "/www/apps/resources/app/commerce-modules/auth/examples/page.mdx", - "pathname": "/commerce-modules/auth/examples" - }, { "filePath": "/www/apps/resources/app/commerce-modules/auth/module-options/page.mdx", "pathname": "/commerce-modules/auth/module-options" @@ -199,10 +195,6 @@ export const filesMap = [ "filePath": "/www/apps/resources/app/commerce-modules/cart/events/page.mdx", "pathname": "/commerce-modules/cart/events" }, - { - "filePath": "/www/apps/resources/app/commerce-modules/cart/examples/page.mdx", - "pathname": "/commerce-modules/cart/examples" - }, { "filePath": "/www/apps/resources/app/commerce-modules/cart/extend/page.mdx", "pathname": "/commerce-modules/cart/extend" diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs index 56f802c4d1d14..4ea79f462923d 100644 --- a/www/apps/resources/generated/sidebar.mjs +++ b/www/apps/resources/generated/sidebar.mjs @@ -538,25 +538,25 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "ref", - "title": "Create an Actor Type", + "type": "link", "path": "/commerce-modules/auth/create-actor-type", + "title": "Create an Actor Type", "children": [] }, { "loaded": true, "isPathHref": true, - "type": "ref", - "title": "Handle Password Reset Event", + "type": "link", "path": "/commerce-modules/auth/reset-password", + "title": "Handle Password Reset Event", "children": [] }, { "loaded": true, "isPathHref": true, - "type": "ref", - "title": "How to Create an Auth Provider Module", + "type": "link", "path": "/references/auth/provider", + "title": "Create Auth Provider Module", "children": [] } ] @@ -944,23 +944,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "link", - "path": "/commerce-modules/cart/examples", - "title": "Examples", - "children": [] - }, - { - "loaded": true, - "isPathHref": true, - "type": "link", - "path": "/commerce-modules/cart/extend", - "title": "Extend Module", - "children": [] - }, - { - "loaded": true, - "isPathHref": true, - "type": "sub-category", + "type": "category", "title": "Concepts", "children": [ { @@ -1000,7 +984,331 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", + "title": "Server Guides", + "autogenerate_tags": "server+cart", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "link", + "path": "/commerce-modules/cart/extend", + "title": "Extend Module", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Storefront Guides", + "autogenerate_tags": "storefront+cart", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Create Cart Context in Storefront", + "path": "/storefront-development/cart/context", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Create Cart in Storefront", + "path": "/storefront-development/cart/create", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Manage Cart's Items in Storefront", + "path": "/storefront-development/cart/manage-items", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Retrieve Cart in Storefront", + "path": "/storefront-development/cart/retrieve", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Update Cart in Storefront", + "path": "/storefront-development/cart/update", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Checkout Step 2: Enter Address", + "path": "/storefront-development/checkout/address", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Checkout Step 5: Complete Cart", + "path": "/storefront-development/checkout/complete-cart", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Checkout Step 1: Enter Email", + "path": "/storefront-development/checkout/email", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Checkout Step 4: Choose Payment Provider", + "path": "/storefront-development/checkout/payment", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Payment with Stripe in React Storefront", + "path": "/storefront-development/checkout/payment/stripe", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Checkout Step 3: Choose Shipping Method", + "path": "/storefront-development/checkout/shipping", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Workflows", + "autogenerate_tags": "workflow+cart", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "addShippingMethodToCartWorkflow", + "path": "/references/medusa-workflows/addShippingMethodToCartWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "addToCartWorkflow", + "path": "/references/medusa-workflows/addToCartWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createCartWorkflow", + "path": "/references/medusa-workflows/createCartWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "transferCartCustomerWorkflow", + "path": "/references/medusa-workflows/transferCartCustomerWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateCartPromotionsWorkflow", + "path": "/references/medusa-workflows/updateCartPromotionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateCartWorkflow", + "path": "/references/medusa-workflows/updateCartWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateLineItemInCartWorkflow", + "path": "/references/medusa-workflows/updateLineItemInCartWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateTaxLinesWorkflow", + "path": "/references/medusa-workflows/updateTaxLinesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteLineItemsWorkflow", + "path": "/references/medusa-workflows/deleteLineItemsWorkflow", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Steps", + "autogenerate_tags": "step+cart", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "addShippingMethodToCartStep", + "path": "/references/medusa-workflows/steps/addShippingMethodToCartStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createCartsStep", + "path": "/references/medusa-workflows/steps/createCartsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createLineItemAdjustmentsStep", + "path": "/references/medusa-workflows/steps/createLineItemAdjustmentsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createLineItemsStep", + "path": "/references/medusa-workflows/steps/createLineItemsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createShippingMethodAdjustmentsStep", + "path": "/references/medusa-workflows/steps/createShippingMethodAdjustmentsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "getLineItemActionsStep", + "path": "/references/medusa-workflows/steps/getLineItemActionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "removeLineItemAdjustmentsStep", + "path": "/references/medusa-workflows/steps/removeLineItemAdjustmentsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "removeShippingMethodAdjustmentsStep", + "path": "/references/medusa-workflows/steps/removeShippingMethodAdjustmentsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "removeShippingMethodFromCartStep", + "path": "/references/medusa-workflows/steps/removeShippingMethodFromCartStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "setTaxLinesForItemsStep", + "path": "/references/medusa-workflows/steps/setTaxLinesForItemsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateCartsStep", + "path": "/references/medusa-workflows/steps/updateCartsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateLineItemsStep", + "path": "/references/medusa-workflows/steps/updateLineItemsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteLineItemsStep", + "path": "/references/medusa-workflows/steps/deleteLineItemsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateLineItemsStepWithSelector", + "path": "/references/medusa-workflows/steps/updateLineItemsStepWithSelector", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", "title": "References", "children": [ { diff --git a/www/apps/resources/references/auth_provider/classes/auth_provider.AbstractAuthModuleProvider/page.mdx b/www/apps/resources/references/auth_provider/classes/auth_provider.AbstractAuthModuleProvider/page.mdx index b2c26dfd21494..292f17ace60af 100644 --- a/www/apps/resources/references/auth_provider/classes/auth_provider.AbstractAuthModuleProvider/page.mdx +++ b/www/apps/resources/references/auth_provider/classes/auth_provider.AbstractAuthModuleProvider/page.mdx @@ -1,8 +1,5 @@ --- slug: /references/auth/provider -tags: - - auth - - server --- import { TypeList } from "docs-ui" diff --git a/www/apps/resources/sidebars/auth.mjs b/www/apps/resources/sidebars/auth.mjs index 780e7b2b5deb9..29eba23cd8f46 100644 --- a/www/apps/resources/sidebars/auth.mjs +++ b/www/apps/resources/sidebars/auth.mjs @@ -48,6 +48,23 @@ export const authSidebar = [ autogenerate_tags: "server+auth", initialOpen: false, autogenerate_as_ref: true, + children: [ + { + type: "link", + path: "/commerce-modules/auth/create-actor-type", + title: "Create an Actor Type", + }, + { + type: "link", + path: "/commerce-modules/auth/reset-password", + title: "Handle Password Reset Event", + }, + { + type: "link", + path: "/references/auth/provider", + title: "Create Auth Provider Module", + }, + ], }, { type: "category", diff --git a/www/apps/resources/sidebars/cart.mjs b/www/apps/resources/sidebars/cart.mjs index b017109d514c6..8b07653b74550 100644 --- a/www/apps/resources/sidebars/cart.mjs +++ b/www/apps/resources/sidebars/cart.mjs @@ -11,17 +11,7 @@ export const cartSidebar = [ title: "Overview", }, { - type: "link", - path: "/commerce-modules/cart/examples", - title: "Examples", - }, - { - type: "link", - path: "/commerce-modules/cart/extend", - title: "Extend Module", - }, - { - type: "sub-category", + type: "category", title: "Concepts", children: [ { @@ -47,7 +37,56 @@ export const cartSidebar = [ ], }, { - type: "sub-category", + type: "category", + title: "Server Guides", + autogenerate_tags: "server+cart", + initialOpen: false, + autogenerate_as_ref: true, + children: [ + { + type: "link", + path: "/commerce-modules/cart/extend", + title: "Extend Module", + }, + ], + }, + { + type: "category", + title: "Storefront Guides", + autogenerate_tags: "storefront+cart", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Admin Guides", + autogenerate_tags: "admin+cart", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "User Guides", + autogenerate_tags: "userGuides+cart", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Workflows", + autogenerate_tags: "workflow+cart", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Steps", + autogenerate_tags: "step+cart", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", title: "References", children: [ { diff --git a/www/packages/build-scripts/src/generate-sidebar.ts b/www/packages/build-scripts/src/generate-sidebar.ts index 0904581f46d03..a958a59803f0a 100644 --- a/www/packages/build-scripts/src/generate-sidebar.ts +++ b/www/packages/build-scripts/src/generate-sidebar.ts @@ -89,7 +89,8 @@ async function getAutogeneratedSidebarItems( async function getAutogeneratedTagSidebarItems( tags: string, - type: "link" | "ref" + type: "link" | "ref", + existingChildren?: RawSidebarItem[] ): Promise { const items: ItemsToAdd[] = [] @@ -105,7 +106,7 @@ async function getAutogeneratedTagSidebarItems( ) ) - return sidebarAttachHrefCommonOptions(items) + return sidebarAttachHrefCommonOptions([...(existingChildren || []), ...items]) } async function checkItem(item: RawSidebarItem): Promise { @@ -132,7 +133,8 @@ async function checkItem(item: RawSidebarItem): Promise { } else if (item.autogenerate_tags) { item.children = await getAutogeneratedTagSidebarItems( item.autogenerate_tags, - item.autogenerate_as_ref ? "ref" : "link" + item.autogenerate_as_ref ? "ref" : "link", + item.children ) } else if ( item.custom_autogenerate && diff --git a/www/packages/tags/src/tags/auth.ts b/www/packages/tags/src/tags/auth.ts index c508f122f6aba..c86c4eeb450b5 100644 --- a/www/packages/tags/src/tags/auth.ts +++ b/www/packages/tags/src/tags/auth.ts @@ -1,12 +1,4 @@ export const auth = [ - { - "title": "Create an Actor Type", - "path": "/commerce-modules/auth/create-actor-type" - }, - { - "title": "Handle Password Reset Event", - "path": "/commerce-modules/auth/reset-password" - }, { "title": "Log-out Customer in Storefront", "path": "/storefront-development/customers/log-out" @@ -31,10 +23,6 @@ export const auth = [ "title": "Third-Party or Social Login in Storefront", "path": "/storefront-development/customers/third-party-login" }, - { - "title": "How to Create an Auth Provider Module", - "path": "/references/auth/provider" - }, { "title": "setAuthAppMetadataStep", "path": "/references/medusa-workflows/steps/setAuthAppMetadataStep" diff --git a/www/packages/tags/src/tags/index.ts b/www/packages/tags/src/tags/index.ts index 209621ad05e3f..e31642ae036b5 100644 --- a/www/packages/tags/src/tags/index.ts +++ b/www/packages/tags/src/tags/index.ts @@ -1,32 +1,31 @@ -export * from "./auth.js" -export * from "./server.js" export * from "./product.js" export * from "./cart.js" export * from "./storefront.js" export * from "./order.js" export * from "./stripe.js" -export * from "./product-category.js" -export * from "./pricing.js" export * from "./payment.js" export * from "./customer.js" +export * from "./fulfillment.js" +export * from "./auth.js" +export * from "./product-category.js" +export * from "./product-collection.js" export * from "./tax.js" export * from "./inventory.js" -export * from "./query.js" -export * from "./product-collection.js" +export * from "./remote-link.js" export * from "./region.js" -export * from "./fulfillment.js" -export * from "./api-key.js" export * from "./step.js" -export * from "./remote-link.js" +export * from "./api-key.js" +export * from "./sales-channel.js" +export * from "./workflow.js" export * from "./event-bus.js" +export * from "./store.js" export * from "./remote-query.js" -export * from "./publishable-api-key.js" -export * from "./file.js" -export * from "./workflow.js" -export * from "./sales-channel.js" export * from "./promotion.js" -export * from "./store.js" -export * from "./stock-location.js" +export * from "./user.js" +export * from "./file.js" export * from "./locking.js" +export * from "./stock-location.js" +export * from "./pricing.js" export * from "./logger.js" -export * from "./user.js" +export * from "./publishable-api-key.js" +export * from "./query.js" diff --git a/www/packages/tags/src/tags/server.ts b/www/packages/tags/src/tags/server.ts deleted file mode 100644 index 5c65e12e37edd..0000000000000 --- a/www/packages/tags/src/tags/server.ts +++ /dev/null @@ -1,14 +0,0 @@ -export const server = [ - { - "title": "Create an Actor Type", - "path": "/commerce-modules/auth/create-actor-type" - }, - { - "title": "Handle Password Reset Event", - "path": "/commerce-modules/auth/reset-password" - }, - { - "title": "How to Create an Auth Provider Module", - "path": "/references/auth/provider" - } -] \ No newline at end of file diff --git a/www/utils/packages/typedoc-generate-references/src/constants/merger-custom-options/auth-provider.ts b/www/utils/packages/typedoc-generate-references/src/constants/merger-custom-options/auth-provider.ts index 30c41453e81a4..c723bf4b8b0c3 100644 --- a/www/utils/packages/typedoc-generate-references/src/constants/merger-custom-options/auth-provider.ts +++ b/www/utils/packages/typedoc-generate-references/src/constants/merger-custom-options/auth-provider.ts @@ -9,7 +9,6 @@ const authProviderOptions: FormattingOptionsType = { reflectionDescription: `In this document, you’ll learn how to create an auth provider module and the methods you must implement in its main service.`, frontmatterData: { slug: "/references/auth/provider", - tags: ["auth", "server"], }, reflectionTitle: { fullReplacement: "How to Create an Auth Provider Module", From 02f8a63c34cfcfc3c65887a4a97049e1d25789fc Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Wed, 25 Dec 2024 15:49:10 +0200 Subject: [PATCH 06/21] revise currency --- .../app/commerce-modules/api-key/page.mdx | 7 +- .../app/commerce-modules/auth/page.mdx | 6 +- .../app/commerce-modules/cart/page.mdx | 6 +- .../currency/examples/page.mdx | 111 ---------- .../app/commerce-modules/currency/page.mdx | 196 ++++++++++++------ .../CommerceModuleSections/index.tsx | 23 +- www/apps/resources/generated/edit-dates.mjs | 9 +- www/apps/resources/generated/files-map.mjs | 4 - www/apps/resources/generated/sidebar.mjs | 10 +- www/apps/resources/sidebars/currency.mjs | 49 ++++- www/packages/tags/src/tags/index.ts | 32 +-- 11 files changed, 227 insertions(+), 226 deletions(-) delete mode 100644 www/apps/resources/app/commerce-modules/currency/examples/page.mdx diff --git a/www/apps/resources/app/commerce-modules/api-key/page.mdx b/www/apps/resources/app/commerce-modules/api-key/page.mdx index 97e600d7195f6..6b18207680a0b 100644 --- a/www/apps/resources/app/commerce-modules/api-key/page.mdx +++ b/www/apps/resources/app/commerce-modules/api-key/page.mdx @@ -33,7 +33,11 @@ You can build custom workflows and steps. You can also re-use Medusa's workflows For example: -```ts title="src/workflows/create-api-key.ts" +export const highlights = [ + ["12", "Modules.API_KEY", "Resolve the module in a step."] +] + +```ts title="src/workflows/create-api-key.ts" highlights={highlights} import { createWorkflow, WorkflowResponse, @@ -42,7 +46,6 @@ import { } from "@medusajs/framework/workflows-sdk" import { Modules } from "@medusajs/framework/utils" - const createApiKeyStep = createStep( "create-api-key", async ({}, { container }) => { diff --git a/www/apps/resources/app/commerce-modules/auth/page.mdx b/www/apps/resources/app/commerce-modules/auth/page.mdx index f1c684882499e..08a84259b89d0 100644 --- a/www/apps/resources/app/commerce-modules/auth/page.mdx +++ b/www/apps/resources/app/commerce-modules/auth/page.mdx @@ -33,7 +33,11 @@ You can build custom workflows and steps. You can also re-use Medusa's workflows For example: -```ts title="src/workflows/authenticate-user.ts" +export const highlights = [ + ["17", "Modules.AUTH", "Resolve the module in a step."] +] + +```ts title="src/workflows/authenticate-user.ts" highlights={highlights} import { createWorkflow, WorkflowResponse, diff --git a/www/apps/resources/app/commerce-modules/cart/page.mdx b/www/apps/resources/app/commerce-modules/cart/page.mdx index 2dd4b094a25ff..cee6f9c747403 100644 --- a/www/apps/resources/app/commerce-modules/cart/page.mdx +++ b/www/apps/resources/app/commerce-modules/cart/page.mdx @@ -33,7 +33,11 @@ You can build custom workflows and steps. You can also re-use Medusa's workflows For example: -```ts title="src/workflows/create-cart.ts" +export const highlights = [ + ["12", "Modules.CART", "Resolve the module in a step."] +] + +```ts title="src/workflows/create-cart.ts" highlights={highlights} import { createWorkflow, WorkflowResponse, diff --git a/www/apps/resources/app/commerce-modules/currency/examples/page.mdx b/www/apps/resources/app/commerce-modules/currency/examples/page.mdx deleted file mode 100644 index 0f05e7b2cc9e3..0000000000000 --- a/www/apps/resources/app/commerce-modules/currency/examples/page.mdx +++ /dev/null @@ -1,111 +0,0 @@ -import { CodeTabs, CodeTab } from "docs-ui" - -export const metadata = { - title: `Examples of the Currency Module`, -} - -# {metadata.title} - -In this guide, you’ll find common examples of how you can use the Currency Module in your application. - - - -You should only use the Currency Module's main service when implementing complex customizations. For common cases, check out [available workflows instead](../../../medusa-workflows-reference/page.mdx). - - - -## List Currencies - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const currencyModuleService = req.scope.resolve( - Modules.CURRENCY - ) - - res.json({ - currencies: await currencyModuleService.listCurrencies(), - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeCurrencyModule } from "@medusajs/medusa/currency" - -export async function GET(request: Request) { - const currencyModuleService = await initializeCurrencyModule() - - return NextResponse.json({ - currencies: await currencyModuleService.listCurrencies(), - }) -} -``` - - - - ---- - -## Retrieve a Currency by its Code - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const currencyModuleService = req.scope.resolve( - Modules.CURRENCY - ) - - const currency = await currencyModuleService.retrieveCurrency("usd") - - res.json({ - currency, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeCurrencyModule } from "@medusajs/medusa/currency" - -export async function GET(request: Request) { - const currencyModuleService = await initializeCurrencyModule() - - const currency = await currencyModuleService.retrieveCurrency("usd") - - return NextResponse.json({ currency }) -} -``` - - - - ---- - -## More Examples - -The [Currency Module's main service reference](/references/currency) provides a reference to all the methods available for use with examples for each. diff --git a/www/apps/resources/app/commerce-modules/currency/page.mdx b/www/apps/resources/app/commerce-modules/currency/page.mdx index 8ac2a67659308..a38cd15944e03 100644 --- a/www/apps/resources/app/commerce-modules/currency/page.mdx +++ b/www/apps/resources/app/commerce-modules/currency/page.mdx @@ -6,91 +6,161 @@ export const metadata = { # {metadata.title} -The Currency Module provides currency-related features in your Medusa and Node.js applications. +In this section of the documentation, you will find resources to learn more about the Currency Module and how to use it in your application. -## How to Use Currency Module's Service +Medusa has currency related features available out-of-the-box through the Currency Module. A [module](!docs!/learn/fundamentals/modules) is a standalone package that provides features for a single domain. Each of Medusa's commerce features are placed in commerce modules, such as this Currency Module. -You can use the Currency Module's main service by resolving from the Medusa container the resource `Modules.CURRENCY`. + -For example: +Learn more about why modules are isolated in [this documentation](!docs!/learn/fundamentals/modules/isolation). - - + -```ts title="src/workflows/hello-world/step1.ts" -import { createStep } from "@medusajs/framework/workflows-sdk" -import { Modules } from "@medusajs/framework/utils" +## Currency Features -const step1 = createStep("step-1", async (_, { container }) => { - const currencyModuleService = container.resolve( - Modules.CURRENCY - ) +- [Currency Management and Retrieval](/references/currency/listAndCountCurrencies): This module adds all common currencies to your application and allows you to retrieve them. +- [Support Currencies in Modules](./links-to-other-modules/page.mdx): Other commerce modules use currency codes in their data models or operations. Use the Currency Module to retrieve a currency code and its details. - const currencies = await currencyModuleService.listCurrencies() -}) -``` +--- - - +## How to Use Currency Module's Service -```ts title="src/api/store/custom/route.ts" -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" +In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. -export async function GET( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const currencyModuleService = req.scope.resolve( - Modules.CURRENCY - ) - - res.json({ - currencies: await currencyModuleService.listCurrencies(), - }) -} -``` +You can build custom workflows and steps. You can also re-use Medusa's workflows and steps, which are provided by the `@medusajs/medusa/core-flows` package. - - +For example: -```ts title="src/subscribers/custom-handler.ts" -import { SubscriberArgs } from "@medusajs/framework" +export const highlights = [ + ["13", "Modules.CURRENCY", "Resolve the module in a step."] +] + +```ts title="src/workflows/retrieve-price-with-currency.ts" highlights={highlights} +import { + createWorkflow, + WorkflowResponse, + createStep, + StepResponse, + transform +} from "@medusajs/framework/workflows-sdk" import { Modules } from "@medusajs/framework/utils" -export default async function subscriberHandler({ container }: SubscriberArgs) { - const currencyModuleService = container.resolve( - Modules.CURRENCY - ) +const retrieveCurrencyStep = createStep( + "retrieve-currency", + async ({}, { container }) => { + const currencyModuleService = container.resolve(Modules.CURRENCY) - const currencies = await currencyModuleService.listCurrencies() -} -``` + const currency = await currencyModuleService + .retrieveCurrency("usd") - - + return new StepResponse({ currency }, currency.id) + } +) ---- +type Input = { + price: number +} -## Features +export const retrievePriceWithCurrency = createWorkflow( + "create-currency", + (input: Input) => { + const currency = await retrieveCurrencyStep() + + const formattedPrice = transform({ + input, + currency + }, (data) => { + return `${data.currency.symbol}${data.input.price}` + }) + + return new WorkflowResponse({ + formattedPrice, + }) + } +) +``` -### Currency Retrieval +You can then execute the workflow in your custom API routes, scheduled jobs, or subscribers: -List and retrieve currencies stored in your application. + + + + ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"], ["13"], ["14"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import type { + MedusaRequest, + MedusaResponse, + } from "@medusajs/framework/http" + import retrievePriceWithCurrency from "../../workflows/retrieve-price-with-currency" + + export async function GET( + req: MedusaRequest, + res: MedusaResponse + ) { + const { result } = await retrievePriceWithCurrency(req.scope) + .run({ + price: 10 + }) + + res.send(result) + } + ``` -```ts -const currency = await currencyModuleService.retrieveCurrency("usd") -``` + + + + ```ts title="src/subscribers/customer-created.ts" highlights={[["11"], ["12"], ["13"], ["14"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import { + type SubscriberConfig, + type SubscriberArgs, + } from "@medusajs/framework" + import retrievePriceWithCurrency from "../workflows/retrieve-price-with-currency" + + export default async function handleCustomerCreate({ + event: { data }, + container, + }: SubscriberArgs<{ id: string }>) { + const { result } = await retrievePriceWithCurrency(container) + .run({ + price: 10 + }) + + console.log(result) + } + + export const config: SubscriberConfig = { + event: "user.created", + } + ``` + + + + + ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"], ["9"], ["10"]]} + import { MedusaContainer } from "@medusajs/framework/types" + import retrievePriceWithCurrency from "../workflows/retrieve-price-with-currency" + + export default async function myCustomJob( + container: MedusaContainer + ) { + const { result } = await retrievePriceWithCurrency(container) + .run({ + price: 10 + }) + + console.log(result.message) + } + + export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, + }; + ``` -### Support Currencies in Modules + + -Other commerce modules use currency codes in their data models or operations. Use the Currency Module to retrieve a currency code and its details. +Learn more about workflows in [this documentation](!docs!/learn/fundamentals/workflows). -An example with the Region Module: +--- -```ts -const region = await regionModuleService.retrieveRegion("reg_123") -const currency = await currencyModuleService.retrieveCurrency( - region.currency_code -) -``` + \ No newline at end of file diff --git a/www/apps/resources/components/CommerceModuleSections/index.tsx b/www/apps/resources/components/CommerceModuleSections/index.tsx index 1c83fa1c90722..c466113a15e0e 100644 --- a/www/apps/resources/components/CommerceModuleSections/index.tsx +++ b/www/apps/resources/components/CommerceModuleSections/index.tsx @@ -5,10 +5,12 @@ import React from "react" type CommerceModuleSectionsProps = { name: string + hideWorkflowsSection?: boolean } export const CommerceModuleSections = ({ name, + hideWorkflowsSection = false, }: CommerceModuleSectionsProps) => { const components: (JSX.Element | JSX.Element[])[] = [] const { component: workflowsComponent } = useChildDocs({ @@ -64,18 +66,23 @@ export const CommerceModuleSections = ({ return ( <> -

Medusa Workflows and Steps

-

- Medusa provides the following workflows and steps that use the {name}{" "} - Module. You can use these workflows and steps in your customizations: -

- {workflowsComponent} - {stepsComponent} + {!hideWorkflowsSection && ( + <> +

Medusa Workflows and Steps

+

+ Medusa provides the following workflows and steps that use the{" "} + {name} Module. You can use these workflows and steps in your + customizations: +

+ {workflowsComponent} + {stepsComponent} + + )} {components.map((component, i) => ( <> -
+ {i !== 0 || !hideWorkflowsSection ?
: null} {component}
diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index b3a6be0aca471..75805c37ba4af 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -4,17 +4,16 @@ export const generatedEditDates = { "app/commerce-modules/auth/authentication-route/page.mdx": "2024-09-05T12:06:38.155Z", "app/commerce-modules/auth/examples/page.mdx": "2024-10-15T15:02:13.794Z", "app/commerce-modules/auth/module-options/page.mdx": "2024-10-15T12:52:08.930Z", - "app/commerce-modules/auth/page.mdx": "2024-12-25T12:42:47.543Z", + "app/commerce-modules/auth/page.mdx": "2024-12-25T13:38:44.159Z", "app/commerce-modules/cart/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/cart/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/cart/concepts/page.mdx": "2024-10-08T07:49:03.737Z", "app/commerce-modules/cart/promotions/page.mdx": "2024-10-08T07:54:31.120Z", "app/commerce-modules/cart/tax-lines/page.mdx": "2024-10-08T07:57:19.168Z", - "app/commerce-modules/cart/page.mdx": "2024-12-25T12:48:02.661Z", + "app/commerce-modules/cart/page.mdx": "2024-12-25T13:40:05.640Z", "app/commerce-modules/currency/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/currency/_events/page.mdx": "2024-07-03T19:27:13+03:00", - "app/commerce-modules/currency/examples/page.mdx": "2024-10-15T14:59:18.466Z", - "app/commerce-modules/currency/page.mdx": "2024-12-09T14:47:12.300Z", + "app/commerce-modules/currency/page.mdx": "2024-12-25T13:44:34.781Z", "app/commerce-modules/customer/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/customer/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/customer/customer-accounts/page.mdx": "2024-10-08T12:20:44.769Z", @@ -208,7 +207,7 @@ export const generatedEditDates = { "app/commerce-modules/auth/auth-flows/page.mdx": "2024-09-05T08:50:11.671Z", "app/commerce-modules/auth/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/auth/auth-identity-and-actor-types/page.mdx": "2024-12-09T13:04:01.129Z", - "app/commerce-modules/api-key/page.mdx": "2024-12-25T12:42:50.276Z", + "app/commerce-modules/api-key/page.mdx": "2024-12-25T13:38:18.365Z", "app/commerce-modules/auth/create-actor-type/page.mdx": "2024-12-25T13:26:27.176Z", "app/architectural-modules/page.mdx": "2024-12-11T10:33:53.064Z", "app/architectural-modules/workflow-engine/redis/page.mdx": "2024-10-15T12:50:59.507Z", diff --git a/www/apps/resources/generated/files-map.mjs b/www/apps/resources/generated/files-map.mjs index 80b8a018e889c..319cb591ac2c4 100644 --- a/www/apps/resources/generated/files-map.mjs +++ b/www/apps/resources/generated/files-map.mjs @@ -215,10 +215,6 @@ export const filesMap = [ "filePath": "/www/apps/resources/app/commerce-modules/cart/tax-lines/page.mdx", "pathname": "/commerce-modules/cart/tax-lines" }, - { - "filePath": "/www/apps/resources/app/commerce-modules/currency/examples/page.mdx", - "pathname": "/commerce-modules/currency/examples" - }, { "filePath": "/www/apps/resources/app/commerce-modules/currency/links-to-other-modules/page.mdx", "pathname": "/commerce-modules/currency/links-to-other-modules" diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs index 4ea79f462923d..21e57b4f9b358 100644 --- a/www/apps/resources/generated/sidebar.mjs +++ b/www/apps/resources/generated/sidebar.mjs @@ -1850,14 +1850,6 @@ export const generatedSidebar = [ "title": "Overview", "children": [] }, - { - "loaded": true, - "isPathHref": true, - "type": "link", - "path": "/commerce-modules/currency/examples", - "title": "Examples", - "children": [] - }, { "loaded": true, "isPathHref": true, @@ -1887,7 +1879,7 @@ export const generatedSidebar = [ "path": "/references/currency", "title": "Main Service Reference", "isChildSidebar": true, - "childSidebarTitle": "Cart Module's Main Service Reference", + "childSidebarTitle": "Currency Module's Main Service Reference", "children": [ { "loaded": true, diff --git a/www/apps/resources/sidebars/currency.mjs b/www/apps/resources/sidebars/currency.mjs index 57a53b2bc928e..0f442b2e5ec2d 100644 --- a/www/apps/resources/sidebars/currency.mjs +++ b/www/apps/resources/sidebars/currency.mjs @@ -10,11 +10,6 @@ export const currencySidebar = [ path: "/commerce-modules/currency", title: "Overview", }, - { - type: "link", - path: "/commerce-modules/currency/examples", - title: "Examples", - }, { type: "sub-category", title: "Concepts", @@ -26,6 +21,48 @@ export const currencySidebar = [ }, ], }, + { + type: "category", + title: "Server Guides", + autogenerate_tags: "server+currency", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Storefront Guides", + autogenerate_tags: "storefront+currency", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Admin Guides", + autogenerate_tags: "admin+currency", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "User Guides", + autogenerate_tags: "userGuides+currency", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Workflows", + autogenerate_tags: "workflow+currency", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Steps", + autogenerate_tags: "step+currency", + initialOpen: false, + autogenerate_as_ref: true, + }, { type: "sub-category", title: "References", @@ -35,7 +72,7 @@ export const currencySidebar = [ path: "/references/currency", title: "Main Service Reference", isChildSidebar: true, - childSidebarTitle: "Cart Module's Main Service Reference", + childSidebarTitle: "Currency Module's Main Service Reference", children: [ { type: "category", diff --git a/www/packages/tags/src/tags/index.ts b/www/packages/tags/src/tags/index.ts index e31642ae036b5..a841b9bdd20fd 100644 --- a/www/packages/tags/src/tags/index.ts +++ b/www/packages/tags/src/tags/index.ts @@ -1,31 +1,31 @@ export * from "./product.js" -export * from "./cart.js" +export * from "./tax.js" export * from "./storefront.js" -export * from "./order.js" -export * from "./stripe.js" +export * from "./cart.js" +export * from "./query.js" export * from "./payment.js" -export * from "./customer.js" export * from "./fulfillment.js" export * from "./auth.js" export * from "./product-category.js" +export * from "./pricing.js" export * from "./product-collection.js" -export * from "./tax.js" -export * from "./inventory.js" -export * from "./remote-link.js" +export * from "./customer.js" export * from "./region.js" +export * from "./order.js" +export * from "./stripe.js" +export * from "./remote-link.js" +export * from "./publishable-api-key.js" export * from "./step.js" export * from "./api-key.js" -export * from "./sales-channel.js" -export * from "./workflow.js" +export * from "./inventory.js" export * from "./event-bus.js" -export * from "./store.js" -export * from "./remote-query.js" export * from "./promotion.js" -export * from "./user.js" -export * from "./file.js" +export * from "./workflow.js" +export * from "./sales-channel.js" export * from "./locking.js" +export * from "./user.js" +export * from "./store.js" export * from "./stock-location.js" -export * from "./pricing.js" +export * from "./remote-query.js" export * from "./logger.js" -export * from "./publishable-api-key.js" -export * from "./query.js" +export * from "./file.js" From 9432f1cf31eaddc0e66cd5f3d9e05622009c34a0 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Wed, 25 Dec 2024 16:02:26 +0200 Subject: [PATCH 07/21] revise customer module --- .../app/commerce-modules/api-key/page.mdx | 2 +- .../app/commerce-modules/auth/page.mdx | 2 +- .../app/commerce-modules/cart/page.mdx | 2 +- .../app/commerce-modules/currency/page.mdx | 4 +- .../customer/examples/page.mdx | 220 ---------- .../app/commerce-modules/customer/page.mdx | 195 ++++++--- .../CommerceModuleSections/index.tsx | 13 +- www/apps/resources/generated/edit-dates.mjs | 11 +- www/apps/resources/generated/files-map.mjs | 4 - www/apps/resources/generated/sidebar.mjs | 414 +++++++++++++++++- www/apps/resources/sidebars/customer.mjs | 63 ++- www/packages/tags/src/tags/index.ts | 34 +- 12 files changed, 608 insertions(+), 356 deletions(-) delete mode 100644 www/apps/resources/app/commerce-modules/customer/examples/page.mdx diff --git a/www/apps/resources/app/commerce-modules/api-key/page.mdx b/www/apps/resources/app/commerce-modules/api-key/page.mdx index 6b18207680a0b..65e109468224f 100644 --- a/www/apps/resources/app/commerce-modules/api-key/page.mdx +++ b/www/apps/resources/app/commerce-modules/api-key/page.mdx @@ -69,7 +69,7 @@ const createApiKeyStep = createStep( export const createApiKeyWorkflow = createWorkflow( "create-api-key", () => { - const apiKey = createApiKeyStep() + const { apiKey } = createApiKeyStep() return new WorkflowResponse({ apiKey, diff --git a/www/apps/resources/app/commerce-modules/auth/page.mdx b/www/apps/resources/app/commerce-modules/auth/page.mdx index 08a84259b89d0..8a7ea0db3696c 100644 --- a/www/apps/resources/app/commerce-modules/auth/page.mdx +++ b/www/apps/resources/app/commerce-modules/auth/page.mdx @@ -86,7 +86,7 @@ const authenticateUserStep = createStep( export const authenticateUserWorkflow = createWorkflow( "authenticate-user", (input: Input) => { - const authIdentity = authenticateUserStep(input) + const { authIdentity } = authenticateUserStep(input) return new WorkflowResponse({ authIdentity, diff --git a/www/apps/resources/app/commerce-modules/cart/page.mdx b/www/apps/resources/app/commerce-modules/cart/page.mdx index cee6f9c747403..92456a8dd9976 100644 --- a/www/apps/resources/app/commerce-modules/cart/page.mdx +++ b/www/apps/resources/app/commerce-modules/cart/page.mdx @@ -78,7 +78,7 @@ const createCartStep = createStep( export const createCartWorkflow = createWorkflow( "create-cart", () => { - const cart = createCartStep() + const { cart } = createCartStep() return new WorkflowResponse({ cart, diff --git a/www/apps/resources/app/commerce-modules/currency/page.mdx b/www/apps/resources/app/commerce-modules/currency/page.mdx index a38cd15944e03..31403b367adac 100644 --- a/www/apps/resources/app/commerce-modules/currency/page.mdx +++ b/www/apps/resources/app/commerce-modules/currency/page.mdx @@ -64,7 +64,7 @@ type Input = { export const retrievePriceWithCurrency = createWorkflow( "create-currency", (input: Input) => { - const currency = await retrieveCurrencyStep() + const { currency } = await retrieveCurrencyStep() const formattedPrice = transform({ input, @@ -163,4 +163,4 @@ Learn more about workflows in [this documentation](!docs!/learn/fundamentals/wor --- - \ No newline at end of file + \ No newline at end of file diff --git a/www/apps/resources/app/commerce-modules/customer/examples/page.mdx b/www/apps/resources/app/commerce-modules/customer/examples/page.mdx deleted file mode 100644 index da6db151ec125..0000000000000 --- a/www/apps/resources/app/commerce-modules/customer/examples/page.mdx +++ /dev/null @@ -1,220 +0,0 @@ -import { CodeTabs, CodeTab } from "docs-ui" - -export const metadata = { - title: `Examples of the Customer Module`, -} - -# {metadata.title} - -In this guide, you’ll find common examples of how you can use the Customer Module in your application. - - - -You should only use the Customer Module's main service when implementing complex customizations. For common cases, check out [available workflows instead](../../../medusa-workflows-reference/page.mdx). - - - -## Create a Customer - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST(request: MedusaRequest, res: MedusaResponse) { - const customerModuleService = request.scope.resolve( - Modules.CUSTOMER - ) - - const customer = await customerModuleService.createCustomers({ - first_name: "Peter", - last_name: "Hayes", - email: "peter.hayes@example.com", - }) - - res.json({ - customer, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeCustomerModule } from "@medusajs/medusa/customer" - -export async function POST(request: Request) { - const customerModuleService = await initializeCustomerModule() - - const customer = await customerModuleService.createCustomers({ - first_name: "Peter", - last_name: "Hayes", - email: "peter.hayes@example.com", - }) - - return NextResponse.json({ - customer, - }) -} -``` - - - - ---- - -## Create a Customer Group - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST(request: MedusaRequest, res: MedusaResponse) { - const customerModuleService = request.scope.resolve( - Modules.CUSTOMER - ) - - const customerGroup = await customerModuleService.createCustomerGroups({ - name: "VIP", - }) - - res.json({ - customer_group: customerGroup, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeCustomerModule } from "@medusajs/medusa/customer" - -export async function POST(request: Request) { - const customerModuleService = await initializeCustomerModule() - - const customerGroup = await customerModuleService.createCustomerGroups({ - name: "VIP", - }) - - return NextResponse.json({ - customer_group: customerGroup, - }) -} -``` - - - - ---- - -## Add a Customer to a Group - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST(request: MedusaRequest, res: MedusaResponse) { - const customerModuleService = request.scope.resolve( - Modules.CUSTOMER - ) - - await customerModuleService.addCustomerToGroup({ - customer_id: "cus_123", - customer_group_id: "cusgroup_123", - }) - - res.status(200) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeCustomerModule } from "@medusajs/medusa/customer" - -export async function POST(request: Request) { - const customerModuleService = await initializeCustomerModule() - - await customerModuleService.addCustomerToGroup({ - customer_id: "cus_123", - customer_group_id: "cusgroup_123", - }) - - return NextResponse.json({}, { status: 200 }) -} -``` - - - - ---- - -## Remove a Customer from a Group - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST(request: MedusaRequest, res: MedusaResponse) { - const customerModuleService = request.scope.resolve( - Modules.CUSTOMER - ) - - await customerModuleService.removeCustomerFromGroup({ - customer_id: "cus_123", - customer_group_id: "cusgroup_123", - }) - - res.status(200) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - - -import { initialize as initializeCustomerModule } from "@medusajs/medusa/customer" - -export async function POST(request: Request) { - const customerModuleService = await initializeCustomerModule() - - await customerModuleService.removeCustomerFromGroup({ - customer_id: "cus_123", - customer_group_id: "cusgroup_123", - }) - - return NextResponse.json({}, { status: 200 }) -} -``` - - - - ---- - -## More Examples - -The [Customer Module's main service reference](/references/customer) provides a reference to all the methods available for use with examples for each. diff --git a/www/apps/resources/app/commerce-modules/customer/page.mdx b/www/apps/resources/app/commerce-modules/customer/page.mdx index 42d959627eb12..b30ea6e4c3e3a 100644 --- a/www/apps/resources/app/commerce-modules/customer/page.mdx +++ b/www/apps/resources/app/commerce-modules/customer/page.mdx @@ -6,96 +6,151 @@ export const metadata = { # {metadata.title} -The Customer Module provides customer-related features in your Medusa and Node.js applications. +In this section of the documentation, you will find resources to learn more about the Customer Module and how to use it in your application. -## How to Use Customer Module's Service - -You can use the Customer Module's main service by resolving from the Medusa container the resource `Modules.CUSTOMER`. +Medusa has customer related features available out-of-the-box through the Customer Module. A [module](!docs!/learn/fundamentals/modules) is a standalone package that provides features for a single domain. Each of Medusa's commerce features are placed in commerce modules, such as this Customer Module. -For example: + - - +Learn more about why modules are isolated in [this documentation](!docs!/learn/fundamentals/modules/isolation). -```ts title="src/workflows/hello-world/step1.ts" -import { createStep } from "@medusajs/framework/workflows-sdk" -import { Modules } from "@medusajs/framework/utils" + -const step1 = createStep("step-1", async (_, { container }) => { - const customerModuleService = container.resolve( - Modules.CUSTOMER - ) +## Customer Features - const customers = await customerModuleService.listCustomers() -}) -``` +- [Customer Management](./customer-accounts/page.mdx): Store and manage guest and registered customers in your store. +- [Customer Organization](/references/customer/models): Organize customers into groups. This has a lot of benefits and supports many use cases, such as provide discounts for specific customer groups using the [Promotion Module](../promotion/page.mdx). - - +--- -```ts title="src/api/store/custom/route.ts" -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" +## How to Use Customer Module's Service -export async function GET(request: MedusaRequest, res: MedusaResponse) { - const customerModuleService = request.scope.resolve( - Modules.CUSTOMER - ) +In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. - res.json({ - customers: await customerModuleService.listCustomers(), - }) -} -``` +You can build custom workflows and steps. You can also re-use Medusa's workflows and steps, which are provided by the `@medusajs/medusa/core-flows` package. - - +For example: -```ts title="src/subscribers/custom-handler.ts" -import { SubscriberArgs } from "@medusajs/framework" +export const highlights = [ + ["12", "Modules.CUSTOMER", "Resolve the module in a step."] +] + +```ts title="src/workflows/create-customer.ts" highlights={highlights} +import { + createWorkflow, + WorkflowResponse, + createStep, + StepResponse, +} from "@medusajs/framework/workflows-sdk" import { Modules } from "@medusajs/framework/utils" -export default async function subscriberHandler({ container }: SubscriberArgs) { - const customerModuleService = container.resolve( - Modules.CUSTOMER - ) - - const customers = await customerModuleService.listCustomers() -} +const createCustomerStep = createStep( + "create-customer", + async ({}, { container }) => { + const customerModuleService = container.resolve(Modules.CUSTOMER) + + const customer = await customerModuleService.createCustomers({ + first_name: "Peter", + last_name: "Hayes", + email: "peter.hayes@example.com", + }) + + return new StepResponse({ customer }, customer.id) + }, + async (customerId, { container }) => { + const customerModuleService = container.resolve(Modules.CUSTOMER) + + await customerModuleService.deleteCustomers([customerId]) + } +) + +export const createCustomerWorkflow = createWorkflow( + "create-customer", + () => { + const { customer } = createCustomerStep() + + return new WorkflowResponse({ + customer + }) + } +) ``` - - - ---- - -## Features +You can then execute the workflow in your custom API routes, scheduled jobs, or subscribers: -### Customer Management - -With the Customer Module, store and manage customers. + + + + ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import type { + MedusaRequest, + MedusaResponse, + } from "@medusajs/framework/http" + import createCustomerWorkflow from "../../workflows/create-customer" + + export async function GET( + req: MedusaRequest, + res: MedusaResponse + ) { + const { result } = await createCustomerWorkflow(req.scope) + .run() + + res.send(result) + } + ``` -```ts -const customer = await customerModuleService.createCustomers({ - first_name: "Peter", - last_name: "Hayes", - email: "peter.hayes@example.com", -}) -``` + + + + ```ts title="src/subscribers/customer-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import { + type SubscriberConfig, + type SubscriberArgs, + } from "@medusajs/framework" + import createCustomerWorkflow from "../workflows/create-customer" + + export default async function handleCustomerCreate({ + event: { data }, + container, + }: SubscriberArgs<{ id: string }>) { + const { result } = await createCustomerWorkflow(container) + .run() + + console.log(result) + } + + export const config: SubscriberConfig = { + event: "user.created", + } + ``` -### Customer Organization + + + + ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} + import { MedusaContainer } from "@medusajs/framework/types" + import createCustomerWorkflow from "../workflows/create-customer" + + export default async function myCustomJob( + container: MedusaContainer + ) { + const { result } = await createCustomerWorkflow(container) + .run() + + console.log(result.message) + } + + export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, + }; + ``` -Organize customers into groups. + + -This has a lot of benefits and supports many use cases, such as provide discounts for specific customer groups using the Promotion Module. +Learn more about workflows in [this documentation](!docs!/learn/fundamentals/workflows). -```ts -const customerGroup = await customerModuleService.createCustomerGroups({ - name: "VIP", -}) +--- -await customerModuleService.addCustomerToGroup({ - customer_id: "cus_123", - customer_group_id: customerGroup.id, -}) -``` + \ No newline at end of file diff --git a/www/apps/resources/components/CommerceModuleSections/index.tsx b/www/apps/resources/components/CommerceModuleSections/index.tsx index c466113a15e0e..461d5e29ea719 100644 --- a/www/apps/resources/components/CommerceModuleSections/index.tsx +++ b/www/apps/resources/components/CommerceModuleSections/index.tsx @@ -1,28 +1,31 @@ "use client" import { H2, Hr, useChildDocs } from "docs-ui" -import React from "react" +import React, { useMemo } from "react" type CommerceModuleSectionsProps = { name: string - hideWorkflowsSection?: boolean } export const CommerceModuleSections = ({ name, - hideWorkflowsSection = false, }: CommerceModuleSectionsProps) => { const components: (JSX.Element | JSX.Element[])[] = [] - const { component: workflowsComponent } = useChildDocs({ + const { items: workflowItems, component: workflowsComponent } = useChildDocs({ showItems: ["Workflows"], titleLevel: 3, itemsPerRow: 2, }) - const { component: stepsComponent } = useChildDocs({ + const { items: stepItems, component: stepsComponent } = useChildDocs({ showItems: ["Steps"], titleLevel: 3, itemsPerRow: 2, }) + + const hideWorkflowsSection = useMemo(() => { + return !workflowItems?.default.length && !stepItems?.default.length + }, [workflowItems, stepItems]) + const { items: serverGuideItems, component: serverGuidesComponent } = useChildDocs({ showItems: ["Server Guides"], diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index 75805c37ba4af..08ac5c7f363db 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -4,21 +4,20 @@ export const generatedEditDates = { "app/commerce-modules/auth/authentication-route/page.mdx": "2024-09-05T12:06:38.155Z", "app/commerce-modules/auth/examples/page.mdx": "2024-10-15T15:02:13.794Z", "app/commerce-modules/auth/module-options/page.mdx": "2024-10-15T12:52:08.930Z", - "app/commerce-modules/auth/page.mdx": "2024-12-25T13:38:44.159Z", + "app/commerce-modules/auth/page.mdx": "2024-12-25T13:54:02.084Z", "app/commerce-modules/cart/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/cart/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/cart/concepts/page.mdx": "2024-10-08T07:49:03.737Z", "app/commerce-modules/cart/promotions/page.mdx": "2024-10-08T07:54:31.120Z", "app/commerce-modules/cart/tax-lines/page.mdx": "2024-10-08T07:57:19.168Z", - "app/commerce-modules/cart/page.mdx": "2024-12-25T13:40:05.640Z", + "app/commerce-modules/cart/page.mdx": "2024-12-25T13:54:08.653Z", "app/commerce-modules/currency/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/currency/_events/page.mdx": "2024-07-03T19:27:13+03:00", - "app/commerce-modules/currency/page.mdx": "2024-12-25T13:44:34.781Z", + "app/commerce-modules/currency/page.mdx": "2024-12-25T13:56:32.681Z", "app/commerce-modules/customer/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/customer/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/customer/customer-accounts/page.mdx": "2024-10-08T12:20:44.769Z", - "app/commerce-modules/customer/examples/page.mdx": "2024-10-15T14:59:26.644Z", - "app/commerce-modules/customer/page.mdx": "2024-12-09T14:47:17.248Z", + "app/commerce-modules/customer/page.mdx": "2024-12-25T13:55:18.405Z", "app/commerce-modules/fulfillment/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/fulfillment/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/fulfillment/concepts/page.mdx": "2024-06-19T13:02:16+00:00", @@ -207,7 +206,7 @@ export const generatedEditDates = { "app/commerce-modules/auth/auth-flows/page.mdx": "2024-09-05T08:50:11.671Z", "app/commerce-modules/auth/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/auth/auth-identity-and-actor-types/page.mdx": "2024-12-09T13:04:01.129Z", - "app/commerce-modules/api-key/page.mdx": "2024-12-25T13:38:18.365Z", + "app/commerce-modules/api-key/page.mdx": "2024-12-25T13:54:14.876Z", "app/commerce-modules/auth/create-actor-type/page.mdx": "2024-12-25T13:26:27.176Z", "app/architectural-modules/page.mdx": "2024-12-11T10:33:53.064Z", "app/architectural-modules/workflow-engine/redis/page.mdx": "2024-10-15T12:50:59.507Z", diff --git a/www/apps/resources/generated/files-map.mjs b/www/apps/resources/generated/files-map.mjs index 319cb591ac2c4..eaa72b6342fd3 100644 --- a/www/apps/resources/generated/files-map.mjs +++ b/www/apps/resources/generated/files-map.mjs @@ -235,10 +235,6 @@ export const filesMap = [ "filePath": "/www/apps/resources/app/commerce-modules/customer/events/page.mdx", "pathname": "/commerce-modules/customer/events" }, - { - "filePath": "/www/apps/resources/app/commerce-modules/customer/examples/page.mdx", - "pathname": "/commerce-modules/customer/examples" - }, { "filePath": "/www/apps/resources/app/commerce-modules/customer/extend/page.mdx", "pathname": "/commerce-modules/customer/extend" diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs index 21e57b4f9b358..1d7e1e8deaa19 100644 --- a/www/apps/resources/generated/sidebar.mjs +++ b/www/apps/resources/generated/sidebar.mjs @@ -1966,39 +1966,125 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "link", - "path": "/commerce-modules/customer/examples", - "title": "Examples", - "children": [] + "type": "category", + "title": "Concepts", + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "link", + "path": "/commerce-modules/customer/customer-accounts", + "title": "Customer Accounts", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "path": "/commerce-modules/customer/links-to-other-modules", + "title": "Link to Modules", + "children": [] + } + ] }, { "loaded": true, "isPathHref": true, - "type": "link", - "path": "/commerce-modules/customer/extend", - "title": "Extend Module", - "children": [] + "type": "category", + "title": "Server Guides", + "autogenerate_tags": "server+customer", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "link", + "path": "/commerce-modules/customer/extend", + "title": "Extend Module", + "children": [] + } + ] }, { "loaded": true, "isPathHref": true, - "type": "sub-category", - "title": "Concepts", + "type": "category", + "title": "Storefront Guides", + "autogenerate_tags": "storefront+customer", + "initialOpen": false, + "autogenerate_as_ref": true, "children": [ { "loaded": true, "isPathHref": true, - "type": "link", - "path": "/commerce-modules/customer/customer-accounts", - "title": "Customer Accounts", + "type": "ref", + "title": "Manage Customer Addresses in Storefront", + "path": "/storefront-development/customers/addresses", "children": [] }, { "loaded": true, "isPathHref": true, - "type": "link", - "path": "/commerce-modules/customer/links-to-other-modules", - "title": "Link to Modules", + "type": "ref", + "title": "Customer Context in Storefront", + "path": "/storefront-development/customers/context", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Log-out Customer in Storefront", + "path": "/storefront-development/customers/log-out", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Login Customer in Storefront", + "path": "/storefront-development/customers/login", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Edit Customer Profile in Storefront", + "path": "/storefront-development/customers/profile", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Register Customer in Storefront", + "path": "/storefront-development/customers/register", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Reset Customer Password in Storefront", + "path": "/storefront-development/customers/reset-password", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Retrieve Customer in Storefront", + "path": "/storefront-development/customers/retrieve", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Third-Party or Social Login in Storefront", + "path": "/storefront-development/customers/third-party-login", "children": [] } ] @@ -2006,7 +2092,301 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", + "title": "Workflows", + "autogenerate_tags": "workflow+customer", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createCartWorkflow", + "path": "/references/medusa-workflows/createCartWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateCartWorkflow", + "path": "/references/medusa-workflows/updateCartWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createCustomerAccountWorkflow", + "path": "/references/medusa-workflows/createCustomerAccountWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createCustomerAddressesWorkflow", + "path": "/references/medusa-workflows/createCustomerAddressesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createCustomersWorkflow", + "path": "/references/medusa-workflows/createCustomersWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteCustomerAddressesWorkflow", + "path": "/references/medusa-workflows/deleteCustomerAddressesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteCustomersWorkflow", + "path": "/references/medusa-workflows/deleteCustomersWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "removeCustomerAccountWorkflow", + "path": "/references/medusa-workflows/removeCustomerAccountWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateCustomerAddressesWorkflow", + "path": "/references/medusa-workflows/updateCustomerAddressesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateCustomersWorkflow", + "path": "/references/medusa-workflows/updateCustomersWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createCustomerGroupsWorkflow", + "path": "/references/medusa-workflows/createCustomerGroupsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteCustomerGroupsWorkflow", + "path": "/references/medusa-workflows/deleteCustomerGroupsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "linkCustomerGroupsToCustomerWorkflow", + "path": "/references/medusa-workflows/linkCustomerGroupsToCustomerWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "linkCustomersToCustomerGroupWorkflow", + "path": "/references/medusa-workflows/linkCustomersToCustomerGroupWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateCustomerGroupsWorkflow", + "path": "/references/medusa-workflows/updateCustomerGroupsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "addOrderLineItemsWorkflow", + "path": "/references/medusa-workflows/addOrderLineItemsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createOrderWorkflow", + "path": "/references/medusa-workflows/createOrderWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderClaimAddNewItemWorkflow", + "path": "/references/medusa-workflows/orderClaimAddNewItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderEditAddNewItemWorkflow", + "path": "/references/medusa-workflows/orderEditAddNewItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderExchangeAddNewItemWorkflow", + "path": "/references/medusa-workflows/orderExchangeAddNewItemWorkflow", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Steps", + "autogenerate_tags": "step+customer", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "findOrCreateCustomerStep", + "path": "/references/medusa-workflows/steps/findOrCreateCustomerStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createCustomerAddressesStep", + "path": "/references/medusa-workflows/steps/createCustomerAddressesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createCustomersStep", + "path": "/references/medusa-workflows/steps/createCustomersStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteCustomerAddressesStep", + "path": "/references/medusa-workflows/steps/deleteCustomerAddressesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteCustomersStep", + "path": "/references/medusa-workflows/steps/deleteCustomersStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "maybeUnsetDefaultBillingAddressesStep", + "path": "/references/medusa-workflows/steps/maybeUnsetDefaultBillingAddressesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "maybeUnsetDefaultShippingAddressesStep", + "path": "/references/medusa-workflows/steps/maybeUnsetDefaultShippingAddressesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateCustomerAddressesStep", + "path": "/references/medusa-workflows/steps/updateCustomerAddressesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateCustomersStep", + "path": "/references/medusa-workflows/steps/updateCustomersStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createCustomerGroupsStep", + "path": "/references/medusa-workflows/steps/createCustomerGroupsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteCustomerGroupStep", + "path": "/references/medusa-workflows/steps/deleteCustomerGroupStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "linkCustomerGroupsToCustomerStep", + "path": "/references/medusa-workflows/steps/linkCustomerGroupsToCustomerStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "linkCustomersToCustomerGroupStep", + "path": "/references/medusa-workflows/steps/linkCustomersToCustomerGroupStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateCustomerGroupsStep", + "path": "/references/medusa-workflows/steps/updateCustomerGroupsStep", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", "title": "References", "children": [ { diff --git a/www/apps/resources/sidebars/customer.mjs b/www/apps/resources/sidebars/customer.mjs index 3f1d6ec450082..acb74475a8e17 100644 --- a/www/apps/resources/sidebars/customer.mjs +++ b/www/apps/resources/sidebars/customer.mjs @@ -11,17 +11,7 @@ export const customerSidebar = [ title: "Overview", }, { - type: "link", - path: "/commerce-modules/customer/examples", - title: "Examples", - }, - { - type: "link", - path: "/commerce-modules/customer/extend", - title: "Extend Module", - }, - { - type: "sub-category", + type: "category", title: "Concepts", children: [ { @@ -37,7 +27,56 @@ export const customerSidebar = [ ], }, { - type: "sub-category", + type: "category", + title: "Server Guides", + autogenerate_tags: "server+customer", + initialOpen: false, + autogenerate_as_ref: true, + children: [ + { + type: "link", + path: "/commerce-modules/customer/extend", + title: "Extend Module", + }, + ], + }, + { + type: "category", + title: "Storefront Guides", + autogenerate_tags: "storefront+customer", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Admin Guides", + autogenerate_tags: "admin+customer", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "User Guides", + autogenerate_tags: "userGuides+customer", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Workflows", + autogenerate_tags: "workflow+customer", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Steps", + autogenerate_tags: "step+customer", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", title: "References", children: [ { diff --git a/www/packages/tags/src/tags/index.ts b/www/packages/tags/src/tags/index.ts index a841b9bdd20fd..aff6607c107e4 100644 --- a/www/packages/tags/src/tags/index.ts +++ b/www/packages/tags/src/tags/index.ts @@ -1,31 +1,31 @@ export * from "./product.js" -export * from "./tax.js" -export * from "./storefront.js" -export * from "./cart.js" export * from "./query.js" +export * from "./order.js" +export * from "./storefront.js" +export * from "./stripe.js" export * from "./payment.js" export * from "./fulfillment.js" +export * from "./cart.js" +export * from "./pricing.js" +export * from "./tax.js" +export * from "./customer.js" export * from "./auth.js" export * from "./product-category.js" -export * from "./pricing.js" export * from "./product-collection.js" -export * from "./customer.js" -export * from "./region.js" -export * from "./order.js" -export * from "./stripe.js" +export * from "./inventory.js" export * from "./remote-link.js" -export * from "./publishable-api-key.js" +export * from "./region.js" export * from "./step.js" -export * from "./api-key.js" -export * from "./inventory.js" -export * from "./event-bus.js" -export * from "./promotion.js" export * from "./workflow.js" export * from "./sales-channel.js" -export * from "./locking.js" -export * from "./user.js" -export * from "./store.js" -export * from "./stock-location.js" export * from "./remote-query.js" +export * from "./publishable-api-key.js" +export * from "./api-key.js" +export * from "./event-bus.js" +export * from "./store.js" +export * from "./user.js" +export * from "./locking.js" +export * from "./promotion.js" export * from "./logger.js" +export * from "./stock-location.js" export * from "./file.js" From d76b5d94055de6c0268783fe75e6c7ab9b22330c Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Wed, 25 Dec 2024 16:17:05 +0200 Subject: [PATCH 08/21] revise fulfillment module --- .../app/commerce-modules/cart/page.mdx | 6 +- .../app/commerce-modules/fulfillment/page.mdx | 275 +++++------ www/apps/resources/generated/edit-dates.mjs | 4 +- www/apps/resources/generated/sidebar.mjs | 440 +++++++++++++++++- www/apps/resources/sidebars/api-key.mjs | 3 + www/apps/resources/sidebars/auth.mjs | 3 + www/apps/resources/sidebars/cart.mjs | 3 + www/apps/resources/sidebars/currency.mjs | 3 + www/apps/resources/sidebars/customer.mjs | 3 + www/apps/resources/sidebars/fulfillment.mjs | 51 +- www/packages/tags/src/tags/index.ts | 24 +- 11 files changed, 656 insertions(+), 159 deletions(-) diff --git a/www/apps/resources/app/commerce-modules/cart/page.mdx b/www/apps/resources/app/commerce-modules/cart/page.mdx index 92456a8dd9976..4805201dc3075 100644 --- a/www/apps/resources/app/commerce-modules/cart/page.mdx +++ b/www/apps/resources/app/commerce-modules/cart/page.mdx @@ -97,7 +97,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or MedusaRequest, MedusaResponse, } from "@medusajs/framework/http" - import createCartWorkflow from "../../workflows/create-workflow" + import createCartWorkflow from "../../workflows/create-cart" export async function GET( req: MedusaRequest, @@ -118,7 +118,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or type SubscriberConfig, type SubscriberArgs, } from "@medusajs/framework" - import createCartWorkflow from "../workflows/create-workflow" + import createCartWorkflow from "../workflows/create-cart" export default async function handleCustomerCreate({ event: { data }, @@ -140,7 +140,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} import { MedusaContainer } from "@medusajs/framework/types" - import createCartWorkflow from "../workflows/create-workflow" + import createCartWorkflow from "../workflows/create-cart" export default async function myCustomJob( container: MedusaContainer diff --git a/www/apps/resources/app/commerce-modules/fulfillment/page.mdx b/www/apps/resources/app/commerce-modules/fulfillment/page.mdx index 3984a149ca32f..61617cb311565 100644 --- a/www/apps/resources/app/commerce-modules/fulfillment/page.mdx +++ b/www/apps/resources/app/commerce-modules/fulfillment/page.mdx @@ -6,162 +6,173 @@ export const metadata = { # {metadata.title} -The Fulfillment Module provides fulfillment-related features in your Medusa and Node.js applications. +In this section of the documentation, you will find resources to learn more about the Fulfillment Module and how to use it in your application. -## How to Use Fulfillment Module's Service +Medusa has fulfillment related features available out-of-the-box through the Fulfillment Module. A [module](!docs!/learn/fundamentals/modules) is a standalone package that provides features for a single domain. Each of Medusa's commerce features are placed in commerce modules, such as this Fulfillment Module. -You can use the Fulfillment Module's main service by resolving from the Medusa container the resource `Modules.FULFILLMENT`. + -For example: +Learn more about why modules are isolated in [this documentation](!docs!/learn/fundamentals/modules/isolation). - - + -```ts title="src/workflows/hello-world/step1.ts" -import { createStep } from "@medusajs/framework/workflows-sdk" -import { Modules } from "@medusajs/framework/utils" +## Fulfillment Features -const step1 = createStep("step-1", async (_, { container }) => { - const fulfillmentModuleService = container.resolve( - Modules.FULFILLMENT - ) +- [Fulfillment Management](./item-fulfillment/page.mdx): Create fulfillments and keep track of their status, items, and more. +- [Integrate Third-Party Fulfillment Providers](./fulfillment-provider/page.mdx): Create third-party fulfillment providers to provide customers with shipping options and fulfill their orders. +- [Restrict By Location and Rules](./shipping-option/page.mdx): Shipping options can be restricted to specific geographical locations. You can also specify custom rules to restrict shipping options. +- [Support Different Fulfillment Forms](./concepts/page.mdx): Support various fulfillment forms, such as shipping or pick up. - const fulfillments = await fulfillmentModuleService.listFulfillments() -}) -``` +--- - - +## How to Use Fulfillment Module's Service -```ts title="src/api/store/custom/route.ts" -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" +In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. -export async function GET( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const fulfillmentModuleService = req.scope.resolve( - Modules.FULFILLMENT - ) - - res.json({ - fulfillments: await fulfillmentModuleService.listFulfillments(), - }) -} -``` +You can build custom workflows and steps. You can also re-use Medusa's workflows and steps, which are provided by the `@medusajs/medusa/core-flows` package. - - +For example: -```ts title="src/subscribers/custom-handler.ts" -import { SubscriberArgs } from "@medusajs/framework" +export const highlights = [ + ["12", "Modules.FULFILLMENT", "Resolve the module in a step."] +] + +```ts title="src/workflows/create-fulfillment.ts" highlights={highlights} +import { + createWorkflow, + WorkflowResponse, + createStep, + StepResponse, +} from "@medusajs/framework/workflows-sdk" import { Modules } from "@medusajs/framework/utils" -export default async function subscriberHandler({ container }: SubscriberArgs) { - const fulfillmentModuleService = container.resolve( - Modules.FULFILLMENT - ) - - const fulfillments = await fulfillmentModuleService.listFulfillments() -} -``` - - - - ---- - -## Features - -### Fulfillment Management - -Create fulfillments and keep track of their status, items, and more. - -```ts -const fulfillment = await fulfillmentModuleService.createFulfillment({ - location_id: "loc_123", - provider_id: "webshipper", - delivery_address: { - country_code: "us", - city: "Strongsville", - address_1: "18290 Royalton Rd", +const createFulfillmentStep = createStep( + "create-fulfillment", + async ({}, { container }) => { + const fulfillmentModuleService = container.resolve(Modules.FULFILLMENT) + + const fulfillment = await fulfillmentModuleService.createFulfillment({ + location_id: "loc_123", + provider_id: "webshipper", + delivery_address: { + country_code: "us", + city: "Strongsville", + address_1: "18290 Royalton Rd", + }, + items: [ + { + title: "Shirt", + sku: "SHIRT", + quantity: 1, + barcode: "123456", + }, + ], + labels: [], + order: {}, + }) + + return new StepResponse({ fulfillment }, fulfillment.id) }, - items: [ - { - title: "Shirt", - sku: "SHIRT", - quantity: 1, - barcode: "123456", - }, - ], - labels: [], - order: {}, -}) + async (fulfillmentId, { container }) => { + const fulfillmentModuleService = container.resolve(Modules.FULFILLMENT) + + await fulfillmentModuleService.deleteFulfillment(fulfillmentId) + } +) + +export const createFulfillmentWorkflow = createWorkflow( + "create-fulfillment", + () => { + const { fulfillment } = createFulfillmentStep() + + return new WorkflowResponse({ + fulfillment, + }) + } +) ``` -### Integrate Third-Party Fulfillment Providers +You can then execute the workflow in your custom API routes, scheduled jobs, or subscribers: -Use third-party fulfillment providers to provide customers with shipping options and fulfill their orders. - -```ts -const shippingOption = await fulfillmentModuleService.createShippingOptions({ - // ... - provider_id: "webshipper", -}) -``` + + + + ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import type { + MedusaRequest, + MedusaResponse, + } from "@medusajs/framework/http" + import createFulfillmentWorkflow from "../../workflows/create-fuilfillment" + + export async function GET( + req: MedusaRequest, + res: MedusaResponse + ) { + const { result } = await createFulfillmentWorkflow(req.scope) + .run() + + res.send(result) + } + ``` -### Restrict By Location and Rules - -Shipping options can be restricted to specific geographical locations. You can also specify custom rules to restrict shipping options. - -```ts -const serviceZone = await fulfillmentModuleService.createServiceZones({ - name: "US", - fulfillment_set_id: "fset_123", - geo_zones: [ - { - type: "country", - country_code: "us", - }, - ], -}) - -const shippingOption = await fulfillmentModuleService.createShippingOptions({ - name: "Express Shipping", - // restrict location - service_zone_id: serviceZone.id, - // restrict by custom rules - rules: [ - { - field: "customer_group", - operator: "eq", - value: "vip", - }, - ], - // ... -}) -``` + + + + ```ts title="src/subscribers/customer-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import { + type SubscriberConfig, + type SubscriberArgs, + } from "@medusajs/framework" + import createFulfillmentWorkflow from "../workflows/create-fuilfillment" + + export default async function handleCustomerCreate({ + event: { data }, + container, + }: SubscriberArgs<{ id: string }>) { + const { result } = await createFulfillmentWorkflow(container) + .run() + + console.log(result) + } + + export const config: SubscriberConfig = { + event: "user.created", + } + ``` -### Support Different Fulfillment Forms + + + + ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} + import { MedusaContainer } from "@medusajs/framework/types" + import createFulfillmentWorkflow from "../workflows/create-fuilfillment" + + export default async function myCustomJob( + container: MedusaContainer + ) { + const { result } = await createFulfillmentWorkflow(container) + .run() + + console.log(result.message) + } + + export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, + }; + ``` -Support various fulfillment forms, such as shipping or pick up. + + -```ts -const fulfillmentSets = await fulfillmentModuleService.createFulfillmentSets([ - { - name: "Shipping", - type: "shipping", - }, - { - name: "Pick-up", - type: "pick-up", - }, -]) -``` +Learn more about workflows in [this documentation](!docs!/learn/fundamentals/workflows). --- ## Configure Fulfillment Module -Refer to [this documentation](./module-options/page.mdx) for details on the module's options. +The Fulfillment Module accepts options for further configurations. Refer to [this documentation](./module-options/page.mdx) for details on the module's options. + +--- + + \ No newline at end of file diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index 08ac5c7f363db..933f8456f3faa 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -10,7 +10,7 @@ export const generatedEditDates = { "app/commerce-modules/cart/concepts/page.mdx": "2024-10-08T07:49:03.737Z", "app/commerce-modules/cart/promotions/page.mdx": "2024-10-08T07:54:31.120Z", "app/commerce-modules/cart/tax-lines/page.mdx": "2024-10-08T07:57:19.168Z", - "app/commerce-modules/cart/page.mdx": "2024-12-25T13:54:08.653Z", + "app/commerce-modules/cart/page.mdx": "2024-12-25T14:06:23.995Z", "app/commerce-modules/currency/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/currency/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/currency/page.mdx": "2024-12-25T13:56:32.681Z", @@ -25,7 +25,7 @@ export const generatedEditDates = { "app/commerce-modules/fulfillment/item-fulfillment/page.mdx": "2024-10-08T14:38:15.496Z", "app/commerce-modules/fulfillment/module-options/page.mdx": "2024-10-15T12:51:56.118Z", "app/commerce-modules/fulfillment/shipping-option/page.mdx": "2024-10-08T14:36:02.660Z", - "app/commerce-modules/fulfillment/page.mdx": "2024-12-09T14:47:23.482Z", + "app/commerce-modules/fulfillment/page.mdx": "2024-12-25T14:07:33.995Z", "app/commerce-modules/inventory/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/inventory/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/inventory/concepts/page.mdx": "2024-10-08T15:11:27.634Z", diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs index 1d7e1e8deaa19..9193abf6b2297 100644 --- a/www/apps/resources/generated/sidebar.mjs +++ b/www/apps/resources/generated/sidebar.mjs @@ -191,6 +191,9 @@ export const generatedSidebar = [ "title": "Overview", "children": [] }, + { + "type": "separator" + }, { "loaded": true, "isPathHref": true, @@ -485,6 +488,9 @@ export const generatedSidebar = [ "title": "Module Options", "children": [] }, + { + "type": "separator" + }, { "loaded": true, "isPathHref": true, @@ -941,6 +947,9 @@ export const generatedSidebar = [ "title": "Overview", "children": [] }, + { + "type": "separator" + }, { "loaded": true, "isPathHref": true, @@ -1850,6 +1859,9 @@ export const generatedSidebar = [ "title": "Overview", "children": [] }, + { + "type": "separator" + }, { "loaded": true, "isPathHref": true, @@ -1963,6 +1975,9 @@ export const generatedSidebar = [ "title": "Overview", "children": [] }, + { + "type": "separator" + }, { "loaded": true, "isPathHref": true, @@ -2696,10 +2711,13 @@ export const generatedSidebar = [ "title": "Module Options", "children": [] }, + { + "type": "separator" + }, { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", "title": "Concepts", "children": [ { @@ -2747,8 +2765,11 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "sub-category", - "title": "Guides", + "type": "category", + "title": "Server Guides", + "autogenerate_tags": "server+fulfillment", + "initialOpen": false, + "autogenerate_as_ref": true, "children": [ { "loaded": true, @@ -2761,7 +2782,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "link", + "type": "ref", "path": "/integrations/guides/shipstation", "title": "Integrate ShipStation", "children": [] @@ -2771,7 +2792,416 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", + "title": "Storefront Guides", + "autogenerate_tags": "storefront+fulfillment", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Checkout Step 3: Choose Shipping Method", + "path": "/storefront-development/checkout/shipping", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Workflows", + "autogenerate_tags": "workflow+fulfillment", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "addShippingMethodToCartWorkflow", + "path": "/references/medusa-workflows/addShippingMethodToCartWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "listShippingOptionsForCartWithPricingWorkflow", + "path": "/references/medusa-workflows/listShippingOptionsForCartWithPricingWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "batchShippingOptionRulesWorkflow", + "path": "/references/medusa-workflows/batchShippingOptionRulesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "calculateShippingOptionsPricesWorkflow", + "path": "/references/medusa-workflows/calculateShippingOptionsPricesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelFulfillmentWorkflow", + "path": "/references/medusa-workflows/cancelFulfillmentWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createFulfillmentWorkflow", + "path": "/references/medusa-workflows/createFulfillmentWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createReturnFulfillmentWorkflow", + "path": "/references/medusa-workflows/createReturnFulfillmentWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createServiceZonesWorkflow", + "path": "/references/medusa-workflows/createServiceZonesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createShipmentWorkflow", + "path": "/references/medusa-workflows/createShipmentWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createShippingOptionsWorkflow", + "path": "/references/medusa-workflows/createShippingOptionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createShippingProfilesWorkflow", + "path": "/references/medusa-workflows/createShippingProfilesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteFulfillmentSetsWorkflow", + "path": "/references/medusa-workflows/deleteFulfillmentSetsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteServiceZonesWorkflow", + "path": "/references/medusa-workflows/deleteServiceZonesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteShippingOptionsWorkflow", + "path": "/references/medusa-workflows/deleteShippingOptionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "markFulfillmentAsDeliveredWorkflow", + "path": "/references/medusa-workflows/markFulfillmentAsDeliveredWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateFulfillmentWorkflow", + "path": "/references/medusa-workflows/updateFulfillmentWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateShippingOptionsWorkflow", + "path": "/references/medusa-workflows/updateShippingOptionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateShippingProfilesWorkflow", + "path": "/references/medusa-workflows/updateShippingProfilesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelOrderFulfillmentWorkflow", + "path": "/references/medusa-workflows/cancelOrderFulfillmentWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "confirmClaimRequestWorkflow", + "path": "/references/medusa-workflows/confirmClaimRequestWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "confirmExchangeRequestWorkflow", + "path": "/references/medusa-workflows/confirmExchangeRequestWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "confirmReturnRequestWorkflow", + "path": "/references/medusa-workflows/confirmReturnRequestWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createAndCompleteReturnOrderWorkflow", + "path": "/references/medusa-workflows/createAndCompleteReturnOrderWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createOrderFulfillmentWorkflow", + "path": "/references/medusa-workflows/createOrderFulfillmentWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createOrderShipmentWorkflow", + "path": "/references/medusa-workflows/createOrderShipmentWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "markOrderFulfillmentAsDeliveredWorkflow", + "path": "/references/medusa-workflows/markOrderFulfillmentAsDeliveredWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteShippingProfileWorkflow", + "path": "/references/medusa-workflows/deleteShippingProfileWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createLocationFulfillmentSetWorkflow", + "path": "/references/medusa-workflows/createLocationFulfillmentSetWorkflow", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Steps", + "autogenerate_tags": "step+fulfillment", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "validateCartShippingOptionsStep", + "path": "/references/medusa-workflows/steps/validateCartShippingOptionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "calculateShippingOptionsPricesStep", + "path": "/references/medusa-workflows/steps/calculateShippingOptionsPricesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelFulfillmentStep", + "path": "/references/medusa-workflows/steps/cancelFulfillmentStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createFulfillmentSets", + "path": "/references/medusa-workflows/steps/createFulfillmentSets", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createFulfillmentStep", + "path": "/references/medusa-workflows/steps/createFulfillmentStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createReturnFulfillmentStep", + "path": "/references/medusa-workflows/steps/createReturnFulfillmentStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createServiceZonesStep", + "path": "/references/medusa-workflows/steps/createServiceZonesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createShippingOptionRulesStep", + "path": "/references/medusa-workflows/steps/createShippingOptionRulesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createShippingProfilesStep", + "path": "/references/medusa-workflows/steps/createShippingProfilesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteFulfillmentSetsStep", + "path": "/references/medusa-workflows/steps/deleteFulfillmentSetsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteServiceZonesStep", + "path": "/references/medusa-workflows/steps/deleteServiceZonesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteShippingOptionRulesStep", + "path": "/references/medusa-workflows/steps/deleteShippingOptionRulesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteShippingOptionsStep", + "path": "/references/medusa-workflows/steps/deleteShippingOptionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateFulfillmentStep", + "path": "/references/medusa-workflows/steps/updateFulfillmentStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateShippingProfilesStep", + "path": "/references/medusa-workflows/steps/updateShippingProfilesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "upsertShippingOptionsStep", + "path": "/references/medusa-workflows/steps/upsertShippingOptionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "validateShipmentStep", + "path": "/references/medusa-workflows/steps/validateShipmentStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteShippingProfilesStep", + "path": "/references/medusa-workflows/steps/deleteShippingProfilesStep", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", "title": "References", "children": [ { diff --git a/www/apps/resources/sidebars/api-key.mjs b/www/apps/resources/sidebars/api-key.mjs index fb153cff6a490..19823e33e70b4 100644 --- a/www/apps/resources/sidebars/api-key.mjs +++ b/www/apps/resources/sidebars/api-key.mjs @@ -10,6 +10,9 @@ export const apiKeySidebar = [ path: "/commerce-modules/api-key", title: "Overview", }, + { + type: "separator", + }, { type: "category", title: "Concepts", diff --git a/www/apps/resources/sidebars/auth.mjs b/www/apps/resources/sidebars/auth.mjs index 29eba23cd8f46..216e2c053811d 100644 --- a/www/apps/resources/sidebars/auth.mjs +++ b/www/apps/resources/sidebars/auth.mjs @@ -15,6 +15,9 @@ export const authSidebar = [ path: "/commerce-modules/auth/module-options", title: "Module Options", }, + { + type: "separator", + }, { type: "category", title: "Concepts", diff --git a/www/apps/resources/sidebars/cart.mjs b/www/apps/resources/sidebars/cart.mjs index 8b07653b74550..315d5f0e9e4ea 100644 --- a/www/apps/resources/sidebars/cart.mjs +++ b/www/apps/resources/sidebars/cart.mjs @@ -10,6 +10,9 @@ export const cartSidebar = [ path: "/commerce-modules/cart", title: "Overview", }, + { + type: "separator", + }, { type: "category", title: "Concepts", diff --git a/www/apps/resources/sidebars/currency.mjs b/www/apps/resources/sidebars/currency.mjs index 0f442b2e5ec2d..77975e7798628 100644 --- a/www/apps/resources/sidebars/currency.mjs +++ b/www/apps/resources/sidebars/currency.mjs @@ -10,6 +10,9 @@ export const currencySidebar = [ path: "/commerce-modules/currency", title: "Overview", }, + { + type: "separator", + }, { type: "sub-category", title: "Concepts", diff --git a/www/apps/resources/sidebars/customer.mjs b/www/apps/resources/sidebars/customer.mjs index acb74475a8e17..5abeadf8deebd 100644 --- a/www/apps/resources/sidebars/customer.mjs +++ b/www/apps/resources/sidebars/customer.mjs @@ -10,6 +10,9 @@ export const customerSidebar = [ path: "/commerce-modules/customer", title: "Overview", }, + { + type: "separator", + }, { type: "category", title: "Concepts", diff --git a/www/apps/resources/sidebars/fulfillment.mjs b/www/apps/resources/sidebars/fulfillment.mjs index c46b2fec93fb6..37c9aa6230fd7 100644 --- a/www/apps/resources/sidebars/fulfillment.mjs +++ b/www/apps/resources/sidebars/fulfillment.mjs @@ -16,7 +16,10 @@ export const fulfillmentSidebar = [ title: "Module Options", }, { - type: "sub-category", + type: "separator", + }, + { + type: "category", title: "Concepts", children: [ { @@ -47,8 +50,11 @@ export const fulfillmentSidebar = [ ], }, { - type: "sub-category", - title: "Guides", + type: "category", + title: "Server Guides", + autogenerate_tags: "server+fulfillment", + initialOpen: false, + autogenerate_as_ref: true, children: [ { type: "link", @@ -56,14 +62,49 @@ export const fulfillmentSidebar = [ title: "Create Fulfillment Provider Module", }, { - type: "link", + type: "ref", path: "/integrations/guides/shipstation", title: "Integrate ShipStation", }, ], }, { - type: "sub-category", + type: "category", + title: "Storefront Guides", + autogenerate_tags: "storefront+fulfillment", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Admin Guides", + autogenerate_tags: "admin+fulfillment", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "User Guides", + autogenerate_tags: "userGuides+fulfillment", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Workflows", + autogenerate_tags: "workflow+fulfillment", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Steps", + autogenerate_tags: "step+fulfillment", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", title: "References", children: [ { diff --git a/www/packages/tags/src/tags/index.ts b/www/packages/tags/src/tags/index.ts index aff6607c107e4..2a6190655b08c 100644 --- a/www/packages/tags/src/tags/index.ts +++ b/www/packages/tags/src/tags/index.ts @@ -1,31 +1,31 @@ export * from "./product.js" -export * from "./query.js" -export * from "./order.js" +export * from "./pricing.js" export * from "./storefront.js" +export * from "./order.js" export * from "./stripe.js" export * from "./payment.js" export * from "./fulfillment.js" -export * from "./cart.js" -export * from "./pricing.js" -export * from "./tax.js" export * from "./customer.js" export * from "./auth.js" export * from "./product-category.js" export * from "./product-collection.js" export * from "./inventory.js" -export * from "./remote-link.js" +export * from "./tax.js" +export * from "./query.js" +export * from "./cart.js" export * from "./region.js" export * from "./step.js" -export * from "./workflow.js" export * from "./sales-channel.js" +export * from "./workflow.js" export * from "./remote-query.js" -export * from "./publishable-api-key.js" export * from "./api-key.js" -export * from "./event-bus.js" +export * from "./remote-link.js" +export * from "./publishable-api-key.js" export * from "./store.js" export * from "./user.js" -export * from "./locking.js" -export * from "./promotion.js" export * from "./logger.js" -export * from "./stock-location.js" +export * from "./promotion.js" +export * from "./locking.js" export * from "./file.js" +export * from "./event-bus.js" +export * from "./stock-location.js" From 99e4d0addba92de89ed5dfd94b5b0a6db85f423c Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Wed, 25 Dec 2024 16:27:20 +0200 Subject: [PATCH 09/21] revise inventory module --- .../inventory/examples/page.mdx | 526 ------------------ .../app/commerce-modules/inventory/page.mdx | 221 ++++---- www/apps/resources/generated/edit-dates.mjs | 3 +- www/apps/resources/generated/files-map.mjs | 4 - www/apps/resources/generated/sidebar.mjs | 420 +++++++++++++- www/apps/resources/sidebars/inventory.mjs | 50 +- www/packages/tags/src/tags/index.ts | 34 +- 7 files changed, 597 insertions(+), 661 deletions(-) delete mode 100644 www/apps/resources/app/commerce-modules/inventory/examples/page.mdx diff --git a/www/apps/resources/app/commerce-modules/inventory/examples/page.mdx b/www/apps/resources/app/commerce-modules/inventory/examples/page.mdx deleted file mode 100644 index 4877b4caf0f3d..0000000000000 --- a/www/apps/resources/app/commerce-modules/inventory/examples/page.mdx +++ /dev/null @@ -1,526 +0,0 @@ -import { CodeTabs, CodeTab } from "docs-ui" - -export const metadata = { - title: `Examples of the Inventory Module`, -} - -# {metadata.title} - -In this document, you’ll find common examples of how you can use the Inventory Module in your application. - - - -You should only use the Inventory Module's main service when implementing complex customizations. For common cases, check out [available workflows instead](../../../medusa-workflows-reference/page.mdx). - - - -## Create an Inventory Item - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const inventoryModuleService = request.scope.resolve( - Modules.INVENTORY - ) - - const inventoryItem = await inventoryModuleService.createInventoryItems({ - sku: request.body.sku, - title: request.body.title, - requires_shipping: request.body.requires_shipping, - }) - - res.json({ inventory_item: inventoryItem }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeInventoryModule } from "@medusajs/medusa/inventory" - -export async function POST(request: Request) { - const inventoryModuleService = await initializeInventoryModule({}) - const body = await request.json() - - const inventoryItem = await inventoryModuleService.createInventoryItems({ - sku: body.sku, - title: body.title, - requires_shipping: body.requires_shipping, - }) - - return NextResponse.json({ inventory_item: inventoryItem }) -} -``` - - - - ---- - -## List Inventory Items - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const inventoryModuleService = request.scope.resolve( - Modules.INVENTORY - ) - - const inventoryItems = await inventoryModuleService.listInventoryItems({}) - - res.json({ inventory_items: inventoryItems }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeInventoryModule } from "@medusajs/medusa/inventory" - -export async function GET(request: Request) { - const inventoryModuleService = await initializeInventoryModule({}) - - const inventoryItems = await inventoryModuleService.listInventoryItems({}) - - return NextResponse.json({ inventory_items: inventoryItems }) -} -``` - - - - ---- - -## Retrieve an Inventory Item by its ID - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const inventoryModuleService = request.scope.resolve( - Modules.INVENTORY - ) - - const inventoryItem = await inventoryModuleService.retrieveInventoryItem( - request.params.id - ) - - res.json({ inventory_item: inventoryItem }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeInventoryModule } from "@medusajs/medusa/inventory" - -type ContextType = { - params: { - id: string - } -} - -export async function GET(request: Request, { params }: ContextType) { - const inventoryModuleService = await initializeInventoryModule({}) - - const inventoryItem = await inventoryModuleService.retrieveInventoryItem( - params.id - ) - - return NextResponse.json({ inventory_item: inventoryItem }) -} -``` - - - - ---- - -## Create an Inventory Level - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const inventoryModuleService = request.scope.resolve( - Modules.INVENTORY - ) - - const inventoryLevel = await inventoryModuleService.createInventoryLevels({ - inventory_item_id: request.body.inventory_item_id, - location_id: request.body.location_id, - stocked_quantity: request.body.quantity, - }) - - res.json({ inventory_level: inventoryLevel }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeInventoryModule } from "@medusajs/medusa/inventory" - -export async function POST(request: Request) { - const inventoryModuleService = await initializeInventoryModule({}) - const body = await request.json() - - const inventoryLevel = await inventoryModuleService.createInventoryLevels({ - inventory_item_id: body.inventory_item_id, - location_id: body.location_id, - stocked_quantity: body.quantity, - }) - - return NextResponse.json({ inventory_level: inventoryLevel }) -} -``` - - - - ---- - -## Adjust Inventory in Location - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const inventoryModuleService = request.scope.resolve( - Modules.INVENTORY - ) - - const inventoryLevel = await inventoryModuleService.adjustInventory( - request.body.inventory_item_id, - request.body.location_id, - request.body.new_quantity - ) - - res.json({ inventory_level: inventoryLevel }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeInventoryModule } from "@medusajs/medusa/inventory" - -export async function POST(request: Request) { - const inventoryModuleService = await initializeInventoryModule({}) - const body = await request.json() - - const inventoryLevel = await inventoryModuleService.adjustInventory( - body.inventory_item_id, - body.location_id, - body.new_quantity - ) - - return NextResponse.json({ inventory_level: inventoryLevel }) -} -``` - - - - ---- - -## Confirm Inventory Item Availability - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const inventoryModuleService = request.scope.resolve( - Modules.INVENTORY - ) - - res.json({ - is_available: await inventoryModuleService.confirmInventory( - request.body.inventory_item_id, - [request.body.location_id], - request.body.required_quantity - ), - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeInventoryModule } from "@medusajs/medusa/inventory" - -export async function POST(request: Request) { - const inventoryModuleService = await initializeInventoryModule({}) - const body = await request.json() - - return NextResponse.json({ - is_available: await inventoryModuleService.confirmInventory( - body.inventory_item_id, - [body.location_id], - body.required_quantity - ), - }) -} -``` - - - - ---- - -## Create Reservation Item - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const inventoryModuleService = request.scope.resolve( - Modules.INVENTORY - ) - - const reservationItem = await inventoryModuleService.createReservationItems({ - inventory_item_id: request.body.inventory_item_id, - location_id: request.body.location_id, - quantity: request.body.reserved_quantity, - }) - - res.json({ reservation_item: reservationItem }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeInventoryModule } from "@medusajs/medusa/inventory" - -export async function POST(request: Request) { - const inventoryModuleService = await initializeInventoryModule({}) - const body = await request.json() - - const reservationItem = await inventoryModuleService.createReservationItems({ - inventory_item_id: body.inventory_item_id, - location_id: body.location_id, - quantity: body.reserved_quantity, - }) - - return NextResponse.json({ - reservation_item: reservationItem, - }) -} -``` - - - - ---- - -## Retrieve Quantity Details - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const inventoryModuleService = request.scope.resolve( - Modules.INVENTORY - ) - - const reservedQuantity = - await inventoryModuleService.retrieveReservedQuantity( - request.params.inventory_item_id, - [request.params.location_id] - ) - const stockedQuantity = await inventoryModuleService.retrieveStockedQuantity( - request.params.inventory_item_id, - [request.params.location_id] - ) - const availableQuantity = - await inventoryModuleService.retrieveAvailableQuantity( - request.params.inventory_item_id, - [request.params.location_id] - ) - - res.json({ - reserved_quantity: reservedQuantity, - stocked_quantity: stockedQuantity, - available_quantity: availableQuantity, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeInventoryModule } from "@medusajs/medusa/inventory" - -type ContextType = { - params: { - inventory_item_id: string - location_id: string - } -} - -export async function POST(request: Request, { params }: ContextType) { - const inventoryModuleService = await initializeInventoryModule({}) - - const reservedQuantity = - await inventoryModuleService.retrieveReservedQuantity( - params.inventory_item_id, - [params.location_id] - ) - const stockedQuantity = await inventoryModuleService.retrieveStockedQuantity( - params.inventory_item_id, - [params.location_id] - ) - const availableQuantity = - await inventoryModuleService.retrieveAvailableQuantity( - params.inventory_item_id, - [params.location_id] - ) - - return NextResponse.json({ - reserved_quantity: reservedQuantity, - stocked_quantity: stockedQuantity, - available_quantity: availableQuantity, - }) -} -``` - - - - ---- - -## Delete a Reservation - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function DELETE( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const inventoryModuleService = request.scope.resolve( - Modules.INVENTORY - ) - - await inventoryModuleService.deleteReservationItems([ - request.params.reservation_id, - ]) - - res.status(200) -} -``` - - - - -```ts -import { initialize as initializeInventoryModule } from "@medusajs/medusa/inventory" - -type ContextType = { - params: { - reservation_id: string - } -} - -export async function DELETE(request: Request, { params }: ContextType) { - const inventoryModuleService = await initializeInventoryModule({}) - - await inventoryModuleService.deleteReservationItems([params.reservation_id]) -} -``` - - - - ---- - -## More Examples - -The [Inventory Module's main service reference](/references/inventory-next) provides a reference to all the methods available for use with examples for each. diff --git a/www/apps/resources/app/commerce-modules/inventory/page.mdx b/www/apps/resources/app/commerce-modules/inventory/page.mdx index 21e0be049d2da..ee13b06abbd83 100644 --- a/www/apps/resources/app/commerce-modules/inventory/page.mdx +++ b/www/apps/resources/app/commerce-modules/inventory/page.mdx @@ -6,130 +6,153 @@ export const metadata = { # {metadata.title} -The Inventory Module provides inventory-related features in your Medusa and Node.js applications. +In this section of the documentation, you will find resources to learn more about the Inventory Module and how to use it in your application. -## How to Use Inventory Module's Service +Medusa has inventory related features available out-of-the-box through the Inventory Module. A [module](!docs!/learn/fundamentals/modules) is a standalone package that provides features for a single domain. Each of Medusa's commerce features are placed in commerce modules, such as this Inventory Module. -You can use the Inventory Module's main service by resolving from the Medusa container the resource `Modules.INVENTORY`. + -For example: +Learn more about why modules are isolated in [this documentation](!docs!/learn/fundamentals/modules/isolation). - - + -```ts title="src/workflows/hello-world/step1.ts" -import { createStep } from "@medusajs/framework/workflows-sdk" -import { Modules } from "@medusajs/framework/utils" +## Inventory Features -const step1 = createStep("step-1", async (_, { container }) => { - const inventoryModuleService = container.resolve( - Modules.INVENTORY - ) +- [Inventory Items Management](./concepts/page.mdx): Store and manage inventory of any stock-kept item, such as product variants. +- [Inventory Across Locations](./concepts/page.mdx#inventorylevel): Manage inventory levels across different locations, such as warehouses. +- [Reservation Management](./concepts/page.mdx#reservationitem): Reserve quantities of inventory items at specific locations for orders or other purposes. +- [Check Inventory Availability](/references/inventory-next/confirmInventory): Check whether an inventory item has the necessary quantity for purchase. - const inventoryItems = await inventoryModuleService.listInventoryItems({}) -}) -``` +--- - - +## How to Use Inventory Module's Service -```ts title="src/api/store/custom/route.ts" -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" +In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. -export async function GET( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const inventoryModuleService = request.scope.resolve( - Modules.INVENTORY - ) - - res.json({ - inventory_items: await inventoryModuleService.listInventoryItems({}), - }) -} -``` +You can build custom workflows and steps. You can also re-use Medusa's workflows and steps, which are provided by the `@medusajs/medusa/core-flows` package. - - +For example: -```ts title="src/subscribers/custom-handler.ts" -import { SubscriberArgs } from "@medusajs/framework" +export const highlights = [ + ["12", "Modules.INVENTORY", "Resolve the module in a step."] +] + +```ts title="src/workflows/create-inventory-item.ts" highlights={highlights} +import { + createWorkflow, + WorkflowResponse, + createStep, + StepResponse, +} from "@medusajs/framework/workflows-sdk" import { Modules } from "@medusajs/framework/utils" -export default async function subscriberHandler({ container }: SubscriberArgs) { - const inventoryModuleService = container.resolve( - Modules.INVENTORY - ) - - const inventoryItems = await inventoryModuleService.listInventoryItems({}) -} -``` - - - - ---- - -## Features - -### Inventory Items Management - -Store and manage inventory of any stock-kept item, such as product variants. - -Inventory items hold details of the underlying stock-kept item, as well as inventory details such as whether the item requires shipping. +const createInventoryItemStep = createStep( + "create-inventory-item", + async ({}, { container }) => { + const inventoryModuleService = container.resolve(Modules.INVENTORY) -```ts -const inventoryItem = await inventoryModuleService.createInventoryItems({ - sku: "SHIRT", - title: "Green Medusa Shirt", - requires_shipping: true, -}) -``` + const inventoryItem = await inventoryModuleService.createInventoryItems({ + sku: "SHIRT", + title: "Green Medusa Shirt", + requires_shipping: true, + }) -### Inventory Across Locations + return new StepResponse({ inventoryItem }, inventoryItem.id) + }, + async (inventoryItemId, { container }) => { + const inventoryModuleService = container.resolve(Modules.INVENTORY) -Inventory items' quantities are set per locations through inventory levels. + await inventoryModuleService.deleteInventoryItems([inventoryItemId]) + } +) -This gives you more flexibility in managing the quantity of a stock-kept item across different locations, such as different warehouses. +export const createInventoryItemWorkflow = createWorkflow( + "create-inventory-item-workflow", + () => { + const { inventoryItem } = createInventoryItemStep() -```ts -const inventoryLevel = await inventoryModuleService.createInventoryLevels([ - { - inventory_item_id: "iitem_123", - location_id: "sloc_123", - stocked_quantity: 20, - }, -]) + return new WorkflowResponse({ + inventoryItem, + }) + } +) ``` -### Reservation Management +You can then execute the workflow in your custom API routes, scheduled jobs, or subscribers: -Reserve quantities of inventory items at specific locations for orders or other purposes. + + + + ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import type { + MedusaRequest, + MedusaResponse, + } from "@medusajs/framework/http" + import createInventoryItemWorkflow from "../../workflows/create-inventory-item" + + export async function GET( + req: MedusaRequest, + res: MedusaResponse + ) { + const { result } = await createInventoryItemWorkflow(req.scope) + .run() + + res.send(result) + } + ``` -The reserved quantity isn't considered for purchase, but can be deleted to revert the reservation. + + + + ```ts title="src/subscribers/customer-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import { + type SubscriberConfig, + type SubscriberArgs, + } from "@medusajs/framework" + import createInventoryItemWorkflow from "../workflows/create-inventory-item" + + export default async function handleCustomerCreate({ + event: { data }, + container, + }: SubscriberArgs<{ id: string }>) { + const { result } = await createInventoryItemWorkflow(container) + .run() + + console.log(result) + } + + export const config: SubscriberConfig = { + event: "user.created", + } + ``` -```ts -const reservationItem = await inventoryModuleService.createReservationItems([ - { - inventory_item_id: "iitem_123", - location_id: "sloc_123", - quantity: 10, - }, -]) -``` + + + + ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} + import { MedusaContainer } from "@medusajs/framework/types" + import createInventoryItemWorkflow from "../workflows/create-inventory-item" + + export default async function myCustomJob( + container: MedusaContainer + ) { + const { result } = await createInventoryItemWorkflow(container) + .run() + + console.log(result.message) + } + + export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, + }; + ``` -### Check Inventory Availability + + -Check whether an inventory item has the necessary quantity for purchase. +Learn more about workflows in [this documentation](!docs!/learn/fundamentals/workflows). -Any reserved quantity is considered unavailable. +--- -```ts -const isAvailable = await inventoryModuleService.confirmInventory( - inventoryItemId, - [locationId], - neededQuantity -) -``` + \ No newline at end of file diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index 933f8456f3faa..b2aa1d29c9288 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -29,9 +29,8 @@ export const generatedEditDates = { "app/commerce-modules/inventory/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/inventory/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/inventory/concepts/page.mdx": "2024-10-08T15:11:27.634Z", - "app/commerce-modules/inventory/examples/page.mdx": "2024-10-15T14:59:45.389Z", "app/commerce-modules/inventory/inventory-in-flows/page.mdx": "2024-10-08T15:14:07.327Z", - "app/commerce-modules/inventory/page.mdx": "2024-12-09T14:47:28.150Z", + "app/commerce-modules/inventory/page.mdx": "2024-12-25T14:21:22.529Z", "app/commerce-modules/order/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/order/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/order/claim/page.mdx": "2024-10-09T10:11:12.090Z", diff --git a/www/apps/resources/generated/files-map.mjs b/www/apps/resources/generated/files-map.mjs index eaa72b6342fd3..c9483c2e862bc 100644 --- a/www/apps/resources/generated/files-map.mjs +++ b/www/apps/resources/generated/files-map.mjs @@ -287,10 +287,6 @@ export const filesMap = [ "filePath": "/www/apps/resources/app/commerce-modules/inventory/concepts/page.mdx", "pathname": "/commerce-modules/inventory/concepts" }, - { - "filePath": "/www/apps/resources/app/commerce-modules/inventory/examples/page.mdx", - "pathname": "/commerce-modules/inventory/examples" - }, { "filePath": "/www/apps/resources/app/commerce-modules/inventory/inventory-in-flows/page.mdx", "pathname": "/commerce-modules/inventory/inventory-in-flows" diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs index 9193abf6b2297..af3f4f366e97d 100644 --- a/www/apps/resources/generated/sidebar.mjs +++ b/www/apps/resources/generated/sidebar.mjs @@ -3921,17 +3921,12 @@ export const generatedSidebar = [ "children": [] }, { - "loaded": true, - "isPathHref": true, - "type": "link", - "path": "/commerce-modules/inventory/examples", - "title": "Examples", - "children": [] + "type": "separator" }, { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", "title": "Concepts", "children": [ { @@ -3963,7 +3958,416 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", + "title": "Storefront Guides", + "autogenerate_tags": "storefront+inventory", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Retrieve Product Variant's Inventory in Storefront", + "path": "/storefront-development/products/inventory", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Workflows", + "autogenerate_tags": "workflow+inventory", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "addToCartWorkflow", + "path": "/references/medusa-workflows/addToCartWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "confirmVariantInventoryWorkflow", + "path": "/references/medusa-workflows/confirmVariantInventoryWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createCartWorkflow", + "path": "/references/medusa-workflows/createCartWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateLineItemInCartWorkflow", + "path": "/references/medusa-workflows/updateLineItemInCartWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "bulkCreateDeleteLevelsWorkflow", + "path": "/references/medusa-workflows/bulkCreateDeleteLevelsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createInventoryItemsWorkflow", + "path": "/references/medusa-workflows/createInventoryItemsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createInventoryLevelsWorkflow", + "path": "/references/medusa-workflows/createInventoryLevelsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteInventoryItemWorkflow", + "path": "/references/medusa-workflows/deleteInventoryItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateInventoryItemsWorkflow", + "path": "/references/medusa-workflows/updateInventoryItemsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateInventoryLevelsWorkflow", + "path": "/references/medusa-workflows/updateInventoryLevelsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "addOrderLineItemsWorkflow", + "path": "/references/medusa-workflows/addOrderLineItemsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelOrderClaimWorkflow", + "path": "/references/medusa-workflows/cancelOrderClaimWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelOrderExchangeWorkflow", + "path": "/references/medusa-workflows/cancelOrderExchangeWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelOrderFulfillmentWorkflow", + "path": "/references/medusa-workflows/cancelOrderFulfillmentWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelOrderWorkflow", + "path": "/references/medusa-workflows/cancelOrderWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "confirmClaimRequestWorkflow", + "path": "/references/medusa-workflows/confirmClaimRequestWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "confirmExchangeRequestWorkflow", + "path": "/references/medusa-workflows/confirmExchangeRequestWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "confirmOrderEditRequestWorkflow", + "path": "/references/medusa-workflows/confirmOrderEditRequestWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "confirmReturnReceiveWorkflow", + "path": "/references/medusa-workflows/confirmReturnReceiveWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createOrderFulfillmentWorkflow", + "path": "/references/medusa-workflows/createOrderFulfillmentWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createOrderWorkflow", + "path": "/references/medusa-workflows/createOrderWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderClaimAddNewItemWorkflow", + "path": "/references/medusa-workflows/orderClaimAddNewItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderEditAddNewItemWorkflow", + "path": "/references/medusa-workflows/orderEditAddNewItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderExchangeAddNewItemWorkflow", + "path": "/references/medusa-workflows/orderExchangeAddNewItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "batchProductVariantsWorkflow", + "path": "/references/medusa-workflows/batchProductVariantsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "batchProductsWorkflow", + "path": "/references/medusa-workflows/batchProductsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createProductVariantsWorkflow", + "path": "/references/medusa-workflows/createProductVariantsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createProductsWorkflow", + "path": "/references/medusa-workflows/createProductsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteProductVariantsWorkflow", + "path": "/references/medusa-workflows/deleteProductVariantsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteProductsWorkflow", + "path": "/references/medusa-workflows/deleteProductsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createReservationsWorkflow", + "path": "/references/medusa-workflows/createReservationsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteReservationsByLineItemsWorkflow", + "path": "/references/medusa-workflows/deleteReservationsByLineItemsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteReservationsWorkflow", + "path": "/references/medusa-workflows/deleteReservationsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateReservationsWorkflow", + "path": "/references/medusa-workflows/updateReservationsWorkflow", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Steps", + "autogenerate_tags": "step+inventory", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "confirmInventoryStep", + "path": "/references/medusa-workflows/steps/confirmInventoryStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "reserveInventoryStep", + "path": "/references/medusa-workflows/steps/reserveInventoryStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "adjustInventoryLevelsStep", + "path": "/references/medusa-workflows/steps/adjustInventoryLevelsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createInventoryItemsStep", + "path": "/references/medusa-workflows/steps/createInventoryItemsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createInventoryLevelsStep", + "path": "/references/medusa-workflows/steps/createInventoryLevelsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteInventoryItemStep", + "path": "/references/medusa-workflows/steps/deleteInventoryItemStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateInventoryItemsStep", + "path": "/references/medusa-workflows/steps/updateInventoryItemsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateInventoryLevelsStep", + "path": "/references/medusa-workflows/steps/updateInventoryLevelsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createReservationsStep", + "path": "/references/medusa-workflows/steps/createReservationsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteReservationsByLineItemsStep", + "path": "/references/medusa-workflows/steps/deleteReservationsByLineItemsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteReservationsStep", + "path": "/references/medusa-workflows/steps/deleteReservationsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateReservationsStep", + "path": "/references/medusa-workflows/steps/updateReservationsStep", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", "title": "References", "children": [ { diff --git a/www/apps/resources/sidebars/inventory.mjs b/www/apps/resources/sidebars/inventory.mjs index 4d32a13a7546a..9308b16a37ac6 100644 --- a/www/apps/resources/sidebars/inventory.mjs +++ b/www/apps/resources/sidebars/inventory.mjs @@ -11,12 +11,10 @@ export const inventorySidebar = [ title: "Overview", }, { - type: "link", - path: "/commerce-modules/inventory/examples", - title: "Examples", + type: "separator", }, { - type: "sub-category", + type: "category", title: "Concepts", children: [ { @@ -37,7 +35,49 @@ export const inventorySidebar = [ ], }, { - type: "sub-category", + type: "category", + title: "Server Guides", + autogenerate_tags: "server+inventory", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Storefront Guides", + autogenerate_tags: "storefront+inventory", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Admin Guides", + autogenerate_tags: "admin+inventory", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "User Guides", + autogenerate_tags: "userGuides+inventory", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Workflows", + autogenerate_tags: "workflow+inventory", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Steps", + autogenerate_tags: "step+inventory", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", title: "References", children: [ { diff --git a/www/packages/tags/src/tags/index.ts b/www/packages/tags/src/tags/index.ts index 2a6190655b08c..c9f5a6ebbef9d 100644 --- a/www/packages/tags/src/tags/index.ts +++ b/www/packages/tags/src/tags/index.ts @@ -1,31 +1,31 @@ export * from "./product.js" -export * from "./pricing.js" -export * from "./storefront.js" +export * from "./tax.js" export * from "./order.js" -export * from "./stripe.js" +export * from "./storefront.js" export * from "./payment.js" +export * from "./stripe.js" export * from "./fulfillment.js" export * from "./customer.js" export * from "./auth.js" -export * from "./product-category.js" export * from "./product-collection.js" -export * from "./inventory.js" -export * from "./tax.js" -export * from "./query.js" export * from "./cart.js" -export * from "./region.js" -export * from "./step.js" +export * from "./inventory.js" +export * from "./publishable-api-key.js" +export * from "./pricing.js" +export * from "./product-category.js" export * from "./sales-channel.js" +export * from "./region.js" +export * from "./remote-link.js" export * from "./workflow.js" +export * from "./query.js" export * from "./remote-query.js" -export * from "./api-key.js" -export * from "./remote-link.js" -export * from "./publishable-api-key.js" export * from "./store.js" -export * from "./user.js" -export * from "./logger.js" -export * from "./promotion.js" export * from "./locking.js" -export * from "./file.js" -export * from "./event-bus.js" +export * from "./promotion.js" +export * from "./step.js" +export * from "./api-key.js" +export * from "./logger.js" +export * from "./user.js" export * from "./stock-location.js" +export * from "./event-bus.js" +export * from "./file.js" From 233ec2cb7367470b359032451045f0e4e1a5363d Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Wed, 25 Dec 2024 16:37:45 +0200 Subject: [PATCH 10/21] revise order module --- .../app/commerce-modules/order/page.mdx | 254 ++-- www/apps/resources/generated/edit-dates.mjs | 2 +- www/apps/resources/generated/sidebar.mjs | 1035 ++++++++++++++++- www/apps/resources/sidebars/cart.mjs | 2 + www/apps/resources/sidebars/currency.mjs | 2 + www/apps/resources/sidebars/customer.mjs | 2 + www/apps/resources/sidebars/fulfillment.mjs | 2 + www/apps/resources/sidebars/inventory.mjs | 2 + www/apps/resources/sidebars/order-module.mjs | 48 +- www/packages/tags/src/tags/index.ts | 26 +- 10 files changed, 1243 insertions(+), 132 deletions(-) diff --git a/www/apps/resources/app/commerce-modules/order/page.mdx b/www/apps/resources/app/commerce-modules/order/page.mdx index 250cf062f6f2c..6002dfe9430bd 100644 --- a/www/apps/resources/app/commerce-modules/order/page.mdx +++ b/www/apps/resources/app/commerce-modules/order/page.mdx @@ -6,138 +6,166 @@ export const metadata = { # {metadata.title} -The Order Module provides order-related features in your Medusa and Node.js applications. +In this section of the documentation, you will find resources to learn more about the Order Module and how to use it in your application. -## How to Use Order Module's Service +Medusa has order related features available out-of-the-box through the Order Module. A [module](!docs!/learn/fundamentals/modules) is a standalone package that provides features for a single domain. Each of Medusa's commerce features are placed in commerce modules, such as this Order Module. -You can use the Order Module's main service by resolving from the Medusa container the resource `Modules.ORDER`. + -For example: +Learn more about why modules are isolated in [this documentation](!docs!/learn/fundamentals/modules/isolation). - - + -```ts title="src/workflows/hello-world/step1.ts" -import { createStep } from "@medusajs/framework/workflows-sdk" -import { Modules } from "@medusajs/framework/utils" - -const step1 = createStep("step-1", async (_, { container }) => { - const orderModuleService = container.resolve( - Modules.ORDER - ) - const orders = await orderModuleService.listOrders() -}) -``` +## Order Features - - - -```ts title="src/api/store/custom/route.ts" -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" +- [Order Management](./concepts/page.mdx): Store and manage your orders to retrieve, create, cancel, and perform other operations. +- Draft Orders: Allow merchants to create orders on behalf of their customers as draft orders that later are transformed to regular orders. +- [Apply Promotion Adjustments](./promotion-adjustments/page.mdx): Apply promotions or discounts to the order's items and shipping methods by adding adjustment lines that are factored into their subtotals. +- [Apply Tax Lines](./tax-lines/page.mdx): Apply tax lines to an order's line items and shipping methods. +- [Returns](./return/page.mdx), [Edits](./edit/page.mdx), [Exchanges](./exchange/page.mdx), and [Claims](./claim/page.mdx): Make [changes](./order-change/page.mdx) to an order to edit, return, or exchange its items, with [version-based control](./order-versioning/page.mdx) over the order's timeline. -export async function GET( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const orderModuleService = req.scope.resolve( - Modules.ORDER - ) - - res.json({ - orders: await orderModuleService.listOrders(), - }) -} -``` - - - +--- -```ts title="src/subscribers/custom-handler.ts" -import { SubscriberArgs } from "@medusajs/framework" -import { Modules } from "@medusajs/framework/utils" +## How to Use Order Module's Service -export default async function subscriberHandler({ container }: SubscriberArgs) { - const orderModuleService = container.resolve( - Modules.ORDER - ) +In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. - const orders = await orderModuleService.listOrders() -} -``` +You can build custom workflows and steps. You can also re-use Medusa's workflows and steps, which are provided by the `@medusajs/medusa/core-flows` package. - - +For example: ---- +export const highlights = [ + ["12", "Modules.ORDER", "Resolve the module in a step."] +] + +```ts title="src/workflows/create-draft-order.ts" highlights={highlights} +import { + createWorkflow, + WorkflowResponse, + createStep, + StepResponse, +} from "@medusajs/framework/workflows-sdk" +import { Modules } from "@medusajs/framework/utils" -## Features - -### Order Management - -Store and manage your orders to retrieve, create, cancel, and perform other operations. - -```ts -const order = await orderModuleService.createOrders({ - currency_code: "usd", - items: [ - { - title: "Shirt", - quantity: 1, - unit_price: 3000, - }, - ], - shipping_methods: [ - { - name: "Express shipping", - amount: 3000, - }, - ], -}) +const createDraftOrderStep = createStep( + "create-order", + async ({}, { container }) => { + const orderModuleService = container.resolve(Modules.ORDER) + + const draftOrder = await orderModuleService.createOrders({ + currency_code: "usd", + items: [ + { + title: "Shirt", + quantity: 1, + unit_price: 3000, + }, + ], + shipping_methods: [ + { + name: "Express shipping", + amount: 3000, + }, + ], + status: "draft", + is_draft_order: true, + }) + + return new StepResponse({ draftOrder }, draftOrder.id) + }, + async (draftOrderId, { container }) => { + const orderModuleService = container.resolve(Modules.ORDER) + + await orderModuleService.deleteOrders([draftOrderId]) + } +) + +export const createDraftOrderWorkflow = createWorkflow( + "create-draft-order", + () => { + const { draftOrder } = createDraftOrderStep() + + return new WorkflowResponse({ + draftOrder, + }) +) ``` -### Draft Orders - -Allow merchants to create orders on behalf of their customers as draft orders that later are transformed to regular orders. - -```ts -const draftOrder = await orderModuleService.createOrders({ - currency_code: "usd", - // other details... - status: "draft", - is_draft_order: true, -}) -``` +You can then execute the workflow in your custom API routes, scheduled jobs, or subscribers: -### Apply Promotions + + + + ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import type { + MedusaRequest, + MedusaResponse, + } from "@medusajs/framework/http" + import createDraftOrderWorkflow from "../../workflows/create-draft-order" + + export async function GET( + req: MedusaRequest, + res: MedusaResponse + ) { + const { result } = await createDraftOrderWorkflow(req.scope) + .run() + + res.send(result) + } + ``` -Apply promotions or discounts to the order's items and shipping methods by adding adjustment lines that are factored into their subtotals. + + + + ```ts title="src/subscribers/customer-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import { + type SubscriberConfig, + type SubscriberArgs, + } from "@medusajs/framework" + import createDraftOrderWorkflow from "../workflows/create-draft-order" + + export default async function handleCustomerCreate({ + event: { data }, + container, + }: SubscriberArgs<{ id: string }>) { + const { result } = await createDraftOrderWorkflow(container) + .run() + + console.log(result) + } + + export const config: SubscriberConfig = { + event: "user.created", + } + ``` -```ts -const lineAdjustments = await orderModuleService.createOrderLineItemAdjustments({ - item_id: "cali_123", - code: "50OFF", - amount: 500, -}) + + + + ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} + import { MedusaContainer } from "@medusajs/framework/types" + import createDraftOrderWorkflow from "../workflows/create-draft-order" + + export default async function myCustomJob( + container: MedusaContainer + ) { + const { result } = await createDraftOrderWorkflow(container) + .run() + + console.log(result.message) + } + + export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, + }; + ``` -const shippingAdjustments = - await orderModuleService.createOrderShippingMethodAdjustments({ - shipping_method_id: "casm_123", - code: "FREESHIPPING", - amount: 1000, - }) -``` + + -### Returns, Exchanges, and Claims +Learn more about workflows in [this documentation](!docs!/learn/fundamentals/workflows). -Return or exchange items, with version-based control over the order's timeline. +--- -```ts -const orderReturn = await orderModuleService.createReturn({ - order_id: "order_123", - items: [{ - id: "orditem_123", - quantity: 1, - }], -}) -``` + \ No newline at end of file diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index b2aa1d29c9288..3355710b78895 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -41,7 +41,7 @@ export const generatedEditDates = { "app/commerce-modules/order/return/page.mdx": "2024-10-09T10:19:40.731Z", "app/commerce-modules/order/tax-lines/page.mdx": "2024-10-09T10:22:49.335Z", "app/commerce-modules/order/transactions/page.mdx": "2024-10-09T10:23:36.485Z", - "app/commerce-modules/order/page.mdx": "2024-12-09T14:47:32.415Z", + "app/commerce-modules/order/page.mdx": "2024-12-25T14:34:00.973Z", "app/commerce-modules/payment/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/payment/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/payment/examples/page.mdx": "2024-10-15T14:59:55.208Z", diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs index af3f4f366e97d..a9b1fa2371b3a 100644 --- a/www/apps/resources/generated/sidebar.mjs +++ b/www/apps/resources/generated/sidebar.mjs @@ -955,6 +955,7 @@ export const generatedSidebar = [ "isPathHref": true, "type": "category", "title": "Concepts", + "initialOpen": false, "children": [ { "loaded": true, @@ -1319,6 +1320,7 @@ export const generatedSidebar = [ "isPathHref": true, "type": "category", "title": "References", + "initialOpen": false, "children": [ { "loaded": true, @@ -1867,6 +1869,7 @@ export const generatedSidebar = [ "isPathHref": true, "type": "sub-category", "title": "Concepts", + "initialOpen": false, "children": [ { "loaded": true, @@ -1883,6 +1886,7 @@ export const generatedSidebar = [ "isPathHref": true, "type": "sub-category", "title": "References", + "initialOpen": false, "children": [ { "loaded": true, @@ -1983,6 +1987,7 @@ export const generatedSidebar = [ "isPathHref": true, "type": "category", "title": "Concepts", + "initialOpen": false, "children": [ { "loaded": true, @@ -2403,6 +2408,7 @@ export const generatedSidebar = [ "isPathHref": true, "type": "category", "title": "References", + "initialOpen": false, "children": [ { "loaded": true, @@ -2719,6 +2725,7 @@ export const generatedSidebar = [ "isPathHref": true, "type": "category", "title": "Concepts", + "initialOpen": false, "children": [ { "loaded": true, @@ -3203,6 +3210,7 @@ export const generatedSidebar = [ "isPathHref": true, "type": "category", "title": "References", + "initialOpen": false, "children": [ { "loaded": true, @@ -3928,6 +3936,7 @@ export const generatedSidebar = [ "isPathHref": true, "type": "category", "title": "Concepts", + "initialOpen": false, "children": [ { "loaded": true, @@ -4369,6 +4378,7 @@ export const generatedSidebar = [ "isPathHref": true, "type": "category", "title": "References", + "initialOpen": false, "children": [ { "loaded": true, @@ -4744,8 +4754,9 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", "title": "Concepts", + "initialOpen": false, "children": [ { "loaded": true, @@ -4840,8 +4851,1026 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "sub-category", - "title": "References", + "type": "category", + "title": "Storefront Guides", + "autogenerate_tags": "storefront+order", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Checkout Step 5: Complete Cart", + "path": "/storefront-development/checkout/complete-cart", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Workflows", + "autogenerate_tags": "workflow+order", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "acceptOrderTransferWorkflow", + "path": "/references/medusa-workflows/acceptOrderTransferWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "addOrderLineItemsWorkflow", + "path": "/references/medusa-workflows/addOrderLineItemsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "archiveOrderWorkflow", + "path": "/references/medusa-workflows/archiveOrderWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "beginClaimOrderWorkflow", + "path": "/references/medusa-workflows/beginClaimOrderWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "beginExchangeOrderWorkflow", + "path": "/references/medusa-workflows/beginExchangeOrderWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "beginOrderEditOrderWorkflow", + "path": "/references/medusa-workflows/beginOrderEditOrderWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "beginReceiveReturnWorkflow", + "path": "/references/medusa-workflows/beginReceiveReturnWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "beginReturnOrderWorkflow", + "path": "/references/medusa-workflows/beginReturnOrderWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelBeginOrderClaimWorkflow", + "path": "/references/medusa-workflows/cancelBeginOrderClaimWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelBeginOrderEditWorkflow", + "path": "/references/medusa-workflows/cancelBeginOrderEditWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelBeginOrderExchangeWorkflow", + "path": "/references/medusa-workflows/cancelBeginOrderExchangeWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelOrderChangeWorkflow", + "path": "/references/medusa-workflows/cancelOrderChangeWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelOrderClaimWorkflow", + "path": "/references/medusa-workflows/cancelOrderClaimWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelOrderExchangeWorkflow", + "path": "/references/medusa-workflows/cancelOrderExchangeWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelOrderFulfillmentWorkflow", + "path": "/references/medusa-workflows/cancelOrderFulfillmentWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelOrderTransferRequestWorkflow", + "path": "/references/medusa-workflows/cancelOrderTransferRequestWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelOrderWorkflow", + "path": "/references/medusa-workflows/cancelOrderWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelReturnReceiveWorkflow", + "path": "/references/medusa-workflows/cancelReturnReceiveWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelReturnRequestWorkflow", + "path": "/references/medusa-workflows/cancelReturnRequestWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelReturnWorkflow", + "path": "/references/medusa-workflows/cancelReturnWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "completeOrderWorkflow", + "path": "/references/medusa-workflows/completeOrderWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "confirmClaimRequestWorkflow", + "path": "/references/medusa-workflows/confirmClaimRequestWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "confirmExchangeRequestWorkflow", + "path": "/references/medusa-workflows/confirmExchangeRequestWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "confirmOrderEditRequestWorkflow", + "path": "/references/medusa-workflows/confirmOrderEditRequestWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "confirmReturnReceiveWorkflow", + "path": "/references/medusa-workflows/confirmReturnReceiveWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "confirmReturnRequestWorkflow", + "path": "/references/medusa-workflows/confirmReturnRequestWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createAndCompleteReturnOrderWorkflow", + "path": "/references/medusa-workflows/createAndCompleteReturnOrderWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createClaimShippingMethodWorkflow", + "path": "/references/medusa-workflows/createClaimShippingMethodWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createExchangeShippingMethodWorkflow", + "path": "/references/medusa-workflows/createExchangeShippingMethodWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createOrderChangeWorkflow", + "path": "/references/medusa-workflows/createOrderChangeWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createOrderEditShippingMethodWorkflow", + "path": "/references/medusa-workflows/createOrderEditShippingMethodWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createOrderFulfillmentWorkflow", + "path": "/references/medusa-workflows/createOrderFulfillmentWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createOrderShipmentWorkflow", + "path": "/references/medusa-workflows/createOrderShipmentWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createOrderWorkflow", + "path": "/references/medusa-workflows/createOrderWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createReturnShippingMethodWorkflow", + "path": "/references/medusa-workflows/createReturnShippingMethodWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "declineOrderChangeWorkflow", + "path": "/references/medusa-workflows/declineOrderChangeWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "declineOrderTransferRequestWorkflow", + "path": "/references/medusa-workflows/declineOrderTransferRequestWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteOrderChangeActionsWorkflow", + "path": "/references/medusa-workflows/deleteOrderChangeActionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteOrderChangeWorkflow", + "path": "/references/medusa-workflows/deleteOrderChangeWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "dismissItemReturnRequestWorkflow", + "path": "/references/medusa-workflows/dismissItemReturnRequestWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "markPaymentCollectionAsPaid", + "path": "/references/medusa-workflows/markPaymentCollectionAsPaid", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderClaimAddNewItemWorkflow", + "path": "/references/medusa-workflows/orderClaimAddNewItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderClaimItemWorkflow", + "path": "/references/medusa-workflows/orderClaimItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderClaimRequestItemReturnWorkflow", + "path": "/references/medusa-workflows/orderClaimRequestItemReturnWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderEditAddNewItemWorkflow", + "path": "/references/medusa-workflows/orderEditAddNewItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderEditUpdateItemQuantityWorkflow", + "path": "/references/medusa-workflows/orderEditUpdateItemQuantityWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderExchangeAddNewItemWorkflow", + "path": "/references/medusa-workflows/orderExchangeAddNewItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderExchangeRequestItemReturnWorkflow", + "path": "/references/medusa-workflows/orderExchangeRequestItemReturnWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "receiveItemReturnRequestWorkflow", + "path": "/references/medusa-workflows/receiveItemReturnRequestWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "removeAddItemClaimActionWorkflow", + "path": "/references/medusa-workflows/removeAddItemClaimActionWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "removeClaimShippingMethodWorkflow", + "path": "/references/medusa-workflows/removeClaimShippingMethodWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "removeExchangeShippingMethodWorkflow", + "path": "/references/medusa-workflows/removeExchangeShippingMethodWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "removeItemClaimActionWorkflow", + "path": "/references/medusa-workflows/removeItemClaimActionWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "removeItemExchangeActionWorkflow", + "path": "/references/medusa-workflows/removeItemExchangeActionWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "removeItemOrderEditActionWorkflow", + "path": "/references/medusa-workflows/removeItemOrderEditActionWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "removeItemReceiveReturnActionWorkflow", + "path": "/references/medusa-workflows/removeItemReceiveReturnActionWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "removeItemReturnActionWorkflow", + "path": "/references/medusa-workflows/removeItemReturnActionWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "removeOrderEditShippingMethodWorkflow", + "path": "/references/medusa-workflows/removeOrderEditShippingMethodWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "removeReturnShippingMethodWorkflow", + "path": "/references/medusa-workflows/removeReturnShippingMethodWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "requestItemReturnWorkflow", + "path": "/references/medusa-workflows/requestItemReturnWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "requestOrderEditRequestWorkflow", + "path": "/references/medusa-workflows/requestOrderEditRequestWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "requestOrderTransferWorkflow", + "path": "/references/medusa-workflows/requestOrderTransferWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateClaimAddItemWorkflow", + "path": "/references/medusa-workflows/updateClaimAddItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateClaimItemWorkflow", + "path": "/references/medusa-workflows/updateClaimItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateClaimShippingMethodWorkflow", + "path": "/references/medusa-workflows/updateClaimShippingMethodWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateExchangeAddItemWorkflow", + "path": "/references/medusa-workflows/updateExchangeAddItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateExchangeShippingMethodWorkflow", + "path": "/references/medusa-workflows/updateExchangeShippingMethodWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateOrderChangeActionsWorkflow", + "path": "/references/medusa-workflows/updateOrderChangeActionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateOrderChangesWorkflow", + "path": "/references/medusa-workflows/updateOrderChangesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateOrderEditAddItemWorkflow", + "path": "/references/medusa-workflows/updateOrderEditAddItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateOrderEditItemQuantityWorkflow", + "path": "/references/medusa-workflows/updateOrderEditItemQuantityWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateOrderEditShippingMethodWorkflow", + "path": "/references/medusa-workflows/updateOrderEditShippingMethodWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateOrderTaxLinesWorkflow", + "path": "/references/medusa-workflows/updateOrderTaxLinesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateOrderWorkflow", + "path": "/references/medusa-workflows/updateOrderWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateReceiveItemReturnRequestWorkflow", + "path": "/references/medusa-workflows/updateReceiveItemReturnRequestWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateRequestItemReturnWorkflow", + "path": "/references/medusa-workflows/updateRequestItemReturnWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateReturnShippingMethodWorkflow", + "path": "/references/medusa-workflows/updateReturnShippingMethodWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateReturnWorkflow", + "path": "/references/medusa-workflows/updateReturnWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "capturePaymentWorkflow", + "path": "/references/medusa-workflows/capturePaymentWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "processPaymentWorkflow", + "path": "/references/medusa-workflows/processPaymentWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "refundPaymentWorkflow", + "path": "/references/medusa-workflows/refundPaymentWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createReturnReasonsWorkflow", + "path": "/references/medusa-workflows/createReturnReasonsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteReturnReasonsWorkflow", + "path": "/references/medusa-workflows/deleteReturnReasonsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateReturnReasonsWorkflow", + "path": "/references/medusa-workflows/updateReturnReasonsWorkflow", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Steps", + "autogenerate_tags": "step+order", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "addOrderTransactionStep", + "path": "/references/medusa-workflows/steps/addOrderTransactionStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "archiveOrdersStep", + "path": "/references/medusa-workflows/steps/archiveOrdersStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelOrderChangeStep", + "path": "/references/medusa-workflows/steps/cancelOrderChangeStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelOrderClaimStep", + "path": "/references/medusa-workflows/steps/cancelOrderClaimStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelOrderExchangeStep", + "path": "/references/medusa-workflows/steps/cancelOrderExchangeStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelOrderFulfillmentStep", + "path": "/references/medusa-workflows/steps/cancelOrderFulfillmentStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelOrderReturnStep", + "path": "/references/medusa-workflows/steps/cancelOrderReturnStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelOrdersStep", + "path": "/references/medusa-workflows/steps/cancelOrdersStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "completeOrdersStep", + "path": "/references/medusa-workflows/steps/completeOrdersStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createCompleteReturnStep", + "path": "/references/medusa-workflows/steps/createCompleteReturnStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createOrderChangeStep", + "path": "/references/medusa-workflows/steps/createOrderChangeStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createOrderClaimItemsFromActionsStep", + "path": "/references/medusa-workflows/steps/createOrderClaimItemsFromActionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createOrderClaimsStep", + "path": "/references/medusa-workflows/steps/createOrderClaimsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createOrderExchangeItemsFromActionsStep", + "path": "/references/medusa-workflows/steps/createOrderExchangeItemsFromActionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createOrderExchangesStep", + "path": "/references/medusa-workflows/steps/createOrderExchangesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createOrderLineItemsStep", + "path": "/references/medusa-workflows/steps/createOrderLineItemsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createOrdersStep", + "path": "/references/medusa-workflows/steps/createOrdersStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createReturnsStep", + "path": "/references/medusa-workflows/steps/createReturnsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "declineOrderChangeStep", + "path": "/references/medusa-workflows/steps/declineOrderChangeStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteClaimsStep", + "path": "/references/medusa-workflows/steps/deleteClaimsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteExchangesStep", + "path": "/references/medusa-workflows/steps/deleteExchangesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteOrderChangeActionsStep", + "path": "/references/medusa-workflows/steps/deleteOrderChangeActionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteOrderChangesStep", + "path": "/references/medusa-workflows/steps/deleteOrderChangesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteOrderShippingMethods", + "path": "/references/medusa-workflows/steps/deleteOrderShippingMethods", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteReturnsStep", + "path": "/references/medusa-workflows/steps/deleteReturnsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "previewOrderChangeStep", + "path": "/references/medusa-workflows/steps/previewOrderChangeStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "registerOrderChangesStep", + "path": "/references/medusa-workflows/steps/registerOrderChangesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "registerOrderFulfillmentStep", + "path": "/references/medusa-workflows/steps/registerOrderFulfillmentStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "registerOrderShipmentStep", + "path": "/references/medusa-workflows/steps/registerOrderShipmentStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "setOrderTaxLinesForItemsStep", + "path": "/references/medusa-workflows/steps/setOrderTaxLinesForItemsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateOrderChangeActionsStep", + "path": "/references/medusa-workflows/steps/updateOrderChangeActionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateOrderChangesStep", + "path": "/references/medusa-workflows/steps/updateOrderChangesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateOrderExchangesStep", + "path": "/references/medusa-workflows/steps/updateOrderExchangesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateOrderShippingMethodsStep", + "path": "/references/medusa-workflows/steps/updateOrderShippingMethodsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateOrdersStep", + "path": "/references/medusa-workflows/steps/updateOrdersStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createReturnReasonsStep", + "path": "/references/medusa-workflows/steps/createReturnReasonsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteReturnReasonStep", + "path": "/references/medusa-workflows/steps/deleteReturnReasonStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateReturnReasonsStep", + "path": "/references/medusa-workflows/steps/updateReturnReasonsStep", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "References", + "initialOpen": false, "children": [ { "loaded": true, diff --git a/www/apps/resources/sidebars/cart.mjs b/www/apps/resources/sidebars/cart.mjs index 315d5f0e9e4ea..015ffacfd1b0f 100644 --- a/www/apps/resources/sidebars/cart.mjs +++ b/www/apps/resources/sidebars/cart.mjs @@ -16,6 +16,7 @@ export const cartSidebar = [ { type: "category", title: "Concepts", + initialOpen: false, children: [ { type: "link", @@ -91,6 +92,7 @@ export const cartSidebar = [ { type: "category", title: "References", + initialOpen: false, children: [ { type: "link", diff --git a/www/apps/resources/sidebars/currency.mjs b/www/apps/resources/sidebars/currency.mjs index 77975e7798628..f2c2796a4b388 100644 --- a/www/apps/resources/sidebars/currency.mjs +++ b/www/apps/resources/sidebars/currency.mjs @@ -16,6 +16,7 @@ export const currencySidebar = [ { type: "sub-category", title: "Concepts", + initialOpen: false, children: [ { type: "link", @@ -69,6 +70,7 @@ export const currencySidebar = [ { type: "sub-category", title: "References", + initialOpen: false, children: [ { type: "link", diff --git a/www/apps/resources/sidebars/customer.mjs b/www/apps/resources/sidebars/customer.mjs index 5abeadf8deebd..25ed586ba4521 100644 --- a/www/apps/resources/sidebars/customer.mjs +++ b/www/apps/resources/sidebars/customer.mjs @@ -16,6 +16,7 @@ export const customerSidebar = [ { type: "category", title: "Concepts", + initialOpen: false, children: [ { type: "link", @@ -81,6 +82,7 @@ export const customerSidebar = [ { type: "category", title: "References", + initialOpen: false, children: [ { type: "link", diff --git a/www/apps/resources/sidebars/fulfillment.mjs b/www/apps/resources/sidebars/fulfillment.mjs index 37c9aa6230fd7..22eda06b5b202 100644 --- a/www/apps/resources/sidebars/fulfillment.mjs +++ b/www/apps/resources/sidebars/fulfillment.mjs @@ -21,6 +21,7 @@ export const fulfillmentSidebar = [ { type: "category", title: "Concepts", + initialOpen: false, children: [ { type: "link", @@ -106,6 +107,7 @@ export const fulfillmentSidebar = [ { type: "category", title: "References", + initialOpen: false, children: [ { type: "link", diff --git a/www/apps/resources/sidebars/inventory.mjs b/www/apps/resources/sidebars/inventory.mjs index 9308b16a37ac6..ed2c3d1ceafd4 100644 --- a/www/apps/resources/sidebars/inventory.mjs +++ b/www/apps/resources/sidebars/inventory.mjs @@ -16,6 +16,7 @@ export const inventorySidebar = [ { type: "category", title: "Concepts", + initialOpen: false, children: [ { type: "link", @@ -79,6 +80,7 @@ export const inventorySidebar = [ { type: "category", title: "References", + initialOpen: false, children: [ { type: "link", diff --git a/www/apps/resources/sidebars/order-module.mjs b/www/apps/resources/sidebars/order-module.mjs index 1142348b9fc70..d7b7ec55f62ce 100644 --- a/www/apps/resources/sidebars/order-module.mjs +++ b/www/apps/resources/sidebars/order-module.mjs @@ -11,8 +11,9 @@ export const orderSidebar = [ title: "Overview", }, { - type: "sub-category", + type: "category", title: "Concepts", + initialOpen: false, children: [ { type: "link", @@ -72,8 +73,51 @@ export const orderSidebar = [ ], }, { - type: "sub-category", + type: "category", + title: "Server Guides", + autogenerate_tags: "server+order", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Storefront Guides", + autogenerate_tags: "storefront+order", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Admin Guides", + autogenerate_tags: "admin+order", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "User Guides", + autogenerate_tags: "userGuides+order", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Workflows", + autogenerate_tags: "workflow+order", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Steps", + autogenerate_tags: "step+order", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", title: "References", + initialOpen: false, children: [ { type: "link", diff --git a/www/packages/tags/src/tags/index.ts b/www/packages/tags/src/tags/index.ts index c9f5a6ebbef9d..cff170c6c0d39 100644 --- a/www/packages/tags/src/tags/index.ts +++ b/www/packages/tags/src/tags/index.ts @@ -1,31 +1,31 @@ export * from "./product.js" -export * from "./tax.js" -export * from "./order.js" +export * from "./cart.js" export * from "./storefront.js" +export * from "./order.js" export * from "./payment.js" export * from "./stripe.js" export * from "./fulfillment.js" export * from "./customer.js" export * from "./auth.js" +export * from "./product-category.js" export * from "./product-collection.js" -export * from "./cart.js" +export * from "./tax.js" export * from "./inventory.js" -export * from "./publishable-api-key.js" export * from "./pricing.js" -export * from "./product-category.js" -export * from "./sales-channel.js" -export * from "./region.js" +export * from "./api-key.js" +export * from "./step.js" export * from "./remote-link.js" export * from "./workflow.js" +export * from "./sales-channel.js" export * from "./query.js" +export * from "./logger.js" export * from "./remote-query.js" +export * from "./promotion.js" export * from "./store.js" +export * from "./publishable-api-key.js" +export * from "./region.js" +export * from "./stock-location.js" export * from "./locking.js" -export * from "./promotion.js" -export * from "./step.js" -export * from "./api-key.js" -export * from "./logger.js" +export * from "./file.js" export * from "./user.js" -export * from "./stock-location.js" export * from "./event-bus.js" -export * from "./file.js" From 654b21ffff8b90ff4e10dd84ef95431281be1aa9 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Wed, 25 Dec 2024 17:03:18 +0200 Subject: [PATCH 11/21] revise payment --- .../payment/examples/page.mdx | 359 ------------------ .../app/commerce-modules/payment/page.mdx | 230 ++++++----- .../guides/customize-stripe/page.mdx | 6 + www/apps/resources/generated/edit-dates.mjs | 5 +- www/apps/resources/generated/files-map.mjs | 4 - www/apps/resources/generated/sidebar.mjs | 277 +++++++++++++- www/apps/resources/sidebars/order-module.mjs | 3 + www/apps/resources/sidebars/payment.mjs | 57 ++- www/packages/tags/src/tags/index.ts | 28 +- www/packages/tags/src/tags/payment.ts | 4 + www/packages/tags/src/tags/storefront.ts | 4 + 11 files changed, 479 insertions(+), 498 deletions(-) delete mode 100644 www/apps/resources/app/commerce-modules/payment/examples/page.mdx diff --git a/www/apps/resources/app/commerce-modules/payment/examples/page.mdx b/www/apps/resources/app/commerce-modules/payment/examples/page.mdx deleted file mode 100644 index 89a28b399e033..0000000000000 --- a/www/apps/resources/app/commerce-modules/payment/examples/page.mdx +++ /dev/null @@ -1,359 +0,0 @@ -import { CodeTabs, CodeTab } from "docs-ui" - -export const metadata = { - title: `Examples of the Payment Module`, -} - -# {metadata.title} - -In this guide, you’ll find common examples of how you can use the Payment Module in your application. - - - -You should only use the Payment Module's main service when implementing complex customizations. For common cases, check out [available workflows instead](../../../medusa-workflows-reference/page.mdx). - - - -## Create a Payment Collection - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const paymentModuleService = req.scope.resolve( - Modules.PAYMENT - ) - - const paymentCollection = await paymentModuleService.createPaymentCollections( - { - region_id: "reg_123", - currency_code: "usd", - amount: 4000, - } - ) - - res.json({ - payment_collection: paymentCollection, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializePaymentModule } from "@medusajs/medusa/payment" - -export async function POST(request: Request) { - const paymentModuleService = await initializePaymentModule() - - const paymentCollection = await paymentModuleService.createPaymentCollections( - { - region_id: "reg_123", - currency_code: "usd", - amount: 4000, - } - ) - - return NextResponse.json({ - payment_collection: paymentCollection, - }) -} -``` - - - - ---- - -## Create Payment Session - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const paymentModuleService = req.scope.resolve( - Modules.PAYMENT - ) - - const paymentSession = await paymentModuleService.createPaymentSession( - "pay_col_123", - { - currency_code: "usd", - provider_id: "system", - amount: 4000, - data: {}, - } - ) - - res.json({ - payment_session: paymentSession, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializePaymentModule } from "@medusajs/medusa/payment" - -export async function POST(request: Request) { - const paymentModuleService = await initializePaymentModule() - - const paymentSession = await paymentModuleService.createPaymentSession( - "pay_col_123", - { - currency_code: "usd", - provider_id: "system", - amount: 4000, - data: {}, - } - ) - - return NextResponse.json({ - payment_session: paymentSession, - }) -} -``` - - - - ---- - -## List Payment Sessions of Payment Collection - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const paymentModuleService = req.scope.resolve( - Modules.PAYMENT - ) - - const paymentSessions = await paymentModuleService.listPaymentSessions({ - payment_collection_id: ["pay_col_123"], - }) - - res.json({ - payment_sessions: paymentSessions, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializePaymentModule } from "@medusajs/medusa/payment" - -export async function POST(request: Request) { - const paymentModuleService = await initializePaymentModule() - - const paymentSessions = await paymentModuleService.listPaymentSessions({ - payment_collection_id: ["pay_col_123"], - }) - - return NextResponse.json({ - payment_sessions: paymentSessions, - }) -} -``` - - - - ---- - -## Authorize Payment Session - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const paymentModuleService = req.scope.resolve( - Modules.PAYMENT - ) - - const payment = await paymentModuleService.authorizePaymentSession( - "payses_123", - {} - ) - - res.json({ - payment, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializePaymentModule } from "@medusajs/medusa/payment" - -export async function POST(request: Request) { - const paymentModuleService = await initializePaymentModule() - - const payment = await paymentModuleService.authorizePaymentSession( - "payses_123", - {} - ) - - return NextResponse.json({ - payment, - }) -} -``` - - - - ---- - -## List Payments of Payment Session - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const paymentModuleService = req.scope.resolve( - Modules.PAYMENT - ) - - const payments = await paymentModuleService.listPayments({ - session_id: "payses_123", - }) - - res.json({ - payments, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializePaymentModule } from "@medusajs/medusa/payment" - -export async function GET(request: Request) { - const paymentModuleService = await initializePaymentModule() - - const payments = await paymentModuleService.listPayments({ - session_id: "payses_123", - }) - - return NextResponse.json({ - payments, - }) -} -``` - - - - ---- - -## Capture Payment - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const paymentModuleService = req.scope.resolve( - Modules.PAYMENT - ) - - const payment = await paymentModuleService.capturePayment({ - payment_id: "pay_123", - }) - - res.json({ - payment, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializePaymentModule } from "@medusajs/medusa/payment" - -export async function POST(request: Request) { - const paymentModuleService = await initializePaymentModule() - - const payment = await paymentModuleService.capturePayment({ - payment_id: "pay_123", - }) - - return NextResponse.json({ - payment, - }) -} -``` - - - - ---- - -## More Examples - -The [Payment Module's main service reference](/references/payment) provides a reference to all the methods available for use with examples for each. diff --git a/www/apps/resources/app/commerce-modules/payment/page.mdx b/www/apps/resources/app/commerce-modules/payment/page.mdx index 93865b05adbeb..8cfae8ae46c4e 100644 --- a/www/apps/resources/app/commerce-modules/payment/page.mdx +++ b/www/apps/resources/app/commerce-modules/payment/page.mdx @@ -1,5 +1,4 @@ -import { CodeTabs, CodeTab } from "docs-ui" -import { Table } from "docs-ui" +import { CodeTabs, CodeTab, ChildDocs } from "docs-ui" export const metadata = { title: `Payment Module`, @@ -7,130 +6,167 @@ export const metadata = { # {metadata.title} -The Payment Module provides payment-related features in your Medusa and Node.js applications. +In this section of the documentation, you will find resources to learn more about the Payment Module and how to use it in your application. -## How to Use Payment Module's Service +Medusa has payment related features available out-of-the-box through the Payment Module. A [module](!docs!/learn/fundamentals/modules) is a standalone package that provides features for a single domain. Each of Medusa's commerce features are placed in commerce modules, such as this Payment Module. -You can use the Payment Module's main service by resolving from the Medusa container the resource `Modules.PAYMENT`. + -For example: +Learn more about why modules are isolated in [this documentation](!docs!/learn/fundamentals/modules/isolation). - - + -```ts title="src/workflows/hello-world/step1.ts" -import { createStep } from "@medusajs/framework/workflows-sdk" -import { Modules } from "@medusajs/framework/utils" +## Payment Features -const step1 = createStep("step-1", async (_, { container }) => { - const paymentModuleService = container.resolve( - Modules.PAYMENT - ) +- [Authorize, Capture, and Refund Payments](./payment/page.mdx): Authorize, capture, and refund payments for a single resource. +- [Payment Collection Management](./payment-collection/page.mdx): Store and manage all payments of a single resources, such as a cart, in payment collections. +- [Integrate Third-Party Payment Providers](./payment-provider/page.mdx): Use payment providers like [Stripe](./payment-provider/stripe/page.mdx) to handle and process payments, or integrate custom payment providers. +- [Handle Webhook Events](./webhook-events/page.mdx): Handle webhook events from third-party providers and process the associated payment. - const payment_collections = - await paymentModuleService.listPaymentCollections() -}) -``` +--- - - +## How to Use Payment Module's Service -```ts title="src/api/store/custom/route.ts" -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" +In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. -export async function GET( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const paymentModuleService = req.scope.resolve( - Modules.PAYMENT - ) - - res.json({ - payment_collections: await paymentModuleService.listPaymentCollections(), - }) -} -``` +You can build custom workflows and steps. You can also re-use Medusa's workflows and steps, which are provided by the `@medusajs/medusa/core-flows` package. - - +For example: -```ts title="src/subscribers/custom-handler.ts" -import { SubscriberArgs } from "@medusajs/framework" +export const highlights = [ + ["12", "Modules.PAYMENT", "Resolve the module in a step."] +] + +```ts title="src/workflows/create-payment-collection.ts" highlights={highlights} +import { + createWorkflow, + WorkflowResponse, + createStep, + StepResponse, +} from "@medusajs/framework/workflows-sdk" import { Modules } from "@medusajs/framework/utils" -export default async function subscriberHandler({ container }: SubscriberArgs) { - const paymentModuleService = container.resolve( - Modules.PAYMENT - ) - - const payment_collections = - await paymentModuleService.listPaymentCollections() -} -``` - - - +const createPaymentCollectionStep = createStep( + "create-payment-collection", + async ({}, { container }) => { + const paymentModuleService = container.resolve(Modules.PAYMENT) ---- + const paymentCollection = await paymentModuleService.createPaymentCollections({ + region_id: "reg_123", + currency_code: "usd", + amount: 5000, + }) -## Features + return new StepResponse({ paymentCollection }, paymentCollection.id) + }, + async (paymentCollectionId, { container }) => { + const paymentModuleService = container.resolve(Modules.PAYMENT) + + await paymentModuleService.deletePaymentCollections([paymentCollectionId]) + } +) + +export const createPaymentCollectionWorkflow = createWorkflow( + "create-payment-collection", + () => { + const { paymentCollection } = createPaymentCollectionStep() + + return new WorkflowResponse({ + paymentCollection, + }) + } +) +``` -### Add Payment Functionalities to Any Resource +You can then execute the workflow in your custom API routes, scheduled jobs, or subscribers: -The Payment Module provides payment functionalities that allow you to process payment of any resource, such as a cart. + + + + ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import type { + MedusaRequest, + MedusaResponse, + } from "@medusajs/framework/http" + import createPaymentCollectionWorkflow from "../../workflows/create-payment-collection" + + export async function GET( + req: MedusaRequest, + res: MedusaResponse + ) { + const { result } = await createPaymentCollectionWorkflow(req.scope) + .run() + + res.send(result) + } + ``` -All payment processing starts with creating a payment collection, which carries information for authorized, captured, and refunded payments for a single resource. + + + + ```ts title="src/subscribers/customer-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import { + type SubscriberConfig, + type SubscriberArgs, + } from "@medusajs/framework" + import createPaymentCollectionWorkflow from "../workflows/create-payment-collection" + + export default async function handleCustomerCreate({ + event: { data }, + container, + }: SubscriberArgs<{ id: string }>) { + const { result } = await createPaymentCollectionWorkflow(container) + .run() + + console.log(result) + } + + export const config: SubscriberConfig = { + event: "user.created", + } + ``` -```ts -const paymentCollection = await paymentModuleService.createPaymentCollections({ - region_id: "reg_123", - currency_code: "usd", - amount: 5000, -}) -``` + + + + ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} + import { MedusaContainer } from "@medusajs/framework/types" + import createPaymentCollectionWorkflow from "../workflows/create-payment-collection" + + export default async function myCustomJob( + container: MedusaContainer + ) { + const { result } = await createPaymentCollectionWorkflow(container) + .run() + + console.log(result.message) + } + + export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, + }; + ``` -### Authorize, Capture, and Refund Payment + + -Receive and handle payments, including authorizing, capturing, and refunding payment. +Learn more about workflows in [this documentation](!docs!/learn/fundamentals/workflows). -```ts -await paymentModuleService.capturePayment({ - payment_id: "pay_1", -}) -``` +--- -### Integrate Third-Party Payment Providers +## Configure Payment Module -Use payment providers like Stripe to handle and process payments. +The Payment Module accepts options for further configurations. Refer to [this documentation](./module-options/page.mdx) for details on the module's options. -```ts -const payment = await paymentModuleService.createPaymentSession("pay_col_1", { - provider_id: "stripe", - amount: 1000, - currency_code: "usd", - data: { - // necessary data for the payment provider - }, -}) -``` +--- -### Handle Webhook Events +## Providers -The Payment Module allows you to handle webhook events from third-party providers and process the associated payment. +Medusa provides the following payment providers out-of-the-box. You can use them to process payments for orders, returns, and other resources. -```ts -await paymentModuleService.processEvent({ - provider: "stripe", - payload: { - // webhook payload - }, -}) -``` + --- -## Configure Payment Module - -Refer to [this documentation](./module-options/page.mdx) for details on the module's options. + \ No newline at end of file diff --git a/www/apps/resources/app/nextjs-starter/guides/customize-stripe/page.mdx b/www/apps/resources/app/nextjs-starter/guides/customize-stripe/page.mdx index 97aea7900d6ec..7fcca61066ce1 100644 --- a/www/apps/resources/app/nextjs-starter/guides/customize-stripe/page.mdx +++ b/www/apps/resources/app/nextjs-starter/guides/customize-stripe/page.mdx @@ -1,3 +1,9 @@ +--- +tags: + - storefront + - payment +--- + import { Prerequisites } from "docs-ui" export const ogImage = "https://res.cloudinary.com/dza7lstvk/image/upload/v1734007558/Medusa%20Resources/integrations-stripe_qfnwtf.jpg" diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index 3355710b78895..3c9937b872c4b 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -44,7 +44,6 @@ export const generatedEditDates = { "app/commerce-modules/order/page.mdx": "2024-12-25T14:34:00.973Z", "app/commerce-modules/payment/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/payment/_events/page.mdx": "2024-07-03T19:27:13+03:00", - "app/commerce-modules/payment/examples/page.mdx": "2024-10-15T14:59:55.208Z", "app/commerce-modules/payment/module-options/page.mdx": "2024-10-15T12:51:40.574Z", "app/commerce-modules/payment/payment/page.mdx": "2024-10-09T10:59:08.463Z", "app/commerce-modules/payment/payment-collection/page.mdx": "2024-10-09T10:56:49.510Z", @@ -53,7 +52,7 @@ export const generatedEditDates = { "app/commerce-modules/payment/payment-provider/page.mdx": "2024-10-09T11:07:27.269Z", "app/commerce-modules/payment/payment-session/page.mdx": "2024-10-09T10:58:00.960Z", "app/commerce-modules/payment/webhook-events/page.mdx": "2024-11-19T11:45:02.167Z", - "app/commerce-modules/payment/page.mdx": "2024-12-09T14:47:57.842Z", + "app/commerce-modules/payment/page.mdx": "2024-12-25T14:47:19.426Z", "app/commerce-modules/pricing/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/pricing/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/pricing/concepts/page.mdx": "2024-10-09T13:37:25.678Z", @@ -5627,7 +5626,7 @@ export const generatedEditDates = { "app/recipes/commerce-automation/restock-notification/page.mdx": "2024-12-11T08:47:27.471Z", "app/troubleshooting/workflow-errors/page.mdx": "2024-12-11T08:44:36.598Z", "app/integrations/guides/shipstation/page.mdx": "2024-12-23T07:48:47.719Z", - "app/nextjs-starter/guides/customize-stripe/page.mdx": "2024-12-12T12:46:33.999Z", + "app/nextjs-starter/guides/customize-stripe/page.mdx": "2024-12-25T14:48:55.877Z", "references/core_flows/Cart/Workflows_Cart/functions/core_flows.Cart.Workflows_Cart.listShippingOptionsForCartWithPricingWorkflow/page.mdx": "2024-12-25T08:43:13.451Z", "references/core_flows/Cart/Workflows_Cart/variables/core_flows.Cart.Workflows_Cart.listShippingOptionsForCartWithPricingWorkflowId/page.mdx": "2024-12-17T16:57:22.044Z", "references/core_flows/Fulfillment/Steps_Fulfillment/functions/core_flows.Fulfillment.Steps_Fulfillment.calculateShippingOptionsPricesStep/page.mdx": "2024-12-25T08:43:13.630Z", diff --git a/www/apps/resources/generated/files-map.mjs b/www/apps/resources/generated/files-map.mjs index c9483c2e862bc..a7d78f1d9f5d6 100644 --- a/www/apps/resources/generated/files-map.mjs +++ b/www/apps/resources/generated/files-map.mjs @@ -359,10 +359,6 @@ export const filesMap = [ "filePath": "/www/apps/resources/app/commerce-modules/page.mdx", "pathname": "/commerce-modules" }, - { - "filePath": "/www/apps/resources/app/commerce-modules/payment/examples/page.mdx", - "pathname": "/commerce-modules/payment/examples" - }, { "filePath": "/www/apps/resources/app/commerce-modules/payment/links-to-other-modules/page.mdx", "pathname": "/commerce-modules/payment/links-to-other-modules" diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs index a9b1fa2371b3a..f302fa692ac5b 100644 --- a/www/apps/resources/generated/sidebar.mjs +++ b/www/apps/resources/generated/sidebar.mjs @@ -4751,6 +4751,9 @@ export const generatedSidebar = [ "title": "Overview", "children": [] }, + { + "type": "separator" + }, { "loaded": true, "isPathHref": true, @@ -7189,18 +7192,14 @@ export const generatedSidebar = [ "children": [] }, { - "loaded": true, - "isPathHref": true, - "type": "link", - "path": "/commerce-modules/payment/examples", - "title": "Examples", - "children": [] + "type": "separator" }, { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", "title": "Concepts", + "initialOpen": false, "children": [ { "loaded": true, @@ -7255,8 +7254,11 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "sub-category", - "title": "Guides", + "type": "category", + "title": "Server Guides", + "autogenerate_tags": "server+payment", + "initialOpen": false, + "autogenerate_as_ref": true, "children": [ { "loaded": true, @@ -7279,8 +7281,258 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "sub-category", - "title": "Payment Providers", + "type": "category", + "title": "Storefront Guides", + "autogenerate_tags": "storefront+payment", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Customize the Stripe Integration in the Next.js Starter", + "path": "/nextjs-starter/guides/customize-stripe", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Checkout Step 5: Complete Cart", + "path": "/storefront-development/checkout/complete-cart", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Checkout Step 4: Choose Payment Provider", + "path": "/storefront-development/checkout/payment", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Payment with Stripe in React Storefront", + "path": "/storefront-development/checkout/payment/stripe", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Workflows", + "autogenerate_tags": "workflow+payment", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createCartWorkflow", + "path": "/references/medusa-workflows/createCartWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createPaymentCollectionForCartWorkflow", + "path": "/references/medusa-workflows/createPaymentCollectionForCartWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "refreshPaymentCollectionForCartWorkflow", + "path": "/references/medusa-workflows/refreshPaymentCollectionForCartWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelOrderWorkflow", + "path": "/references/medusa-workflows/cancelOrderWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createOrderPaymentCollectionWorkflow", + "path": "/references/medusa-workflows/createOrderPaymentCollectionWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "markPaymentCollectionAsPaid", + "path": "/references/medusa-workflows/markPaymentCollectionAsPaid", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "capturePaymentWorkflow", + "path": "/references/medusa-workflows/capturePaymentWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "processPaymentWorkflow", + "path": "/references/medusa-workflows/processPaymentWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "refundPaymentWorkflow", + "path": "/references/medusa-workflows/refundPaymentWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createPaymentSessionsWorkflow", + "path": "/references/medusa-workflows/createPaymentSessionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createRefundReasonsWorkflow", + "path": "/references/medusa-workflows/createRefundReasonsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deletePaymentSessionsWorkflow", + "path": "/references/medusa-workflows/deletePaymentSessionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateRefundReasonsWorkflow", + "path": "/references/medusa-workflows/updateRefundReasonsWorkflow", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Steps", + "autogenerate_tags": "step+payment", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createPaymentCollectionsStep", + "path": "/references/medusa-workflows/steps/createPaymentCollectionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "authorizePaymentSessionStep", + "path": "/references/medusa-workflows/steps/authorizePaymentSessionStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "cancelPaymentStep", + "path": "/references/medusa-workflows/steps/cancelPaymentStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "capturePaymentStep", + "path": "/references/medusa-workflows/steps/capturePaymentStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "refundPaymentStep", + "path": "/references/medusa-workflows/steps/refundPaymentStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createPaymentSessionStep", + "path": "/references/medusa-workflows/steps/createPaymentSessionStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createRefundReasonStep", + "path": "/references/medusa-workflows/steps/createRefundReasonStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deletePaymentSessionsStep", + "path": "/references/medusa-workflows/steps/deletePaymentSessionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updatePaymentCollectionStep", + "path": "/references/medusa-workflows/steps/updatePaymentCollectionStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateRefundReasonsStep", + "path": "/references/medusa-workflows/steps/updateRefundReasonsStep", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Providers", + "initialOpen": false, "children": [ { "loaded": true, @@ -7295,8 +7547,9 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", "title": "References", + "initialOpen": false, "children": [ { "loaded": true, diff --git a/www/apps/resources/sidebars/order-module.mjs b/www/apps/resources/sidebars/order-module.mjs index d7b7ec55f62ce..911fc02eb02f8 100644 --- a/www/apps/resources/sidebars/order-module.mjs +++ b/www/apps/resources/sidebars/order-module.mjs @@ -10,6 +10,9 @@ export const orderSidebar = [ path: "/commerce-modules/order", title: "Overview", }, + { + type: "separator", + }, { type: "category", title: "Concepts", diff --git a/www/apps/resources/sidebars/payment.mjs b/www/apps/resources/sidebars/payment.mjs index 7e9625fd4d800..0f0b032745d34 100644 --- a/www/apps/resources/sidebars/payment.mjs +++ b/www/apps/resources/sidebars/payment.mjs @@ -16,13 +16,12 @@ export const paymentSidebar = [ title: "Module Options", }, { - type: "link", - path: "/commerce-modules/payment/examples", - title: "Examples", + type: "separator", }, { - type: "sub-category", + type: "category", title: "Concepts", + initialOpen: false, children: [ { type: "link", @@ -57,8 +56,11 @@ export const paymentSidebar = [ ], }, { - type: "sub-category", - title: "Guides", + type: "category", + title: "Server Guides", + autogenerate_tags: "server+payment", + initialOpen: false, + autogenerate_as_ref: true, children: [ { type: "link", @@ -73,8 +75,44 @@ export const paymentSidebar = [ ], }, { - type: "sub-category", - title: "Payment Providers", + type: "category", + title: "Storefront Guides", + autogenerate_tags: "storefront+payment", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Admin Guides", + autogenerate_tags: "admin+payment", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "User Guides", + autogenerate_tags: "userGuides+payment", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Workflows", + autogenerate_tags: "workflow+payment", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Steps", + autogenerate_tags: "step+payment", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Providers", + initialOpen: false, children: [ { type: "link", @@ -84,8 +122,9 @@ export const paymentSidebar = [ ], }, { - type: "sub-category", + type: "category", title: "References", + initialOpen: false, children: [ { type: "link", diff --git a/www/packages/tags/src/tags/index.ts b/www/packages/tags/src/tags/index.ts index cff170c6c0d39..f1bc7d39bd525 100644 --- a/www/packages/tags/src/tags/index.ts +++ b/www/packages/tags/src/tags/index.ts @@ -1,31 +1,31 @@ export * from "./product.js" -export * from "./cart.js" export * from "./storefront.js" -export * from "./order.js" export * from "./payment.js" +export * from "./cart.js" +export * from "./order.js" export * from "./stripe.js" export * from "./fulfillment.js" export * from "./customer.js" -export * from "./auth.js" -export * from "./product-category.js" -export * from "./product-collection.js" export * from "./tax.js" +export * from "./product-collection.js" export * from "./inventory.js" export * from "./pricing.js" -export * from "./api-key.js" -export * from "./step.js" +export * from "./query.js" +export * from "./auth.js" export * from "./remote-link.js" -export * from "./workflow.js" export * from "./sales-channel.js" -export * from "./query.js" -export * from "./logger.js" +export * from "./workflow.js" +export * from "./api-key.js" +export * from "./region.js" +export * from "./publishable-api-key.js" export * from "./remote-query.js" +export * from "./event-bus.js" +export * from "./logger.js" export * from "./promotion.js" +export * from "./product-category.js" export * from "./store.js" -export * from "./publishable-api-key.js" -export * from "./region.js" +export * from "./file.js" export * from "./stock-location.js" +export * from "./step.js" export * from "./locking.js" -export * from "./file.js" export * from "./user.js" -export * from "./event-bus.js" diff --git a/www/packages/tags/src/tags/payment.ts b/www/packages/tags/src/tags/payment.ts index 5212a2544e6af..4d32aed86b31e 100644 --- a/www/packages/tags/src/tags/payment.ts +++ b/www/packages/tags/src/tags/payment.ts @@ -1,4 +1,8 @@ export const payment = [ + { + "title": "Customize the Stripe Integration in the Next.js Starter", + "path": "/nextjs-starter/guides/customize-stripe" + }, { "title": "Checkout Step 5: Complete Cart", "path": "/storefront-development/checkout/complete-cart" diff --git a/www/packages/tags/src/tags/storefront.ts b/www/packages/tags/src/tags/storefront.ts index b10f22863a3b9..162d33cf180da 100644 --- a/www/packages/tags/src/tags/storefront.ts +++ b/www/packages/tags/src/tags/storefront.ts @@ -1,4 +1,8 @@ export const storefront = [ + { + "title": "Customize the Stripe Integration in the Next.js Starter", + "path": "/nextjs-starter/guides/customize-stripe" + }, { "title": "Create Cart Context in Storefront", "path": "/storefront-development/cart/context" From 2cb13997888d52650dc23b942750290133305608 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Wed, 25 Dec 2024 17:12:28 +0200 Subject: [PATCH 12/21] revise pricing module --- .../pricing/examples/page.mdx | 395 ----------------- .../app/commerce-modules/pricing/page.mdx | 267 ++++++------ .../product/guides/price-with-taxes/page.mdx | 1 + .../product/guides/price/page.mdx | 1 + www/apps/resources/generated/edit-dates.mjs | 7 +- www/apps/resources/generated/files-map.mjs | 4 - www/apps/resources/generated/sidebar.mjs | 409 +++++++++++++++++- www/apps/resources/sidebars/pricing.mjs | 52 ++- www/packages/tags/src/tags/index.ts | 31 +- www/packages/tags/src/tags/server.ts | 10 + 10 files changed, 616 insertions(+), 561 deletions(-) delete mode 100644 www/apps/resources/app/commerce-modules/pricing/examples/page.mdx create mode 100644 www/packages/tags/src/tags/server.ts diff --git a/www/apps/resources/app/commerce-modules/pricing/examples/page.mdx b/www/apps/resources/app/commerce-modules/pricing/examples/page.mdx deleted file mode 100644 index 5284571f5f7f2..0000000000000 --- a/www/apps/resources/app/commerce-modules/pricing/examples/page.mdx +++ /dev/null @@ -1,395 +0,0 @@ -import { CodeTabs, CodeTab } from "docs-ui" - -export const metadata = { - title: `Examples of the Pricing Module`, -} - -# {metadata.title} - -In this document, you’ll find common examples of how you can use the Pricing Module in your application. - - - -You should only use the Pricing Module's main service when implementing complex customizations. For common cases, check out [available workflows instead](../../../medusa-workflows-reference/page.mdx). - - - -## Create a Price Set - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const pricingModuleService = request.scope.resolve( - Modules.PRICING - ) - - const priceSet = await pricingModuleService.createPriceSets([ - { - prices: [ - { - currency_code: "eur", - amount: 10, - rules: { - region_id: "reg_123", - }, - }, - ], - }, - ]) - - res.json({ price_set: priceSet }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializePricingModule } from "@medusajs/medusa/pricing" - -export async function POST(request: Request) { - const pricingModuleService = await initializePricingModule() - const body = await request.json() - - const priceSet = await pricingModuleService.createPriceSets([ - { - prices: [ - { - currency_code: "eur", - amount: 10, - rules: { - region_id: "reg_123", - }, - }, - ], - }, - ]) - - return NextResponse.json({ price_set: priceSet }) -} -``` - - - - ---- - -## List Price Sets - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const pricingModuleService = request.scope.resolve( - Modules.PRICING - ) - - const priceSets = await pricingModuleService.listPriceSets() - - res.json({ price_sets: priceSets }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializePricingModule } from "@medusajs/medusa/pricing" - -export async function GET(request: Request) { - const pricingModuleService = await initializePricingModule() - - const priceSets = await pricingModuleService.listPriceSets() - - return NextResponse.json({ price_sets: priceSets }) -} -``` - - - - ---- - -## Retrieve a Price Set by its ID - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const pricingModuleService = request.scope.resolve( - Modules.PRICING - ) - - const priceSet = await pricingModuleService.retrievePriceSet("pset_123") - - res.json({ price_set: priceSet }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializePricingModule } from "@medusajs/medusa/pricing" - -export async function GET(request: Request) { - const pricingModuleService = await initializePricingModule() - - const priceSet = await pricingModuleService.retrievePriceSet("pset_123") - - return NextResponse.json({ price_set: priceSet }) -} -``` - - - - ---- - -## Add Prices with Rules - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const pricingModuleService = request.scope.resolve( - Modules.PRICING - ) - - const priceSet = await pricingModuleService.addPrices({ - priceSetId: "pset_123", - prices: [ - { - amount: 500, - currency_code: "USD", - rules: { - region_id: "reg_123", - }, - }, - ], - }) - - res.json({ price_set: priceSet }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializePricingModule } from "@medusajs/medusa/pricing" - -export async function POST(request: Request) { - const pricingModuleService = await initializePricingModule() - const body = await request.json() - - const priceSet = await pricingModuleService.addPrices({ - priceSetId: "pset_123", - prices: [ - { - amount: 500, - currency_code: "USD", - rules: { - region_id: "reg_123", - }, - }, - ], - }) - - return NextResponse.json({ price_set: priceSet }) -} -``` - - - - ---- - -## Create Price List - - - - - ```ts collapsibleLines="1-8" expandButtonLabel="Show Imports" - import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" - import { IPricingModuleService } from "@medusajs/framework/types" - import { PriceListType } from "@medusajs/framework/utils" - import { Modules } from "@medusajs/framework/utils" - -export async function POST( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const pricingModuleService = request.scope.resolve( - Modules.PRICING - ) - - const priceLists = await pricingModuleService.createPriceLists([ - { - title: "My Sale", - description: "This is my sale", - type: PriceListType.SALE, - starts_at: Date.parse("01/10/2023").toString(), - ends_at: Date.parse("31/10/2023").toString(), - rules: { - region_id: ["reg_123", "reg_321"], - }, - prices: [ - { - amount: 400, - currency_code: "EUR", - price_set_id: "pset_124", - }, - ], - }, - ]) - - res.json({ price_lists: priceLists }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" -import { PriceListType } from "@medusajs/framework/utils" - -import { initialize as initializePricingModule } from "@medusajs/medusa/pricing" -import { PriceListType } from "@medusajs/framework/utils" - -export async function POST(request: Request) { - const pricingModuleService = await initializePricingModule() - - const priceLists = await pricingModuleService.createPriceLists([ - { - title: "My Sale", - description: "This is my sale", - type: PriceListType.SALE, - starts_at: Date.parse("01/10/2023").toString(), - ends_at: Date.parse("31/10/2023").toString(), - rules: { - region_id: ["reg_123", "reg_321"], - }, - prices: [ - { - amount: 400, - currency_code: "EUR", - price_set_id: "pset_124", - }, - ], - }, - ]) - - return NextResponse.json({ price_lists: priceLists }) -} -``` - - - - ---- - -## Calculate Prices For a Currency - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const pricingModuleService = request.scope.resolve( - Modules.PRICING - ) - - const price = await pricingModuleService.calculatePrices( - { - id: ["pset_123"], - }, - { - context: { - currency_code: "eur", - }, - } - ) - - res.json({ price }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializePricingModule } from "@medusajs/medusa/pricing" - -export async function GET(request: Request) { - const pricingModuleService = await initializePricingModule() - - const price = await pricingModuleService.calculatePrices( - { - id: ["pset_123"], - }, - { - context: { - currency_code: "eur", - }, - } - ) - - return NextResponse.json({ price }) -} -``` - - - - ---- - -## More Examples - -The [Pricing Module's main service reference](/references/pricing) provides a reference to all the methods available for use with examples for each. diff --git a/www/apps/resources/app/commerce-modules/pricing/page.mdx b/www/apps/resources/app/commerce-modules/pricing/page.mdx index 9ef1c8f6114b3..571c4d3eb041b 100644 --- a/www/apps/resources/app/commerce-modules/pricing/page.mdx +++ b/www/apps/resources/app/commerce-modules/pricing/page.mdx @@ -6,157 +6,164 @@ export const metadata = { # {metadata.title} -The Pricing Module provides pricing-related features in your Medusa and Node.js applications. +In this section of the documentation, you will find resources to learn more about the Pricing Module and how to use it in your application. -## How to Use Pricing Module's Service +Medusa has pricing related features available out-of-the-box through the Pricing Module. A [module](!docs!/learn/fundamentals/modules) is a standalone package that provides features for a single domain. Each of Medusa's commerce features are placed in commerce modules, such as this Pricing Module. -You can use the Pricing Module's main service by resolving from the Medusa container the resource `Modules.PRICING`. + -For example: +Learn more about why modules are isolated in [this documentation](!docs!/learn/fundamentals/modules/isolation). - - + -```ts title="src/workflows/hello-world/step1.ts" -import { createStep } from "@medusajs/framework/workflows-sdk" -import { Modules } from "@medusajs/framework/utils" +## Pricing Features -const step1 = createStep("step-1", async (_, { container }) => { - const pricingModuleService = container.resolve( - Modules.PRICING - ) +- [Price Management](./concepts/page.mdx): Store and manage prices of a resource, such as a product or a variant. +- [Advanced Rule Engine](./price-rules/page.mdx): Create prices with custom rules to condition prices based on different contexts. +- [Price Lists](./concepts/page.mdx#price-list): Group prices and apply them only in specific conditions with price lists. +- [Price Calculation Strategy](./price-calculation/page.mdx): Retrieve the best price in a given context and for the specified rule values. +- [Tax-Inclusive Pricing](./tax-inclusive-pricing/page.mdx): Calculate prices with taxes included in the price, and Medusa will handle calculating the taxes automatically. - const priceSets = await pricingModuleService.listPriceSets() -}) -``` +--- - - +## How to Use Pricing Module's Service -```ts title="src/api/store/custom/route.ts" -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" +In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. -export async function GET( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const pricingModuleService = request.scope.resolve( - Modules.PRICING - ) - - res.json({ - price_sets: await pricingModuleService.listPriceSets(), - }) -} -``` +You can build custom workflows and steps. You can also re-use Medusa's workflows and steps, which are provided by the `@medusajs/medusa/core-flows` package. - - +For example: -```ts title="src/subscribers/custom-handler.ts" -import { SubscriberArgs } from "@medusajs/framework" +export const highlights = [ + ["12", "Modules.PRICING", "Resolve the module in a step."] +] + +```ts title="src/workflows/create-price-set.ts" highlights={highlights} +import { + createWorkflow, + WorkflowResponse, + createStep, + StepResponse, +} from "@medusajs/framework/workflows-sdk" import { Modules } from "@medusajs/framework/utils" -export default async function subscriberHandler({ container }: SubscriberArgs) { - const pricingModuleService = container.resolve( - Modules.PRICING - ) +const createPriceSetStep = createStep( + "create-price-set", + async ({}, { container }) => { + const pricingModuleService = container.resolve(Modules.PRICING) + + const priceSet = await pricingModuleService.createPriceSets({ + prices: [ + { + amount: 500, + currency_code: "USD", + }, + { + amount: 400, + currency_code: "EUR", + min_quantity: 0, + max_quantity: 4, + rules: {}, + }, + ], + }) + + return new StepResponse({ priceSet }, priceSet.id) + }, + async (priceSetId, { container }) => { + const pricingModuleService = container.resolve(Modules.PRICING) - const priceSets = await pricingModuleService.listPriceSets() -} + await pricingModuleService.deletePriceSets([priceSetId]) + } +) + +export const createPriceSetWorkflow = createWorkflow( + "create-price-set", + () => { + const { priceSet } = createPriceSetStep() + + return new WorkflowResponse({ + priceSet, + }) + } +) ``` - - +You can then execute the workflow in your custom API routes, scheduled jobs, or subscribers: ---- + + + + ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import type { + MedusaRequest, + MedusaResponse, + } from "@medusajs/framework/http" + import createPriceSetWorkflow from "../../workflows/create-price-set" + + export async function GET( + req: MedusaRequest, + res: MedusaResponse + ) { + const { result } = await createPriceSetWorkflow(req.scope) + .run() + + res.send(result) + } + ``` -## Features - -### Price Management - -Store the prices of a resource and manage them through the main service's methods. - -Prices are grouped in a price set, allowing you to add more than one price for a resource based on different conditions, such as currency code. - -```ts -const priceSet = await pricingModuleService.createPriceSets({ - prices: [ - { - amount: 500, - currency_code: "USD", - }, - { - amount: 400, - currency_code: "EUR", - min_quantity: 0, - max_quantity: 4, - rules: {}, - }, - ], -}) -``` + + + + ```ts title="src/subscribers/customer-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import { + type SubscriberConfig, + type SubscriberArgs, + } from "@medusajs/framework" + import createPriceSetWorkflow from "../workflows/create-price-set" + + export default async function handleCustomerCreate({ + event: { data }, + container, + }: SubscriberArgs<{ id: string }>) { + const { result } = await createPriceSetWorkflow(container) + .run() + + console.log(result) + } + + export const config: SubscriberConfig = { + event: "user.created", + } + ``` -### Advanced Rule Engine - -Create prices with custom rules. This gives you more flexibility in how you condition prices, filter them, and ensure the best prices are retrieved for custom contexts. - -```ts highlights={[["8"]]} -const priceSet = await pricingModuleService.addPrices({ - priceSetId: "pset_123", - prices: [ - { - amount: 500, - currency_code: "EUR", - rules: { - region_id: "reg_123", - }, - }, - ], -}) -``` + + + + ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} + import { MedusaContainer } from "@medusajs/framework/types" + import createPriceSetWorkflow from "../workflows/create-price-set" + + export default async function myCustomJob( + container: MedusaContainer + ) { + const { result } = await createPriceSetWorkflow(container) + .run() + + console.log(result.message) + } + + export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, + }; + ``` -### Price Lists - -Group prices and apply them only in specific conditions with price lists. - -You can also use them to override existing prices for specified conditions, or create a sale. - -```ts -const priceList = await pricingModuleService.createPriceLists([ - { - title: "My Sale", - description: "Sale on selected items.", - type: "sale", - starts_at: Date.parse("01/10/2023").toString(), - ends_at: Date.parse("31/10/2023").toString(), - rules: { - region_id: ["reg_123", "reg_321"], - }, - prices: [ - { - amount: 400, - currency_code: "EUR", - price_set_id: "pset_123", - }, - ], - }, -]) -``` + + -### Price Calculation Strategy +Learn more about workflows in [this documentation](!docs!/learn/fundamentals/workflows). -Retrieve the best price in a given context and for the specified rule values. +--- -```ts -const price = await pricingModuleService.calculatePrices( - { id: ["pset_123"] }, - { - context: { - currency_code: "EUR", - region_id: "reg_123", - }, - } -) -``` + \ No newline at end of file diff --git a/www/apps/resources/app/commerce-modules/product/guides/price-with-taxes/page.mdx b/www/apps/resources/app/commerce-modules/product/guides/price-with-taxes/page.mdx index d615be436a614..7e405cabeec15 100644 --- a/www/apps/resources/app/commerce-modules/product/guides/price-with-taxes/page.mdx +++ b/www/apps/resources/app/commerce-modules/product/guides/price-with-taxes/page.mdx @@ -5,6 +5,7 @@ tags: - pricing - query - tax + - server --- export const metadata = { diff --git a/www/apps/resources/app/commerce-modules/product/guides/price/page.mdx b/www/apps/resources/app/commerce-modules/product/guides/price/page.mdx index d03f5a6c147e9..afc633b2cd47e 100644 --- a/www/apps/resources/app/commerce-modules/product/guides/price/page.mdx +++ b/www/apps/resources/app/commerce-modules/product/guides/price/page.mdx @@ -4,6 +4,7 @@ tags: - product - pricing - query + - server --- export const metadata = { diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index 3c9937b872c4b..23472917352c7 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -56,16 +56,15 @@ export const generatedEditDates = { "app/commerce-modules/pricing/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/pricing/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/pricing/concepts/page.mdx": "2024-10-09T13:37:25.678Z", - "app/commerce-modules/pricing/examples/page.mdx": "2024-12-09T13:04:57.713Z", "app/commerce-modules/pricing/price-calculation/page.mdx": "2024-10-09T13:43:14.038Z", "app/commerce-modules/pricing/price-rules/page.mdx": "2024-10-09T13:38:47.112Z", "app/commerce-modules/pricing/tax-inclusive-pricing/page.mdx": "2024-10-09T13:48:23.261Z", - "app/commerce-modules/pricing/page.mdx": "2024-12-09T14:48:02.172Z", + "app/commerce-modules/pricing/page.mdx": "2024-12-25T15:07:51.830Z", "app/commerce-modules/product/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/product/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/product/examples/page.mdx": "2024-10-09T13:59:32.887Z", - "app/commerce-modules/product/guides/price/page.mdx": "2024-12-19T16:37:40.491Z", - "app/commerce-modules/product/guides/price-with-taxes/page.mdx": "2024-12-19T16:37:48.597Z", + "app/commerce-modules/product/guides/price/page.mdx": "2024-12-25T15:10:37.730Z", + "app/commerce-modules/product/guides/price-with-taxes/page.mdx": "2024-12-25T15:10:40.879Z", "app/commerce-modules/product/page.mdx": "2024-12-09T14:48:26.091Z", "app/commerce-modules/promotion/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/promotion/_events/page.mdx": "2024-07-03T19:27:13+03:00", diff --git a/www/apps/resources/generated/files-map.mjs b/www/apps/resources/generated/files-map.mjs index a7d78f1d9f5d6..358cb610801a1 100644 --- a/www/apps/resources/generated/files-map.mjs +++ b/www/apps/resources/generated/files-map.mjs @@ -407,10 +407,6 @@ export const filesMap = [ "filePath": "/www/apps/resources/app/commerce-modules/pricing/concepts/page.mdx", "pathname": "/commerce-modules/pricing/concepts" }, - { - "filePath": "/www/apps/resources/app/commerce-modules/pricing/examples/page.mdx", - "pathname": "/commerce-modules/pricing/examples" - }, { "filePath": "/www/apps/resources/app/commerce-modules/pricing/links-to-other-modules/page.mdx", "pathname": "/commerce-modules/pricing/links-to-other-modules" diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs index f302fa692ac5b..fa74306b494b0 100644 --- a/www/apps/resources/generated/sidebar.mjs +++ b/www/apps/resources/generated/sidebar.mjs @@ -7931,18 +7931,14 @@ export const generatedSidebar = [ "children": [] }, { - "loaded": true, - "isPathHref": true, - "type": "link", - "path": "/commerce-modules/pricing/examples", - "title": "Examples", - "children": [] + "type": "separator" }, { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", "title": "Concepts", + "initialOpen": false, "children": [ { "loaded": true, @@ -7989,8 +7985,405 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", + "title": "Server Guides", + "autogenerate_tags": "server+pricing", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Get Variant Prices", + "path": "/commerce-modules/product/guides/price", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Get Variant Price with Taxes", + "path": "/commerce-modules/product/guides/price-with-taxes", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Storefront Guides", + "autogenerate_tags": "storefront+pricing", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Example: Show Sale Price", + "path": "/storefront-development/products/price/examples/sale-price", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Example: Show Variant's Price", + "path": "/storefront-development/products/price/examples/show-price", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Example: Show Price with Taxes", + "path": "/storefront-development/products/price/examples/tax-price", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Retrieve Product Variant's Prices in Storefront", + "path": "/storefront-development/products/price", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Workflows", + "autogenerate_tags": "workflow+pricing", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createShippingOptionsWorkflow", + "path": "/references/medusa-workflows/createShippingOptionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateShippingOptionsWorkflow", + "path": "/references/medusa-workflows/updateShippingOptionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "batchPriceListPricesWorkflow", + "path": "/references/medusa-workflows/batchPriceListPricesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createPriceListPricesWorkflow", + "path": "/references/medusa-workflows/createPriceListPricesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createPriceListsWorkflow", + "path": "/references/medusa-workflows/createPriceListsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deletePriceListsWorkflow", + "path": "/references/medusa-workflows/deletePriceListsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "removePriceListPricesWorkflow", + "path": "/references/medusa-workflows/removePriceListPricesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updatePriceListPricesWorkflow", + "path": "/references/medusa-workflows/updatePriceListPricesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updatePriceListsWorkflow", + "path": "/references/medusa-workflows/updatePriceListsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createPricePreferencesWorkflow", + "path": "/references/medusa-workflows/createPricePreferencesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deletePricePreferencesWorkflow", + "path": "/references/medusa-workflows/deletePricePreferencesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updatePricePreferencesWorkflow", + "path": "/references/medusa-workflows/updatePricePreferencesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "batchProductVariantsWorkflow", + "path": "/references/medusa-workflows/batchProductVariantsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "batchProductsWorkflow", + "path": "/references/medusa-workflows/batchProductsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createProductVariantsWorkflow", + "path": "/references/medusa-workflows/createProductVariantsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createProductsWorkflow", + "path": "/references/medusa-workflows/createProductsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateProductVariantsWorkflow", + "path": "/references/medusa-workflows/updateProductVariantsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateProductsWorkflow", + "path": "/references/medusa-workflows/updateProductsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "upsertVariantPricesWorkflow", + "path": "/references/medusa-workflows/upsertVariantPricesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createRegionsWorkflow", + "path": "/references/medusa-workflows/createRegionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateRegionsWorkflow", + "path": "/references/medusa-workflows/updateRegionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createStoresWorkflow", + "path": "/references/medusa-workflows/createStoresWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateStoresWorkflow", + "path": "/references/medusa-workflows/updateStoresWorkflow", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Steps", + "autogenerate_tags": "step+pricing", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createShippingOptionsPriceSetsStep", + "path": "/references/medusa-workflows/steps/createShippingOptionsPriceSetsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "setShippingOptionsPricesStep", + "path": "/references/medusa-workflows/steps/setShippingOptionsPricesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createPriceListPricesStep", + "path": "/references/medusa-workflows/steps/createPriceListPricesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createPriceListsStep", + "path": "/references/medusa-workflows/steps/createPriceListsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deletePriceListsStep", + "path": "/references/medusa-workflows/steps/deletePriceListsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "removePriceListPricesStep", + "path": "/references/medusa-workflows/steps/removePriceListPricesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updatePriceListPricesStep", + "path": "/references/medusa-workflows/steps/updatePriceListPricesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updatePriceListsStep", + "path": "/references/medusa-workflows/steps/updatePriceListsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "validatePriceListsStep", + "path": "/references/medusa-workflows/steps/validatePriceListsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createPricePreferencesStep", + "path": "/references/medusa-workflows/steps/createPricePreferencesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createPriceSetsStep", + "path": "/references/medusa-workflows/steps/createPriceSetsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deletePricePreferencesStep", + "path": "/references/medusa-workflows/steps/deletePricePreferencesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updatePricePreferencesAsArrayStep", + "path": "/references/medusa-workflows/steps/updatePricePreferencesAsArrayStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updatePricePreferencesStep", + "path": "/references/medusa-workflows/steps/updatePricePreferencesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updatePriceSetsStep", + "path": "/references/medusa-workflows/steps/updatePriceSetsStep", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", "title": "References", + "initialOpen": false, "children": [ { "loaded": true, diff --git a/www/apps/resources/sidebars/pricing.mjs b/www/apps/resources/sidebars/pricing.mjs index 090fde1184b2a..c75402480aebf 100644 --- a/www/apps/resources/sidebars/pricing.mjs +++ b/www/apps/resources/sidebars/pricing.mjs @@ -11,13 +11,12 @@ export const pricingSidebar = [ title: "Overview", }, { - type: "link", - path: "/commerce-modules/pricing/examples", - title: "Examples", + type: "separator", }, { - type: "sub-category", + type: "category", title: "Concepts", + initialOpen: false, children: [ { type: "link", @@ -47,8 +46,51 @@ export const pricingSidebar = [ ], }, { - type: "sub-category", + type: "category", + title: "Server Guides", + autogenerate_tags: "server+pricing", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Storefront Guides", + autogenerate_tags: "storefront+pricing", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Admin Guides", + autogenerate_tags: "admin+pricing", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "User Guides", + autogenerate_tags: "userGuides+pricing", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Workflows", + autogenerate_tags: "workflow+pricing", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Steps", + autogenerate_tags: "step+pricing", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", title: "References", + initialOpen: false, children: [ { type: "link", diff --git a/www/packages/tags/src/tags/index.ts b/www/packages/tags/src/tags/index.ts index f1bc7d39bd525..01dd6a2272459 100644 --- a/www/packages/tags/src/tags/index.ts +++ b/www/packages/tags/src/tags/index.ts @@ -1,31 +1,32 @@ export * from "./product.js" export * from "./storefront.js" +export * from "./tax.js" export * from "./payment.js" export * from "./cart.js" export * from "./order.js" -export * from "./stripe.js" export * from "./fulfillment.js" -export * from "./customer.js" -export * from "./tax.js" -export * from "./product-collection.js" -export * from "./inventory.js" -export * from "./pricing.js" +export * from "./stripe.js" export * from "./query.js" export * from "./auth.js" -export * from "./remote-link.js" -export * from "./sales-channel.js" -export * from "./workflow.js" +export * from "./customer.js" +export * from "./product-category.js" +export * from "./server.js" export * from "./api-key.js" -export * from "./region.js" export * from "./publishable-api-key.js" +export * from "./pricing.js" +export * from "./region.js" +export * from "./sales-channel.js" +export * from "./step.js" export * from "./remote-query.js" +export * from "./inventory.js" +export * from "./product-collection.js" export * from "./event-bus.js" +export * from "./workflow.js" +export * from "./file.js" +export * from "./store.js" export * from "./logger.js" +export * from "./locking.js" export * from "./promotion.js" -export * from "./product-category.js" -export * from "./store.js" -export * from "./file.js" +export * from "./remote-link.js" export * from "./stock-location.js" -export * from "./step.js" -export * from "./locking.js" export * from "./user.js" diff --git a/www/packages/tags/src/tags/server.ts b/www/packages/tags/src/tags/server.ts new file mode 100644 index 0000000000000..1327cf802aed5 --- /dev/null +++ b/www/packages/tags/src/tags/server.ts @@ -0,0 +1,10 @@ +export const server = [ + { + "title": "Get Variant Prices", + "path": "/commerce-modules/product/guides/price" + }, + { + "title": "Get Variant Price with Taxes", + "path": "/commerce-modules/product/guides/price-with-taxes" + } +] \ No newline at end of file From eef9131f8170caee51b282df4749221a4523c852 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Wed, 25 Dec 2024 17:28:56 +0200 Subject: [PATCH 13/21] revise product module --- .../product/examples/page.mdx | 325 ---------- .../app/commerce-modules/product/page.mdx | 225 ++++--- www/apps/resources/generated/edit-dates.mjs | 3 +- www/apps/resources/generated/files-map.mjs | 4 - www/apps/resources/generated/sidebar.mjs | 590 +++++++++++++++++- www/apps/resources/sidebars/product.mjs | 75 ++- .../build-scripts/src/generate-sidebar.ts | 24 +- www/packages/tags/src/tags/index.ts | 30 +- 8 files changed, 803 insertions(+), 473 deletions(-) delete mode 100644 www/apps/resources/app/commerce-modules/product/examples/page.mdx diff --git a/www/apps/resources/app/commerce-modules/product/examples/page.mdx b/www/apps/resources/app/commerce-modules/product/examples/page.mdx deleted file mode 100644 index dace573df9095..0000000000000 --- a/www/apps/resources/app/commerce-modules/product/examples/page.mdx +++ /dev/null @@ -1,325 +0,0 @@ -import { CodeTabs, CodeTab } from "docs-ui" - -export const metadata = { - title: `Examples of the Product Module`, -} - -# {metadata.title} - -In this guide, you’ll find common examples of how you can use the Product Module in your application. - - - -You should only use the Product Module's main service when implementing complex customizations. For common cases, check out [available workflows instead](../../../medusa-workflows-reference/page.mdx). - - - -## Create Product - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST(request: MedusaRequest, res: MedusaResponse) { - const productModuleService = request.scope.resolve( - Modules.PRODUCT - ) - - const products = await productModuleService.createProducts([ - { - title: "Medusa Shirt", - options: [ - { - title: "Color", - }, - ], - variants: [ - { - title: "Black Shirt", - options: [ - { - value: "Black", - }, - ], - }, - ], - }, - ]) - - res.json({ products }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeProductModule } from "@medusajs/medusa/product" - -export async function POST(request: Request) { - const productModuleService = await initializeProductModule() - - const products = await productModuleService.createProducts([ - { - title: "Medusa Shirt", - options: [ - { - title: "Color", - }, - ], - variants: [ - { - title: "Black Shirt", - options: [ - { - value: "Black", - }, - ], - }, - ], - }, - ]) - - return NextResponse.json({ products }) -} -``` - - - - ---- - -## List Products - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET(request: MedusaRequest, res: MedusaResponse) { - const productModuleService = request.scope.resolve( - Modules.PRODUCT - ) - - const products = await productModuleService.listProducts() - - res.json({ products }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeProductModule } from "@medusajs/medusa/product" - -export async function GET(request: Request) { - const productModuleService = await initializeProductModule() - - const products = await productModuleService.listProducts() - - return NextResponse.json({ products }) -} -``` - - - - ---- - -## Retrieve a Product by its ID - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET(request: MedusaRequest, res: MedusaResponse) { - const productModuleService = request.scope.resolve( - Modules.PRODUCT - ) - - const product = await productModuleService.retrieveProduct(request.params.id) - - res.json({ product }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeProductModule } from "@medusajs/medusa/product" - -export async function GET( - request: Request, - { params }: { params: Record } -) { - const { id } = params - const productModuleService = await initializeProductModule() - - const product = await productModuleService.retrieveProduct(id) - - return NextResponse.json({ product }) -} -``` - - - - ---- - -## Retrieve a Product by its Handle - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET(request: MedusaRequest, res: MedusaResponse) { - const productModuleService = request.scope.resolve( - Modules.PRODUCT - ) - - const data = await productModuleService.listProducts({ - handle: "shirt", - }) - - res.json({ product: data[0] }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeProductModule } from "@medusajs/medusa/product" - -export async function GET(request: Request) { - const productModuleService = await initializeProductModule() - - const data = await productModuleService.listProducts({ - handle: "shirt", - }) - - return NextResponse.json({ product: data[0] }) -} -``` - - - - ---- - -## Retrieve Categories - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST(request: MedusaRequest, res: MedusaResponse) { - const productModuleService = request.scope.resolve( - Modules.PRODUCT - ) - - const categories = await productModuleService.listProductCategories() - - res.json({ categories }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeProductModule } from "@medusajs/medusa/product" - -export async function GET(request: Request) { - const productModuleService = await initializeProductModule() - - const categories = await productModuleService.listProductCategories() - - return NextResponse.json({ categories }) -} -``` - - - - ---- - -## Retrieve Category by Handle - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST(request: MedusaRequest, res: MedusaResponse) { - const productModuleService = request.scope.resolve( - Modules.PRODUCT - ) - - const data = await productModuleService.listProductCategories({ - handle: request.params.handle, - }) - - res.json({ category: data[0] }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeProductModule } from "@medusajs/medusa/product" - -export async function GET( - request: Request, - { params }: { params: Record } -) { - const { handle } = params - const productModuleService = await initializeProductModule() - - const data = await productModuleService.listProductCategories({ - handle, - }) - - return NextResponse.json({ category: data[0] }) -} -``` - - - - ---- - -## More Examples - -The [Product Module's main service reference](/references/product) provides a reference to all the methods available for use with examples for each. diff --git a/www/apps/resources/app/commerce-modules/product/page.mdx b/www/apps/resources/app/commerce-modules/product/page.mdx index df937a65754ed..81c9c1742bb56 100644 --- a/www/apps/resources/app/commerce-modules/product/page.mdx +++ b/www/apps/resources/app/commerce-modules/product/page.mdx @@ -6,114 +6,163 @@ export const metadata = { # {metadata.title} -The Product Module provides product-related features in your Medusa and Node.js applications. +In this section of the documentation, you will find resources to learn more about the Product Module and how to use it in your application. -## How to Use Product Module's Service +Medusa has product related features available out-of-the-box through the Product Module. A [module](!docs!/learn/fundamentals/modules) is a standalone package that provides features for a single domain. Each of Medusa's commerce features are placed in commerce modules, such as this Product Module. -You can use the Product Module's main service by resolving from the Medusa container the resource `Modules.PRODUCT`. + -For example: +Learn more about why modules are isolated in [this documentation](!docs!/learn/fundamentals/modules/isolation). - - + -```ts title="src/workflows/hello-world/step1.ts" -import { createStep } from "@medusajs/framework/workflows-sdk" -import { Modules } from "@medusajs/framework/utils" +## Product Features -const step1 = createStep("step-1", async (_, { container }) => { - const productModuleService = container.resolve( - Modules.PRODUCT - ) - - const products = await productModuleService.listProducts() -}) -``` +- [Products Management](/references/product/models/Product): Store and manage products. Products have custom options, such as color or size, and each variant in the product sets the value for these options. +- [Product Organization](/references/product/models): The Product Module provides different data models used to organize products, including categories, collections, tags, and more. - - +--- -```ts title="src/api/store/custom/route.ts" -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" +## How to Use Product Module's Service -export async function GET(request: MedusaRequest, res: MedusaResponse) { - const productModuleService = request.scope.resolve( - Modules.PRODUCT - ) +In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. - res.json({ - products: await productModuleService.listProducts(), - }) -} -``` +You can build custom workflows and steps. You can also re-use Medusa's workflows and steps, which are provided by the `@medusajs/medusa/core-flows` package. - - +For example: -```ts title="src/subscribers/custom-handler.ts" -import { SubscriberArgs } from "@medusajs/framework" +export const highlights = [ + ["12", "Modules.PRODUCT", "Resolve the module in a step."] +] + +```ts title="src/workflows/create-product.ts" highlights={highlights} +import { + createWorkflow, + WorkflowResponse, + createStep, + StepResponse, +} from "@medusajs/framework/workflows-sdk" import { Modules } from "@medusajs/framework/utils" -export default async function subscriberHandler({ container }: SubscriberArgs) { - const productModuleService = container.resolve( - Modules.PRODUCT - ) +const createProductStep = createStep( + "create-product", + async ({}, { container }) => { + const productService = container.resolve(Modules.PRODUCT) + + const product = await productService.createProducts({ + title: "Medusa Shirt", + options: [ + { + title: "Color", + values: ["Black", "White"], + }, + ], + variants: [ + { + title: "Black Shirt", + options: { + Color: "Black", + }, + }, + ], + }) - const products = await productModuleService.listProducts() -} + return new StepResponse({ product }, product.id) + }, + async (productId, { container }) => { + const productService = container.resolve(Modules.PRODUCT) + + await productService.deleteProducts([productId]) + } +) + +export const createProductWorkflow = createWorkflow( + "create-product", + () => { + const { product } = createProductStep() + + return new WorkflowResponse({ + product, + }) + } +) ``` - - +You can then execute the workflow in your custom API routes, scheduled jobs, or subscribers: ---- + + + + ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import type { + MedusaRequest, + MedusaResponse, + } from "@medusajs/framework/http" + import createProductWorkflow from "../../workflows/create-product" + + export async function GET( + req: MedusaRequest, + res: MedusaResponse + ) { + const { result } = await createProductWorkflow(req.scope) + .run() + + res.send(result) + } + ``` -## Features - -### Products Management - -Store and manage products. Products have custom options, such as color or size, and each variant in the product sets the value for these options. - -```ts -const products = await productService.createProducts([ - { - title: "Medusa Shirt", - options: [ - { - title: "Color", - values: ["Black", "White"], - }, - ], - variants: [ - { - title: "Black Shirt", - options: { - Color: "Black", - }, - }, - ], - }, -]) -``` + + + + ```ts title="src/subscribers/customer-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import { + type SubscriberConfig, + type SubscriberArgs, + } from "@medusajs/framework" + import createProductWorkflow from "../workflows/create-product" + + export default async function handleCustomerCreate({ + event: { data }, + container, + }: SubscriberArgs<{ id: string }>) { + const { result } = await createProductWorkflow(container) + .run() + + console.log(result) + } + + export const config: SubscriberConfig = { + event: "user.created", + } + ``` + + + + + ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} + import { MedusaContainer } from "@medusajs/framework/types" + import createProductWorkflow from "../workflows/create-product" + + export default async function myCustomJob( + container: MedusaContainer + ) { + const { result } = await createProductWorkflow(container) + .run() + + console.log(result.message) + } + + export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, + }; + ``` -### Product Organization + + -The Product Module provides different data models used to organize products, including categories, collections, tags, and more. +Learn more about workflows in [this documentation](!docs!/learn/fundamentals/workflows). -```ts -const category = await productService.createProductCategories({ - name: "Shirts", -}) +--- -const products = await productService.updateProducts([ - { - id: product.id, - categories: [ - { - id: category.id, - }, - ], - }, -]) -``` + \ No newline at end of file diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index 23472917352c7..ba7c9223a984f 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -62,10 +62,9 @@ export const generatedEditDates = { "app/commerce-modules/pricing/page.mdx": "2024-12-25T15:07:51.830Z", "app/commerce-modules/product/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/product/_events/page.mdx": "2024-07-03T19:27:13+03:00", - "app/commerce-modules/product/examples/page.mdx": "2024-10-09T13:59:32.887Z", "app/commerce-modules/product/guides/price/page.mdx": "2024-12-25T15:10:37.730Z", "app/commerce-modules/product/guides/price-with-taxes/page.mdx": "2024-12-25T15:10:40.879Z", - "app/commerce-modules/product/page.mdx": "2024-12-09T14:48:26.091Z", + "app/commerce-modules/product/page.mdx": "2024-12-25T15:15:51.007Z", "app/commerce-modules/promotion/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/promotion/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/promotion/actions/page.mdx": "2024-10-09T14:49:01.645Z", diff --git a/www/apps/resources/generated/files-map.mjs b/www/apps/resources/generated/files-map.mjs index 358cb610801a1..f11b7cfbd9446 100644 --- a/www/apps/resources/generated/files-map.mjs +++ b/www/apps/resources/generated/files-map.mjs @@ -435,10 +435,6 @@ export const filesMap = [ "filePath": "/www/apps/resources/app/commerce-modules/product/events/page.mdx", "pathname": "/commerce-modules/product/events" }, - { - "filePath": "/www/apps/resources/app/commerce-modules/product/examples/page.mdx", - "pathname": "/commerce-modules/product/examples" - }, { "filePath": "/www/apps/resources/app/commerce-modules/product/extend/page.mdx", "pathname": "/commerce-modules/product/extend" diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs index fa74306b494b0..ccfb62d6103f5 100644 --- a/www/apps/resources/generated/sidebar.mjs +++ b/www/apps/resources/generated/sidebar.mjs @@ -8854,26 +8854,14 @@ export const generatedSidebar = [ "children": [] }, { - "loaded": true, - "isPathHref": true, - "type": "link", - "path": "/commerce-modules/product/examples", - "title": "Examples", - "children": [] - }, - { - "loaded": true, - "isPathHref": true, - "type": "link", - "path": "/commerce-modules/product/extend", - "title": "Extend Module", - "children": [] + "type": "separator" }, { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", "title": "Concepts", + "initialOpen": false, "children": [ { "loaded": true, @@ -8888,10 +8876,20 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "sub-category", - "title": "Guides", - "autogenerate_path": "/commerce-modules/product/guides", + "type": "category", + "title": "Server Guides", + "autogenerate_tags": "server+product", + "initialOpen": false, + "autogenerate_as_ref": true, "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "link", + "path": "/commerce-modules/product/extend", + "title": "Extend Module", + "children": [] + }, { "loaded": true, "isPathHref": true, @@ -8913,8 +8911,562 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", + "title": "Storefront Guides", + "autogenerate_tags": "storefront+product", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "List Product Categories in Storefront", + "path": "/storefront-development/products/categories/list", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Retrieve Nested Categories in Storefront", + "path": "/storefront-development/products/categories/nested-categories", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Retrieve a Category's Products in Storefront", + "path": "/storefront-development/products/categories/products", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Retrieve a Category in Storefront", + "path": "/storefront-development/products/categories/retrieve", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "List Product Collections in Storefront", + "path": "/storefront-development/products/collections/list", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Retrieve a Collection's Products in Storefront", + "path": "/storefront-development/products/collections/products", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Retrieve a Collection in Storefront", + "path": "/storefront-development/products/collections/retrieve", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Retrieve Product Variant's Inventory in Storefront", + "path": "/storefront-development/products/inventory", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "List Products in Storefront", + "path": "/storefront-development/products/list", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Example: Show Sale Price", + "path": "/storefront-development/products/price/examples/sale-price", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Example: Show Variant's Price", + "path": "/storefront-development/products/price/examples/show-price", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Example: Show Price with Taxes", + "path": "/storefront-development/products/price/examples/tax-price", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Retrieve Product Variant's Prices in Storefront", + "path": "/storefront-development/products/price", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Retrieve a Product in Storefront", + "path": "/storefront-development/products/retrieve", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Select Product Variants in Storefront", + "path": "/storefront-development/products/variants", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Workflows", + "autogenerate_tags": "workflow+product", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "batchLinkProductsToCollectionWorkflow", + "path": "/references/medusa-workflows/batchLinkProductsToCollectionWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "batchProductVariantsWorkflow", + "path": "/references/medusa-workflows/batchProductVariantsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "batchProductsWorkflow", + "path": "/references/medusa-workflows/batchProductsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createCollectionsWorkflow", + "path": "/references/medusa-workflows/createCollectionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createProductOptionsWorkflow", + "path": "/references/medusa-workflows/createProductOptionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createProductTagsWorkflow", + "path": "/references/medusa-workflows/createProductTagsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createProductTypesWorkflow", + "path": "/references/medusa-workflows/createProductTypesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createProductVariantsWorkflow", + "path": "/references/medusa-workflows/createProductVariantsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createProductsWorkflow", + "path": "/references/medusa-workflows/createProductsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteCollectionsWorkflow", + "path": "/references/medusa-workflows/deleteCollectionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteProductOptionsWorkflow", + "path": "/references/medusa-workflows/deleteProductOptionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteProductTagsWorkflow", + "path": "/references/medusa-workflows/deleteProductTagsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteProductTypesWorkflow", + "path": "/references/medusa-workflows/deleteProductTypesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteProductVariantsWorkflow", + "path": "/references/medusa-workflows/deleteProductVariantsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteProductsWorkflow", + "path": "/references/medusa-workflows/deleteProductsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "importProductsWorkflow", + "path": "/references/medusa-workflows/importProductsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateCollectionsWorkflow", + "path": "/references/medusa-workflows/updateCollectionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateProductOptionsWorkflow", + "path": "/references/medusa-workflows/updateProductOptionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateProductTagsWorkflow", + "path": "/references/medusa-workflows/updateProductTagsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateProductTypesWorkflow", + "path": "/references/medusa-workflows/updateProductTypesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateProductVariantsWorkflow", + "path": "/references/medusa-workflows/updateProductVariantsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateProductsWorkflow", + "path": "/references/medusa-workflows/updateProductsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createProductCategoriesWorkflow", + "path": "/references/medusa-workflows/createProductCategoriesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteProductCategoriesWorkflow", + "path": "/references/medusa-workflows/deleteProductCategoriesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateProductCategoriesWorkflow", + "path": "/references/medusa-workflows/updateProductCategoriesWorkflow", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Steps", + "autogenerate_tags": "step+product", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "batchLinkProductsToCollectionStep", + "path": "/references/medusa-workflows/steps/batchLinkProductsToCollectionStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createCollectionsStep", + "path": "/references/medusa-workflows/steps/createCollectionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createProductOptionsStep", + "path": "/references/medusa-workflows/steps/createProductOptionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createProductTagsStep", + "path": "/references/medusa-workflows/steps/createProductTagsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createProductTypesStep", + "path": "/references/medusa-workflows/steps/createProductTypesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createProductVariantsStep", + "path": "/references/medusa-workflows/steps/createProductVariantsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createProductsStep", + "path": "/references/medusa-workflows/steps/createProductsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteCollectionsStep", + "path": "/references/medusa-workflows/steps/deleteCollectionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteProductOptionsStep", + "path": "/references/medusa-workflows/steps/deleteProductOptionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteProductTagsStep", + "path": "/references/medusa-workflows/steps/deleteProductTagsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteProductTypesStep", + "path": "/references/medusa-workflows/steps/deleteProductTypesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteProductVariantsStep", + "path": "/references/medusa-workflows/steps/deleteProductVariantsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteProductsStep", + "path": "/references/medusa-workflows/steps/deleteProductsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "getProductsStep", + "path": "/references/medusa-workflows/steps/getProductsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "groupProductsForBatchStep", + "path": "/references/medusa-workflows/steps/groupProductsForBatchStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "parseProductCsvStep", + "path": "/references/medusa-workflows/steps/parseProductCsvStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateCollectionsStep", + "path": "/references/medusa-workflows/steps/updateCollectionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateProductOptionsStep", + "path": "/references/medusa-workflows/steps/updateProductOptionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateProductTagsStep", + "path": "/references/medusa-workflows/steps/updateProductTagsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateProductTypesStep", + "path": "/references/medusa-workflows/steps/updateProductTypesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateProductVariantsStep", + "path": "/references/medusa-workflows/steps/updateProductVariantsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateProductsStep", + "path": "/references/medusa-workflows/steps/updateProductsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createProductCategoriesStep", + "path": "/references/medusa-workflows/steps/createProductCategoriesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteProductCategoriesStep", + "path": "/references/medusa-workflows/steps/deleteProductCategoriesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateProductCategoriesStep", + "path": "/references/medusa-workflows/steps/updateProductCategoriesStep", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", "title": "References", + "initialOpen": false, "children": [ { "loaded": true, diff --git a/www/apps/resources/sidebars/product.mjs b/www/apps/resources/sidebars/product.mjs index bb2157bd33663..715b29e016253 100644 --- a/www/apps/resources/sidebars/product.mjs +++ b/www/apps/resources/sidebars/product.mjs @@ -11,18 +11,12 @@ export const productSidebar = [ title: "Overview", }, { - type: "link", - path: "/commerce-modules/product/examples", - title: "Examples", - }, - { - type: "link", - path: "/commerce-modules/product/extend", - title: "Extend Module", + type: "separator", }, { - type: "sub-category", + type: "category", title: "Concepts", + initialOpen: false, children: [ { type: "link", @@ -32,13 +26,68 @@ export const productSidebar = [ ], }, { - type: "sub-category", - title: "Guides", - autogenerate_path: "/commerce-modules/product/guides", + type: "category", + title: "Server Guides", + autogenerate_tags: "server+product", + initialOpen: false, + autogenerate_as_ref: true, + children: [ + { + type: "link", + path: "/commerce-modules/product/extend", + title: "Extend Module", + }, + { + type: "link", + path: "/commerce-modules/product/guides/price", + title: "Get Variant Prices", + }, + { + type: "link", + path: "/commerce-modules/product/guides/price-with-taxes", + title: "Get Variant Price with Taxes", + }, + ], + }, + { + type: "category", + title: "Storefront Guides", + autogenerate_tags: "storefront+product", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Admin Guides", + autogenerate_tags: "admin+product", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "User Guides", + autogenerate_tags: "userGuides+product", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Workflows", + autogenerate_tags: "workflow+product", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Steps", + autogenerate_tags: "step+product", + initialOpen: false, + autogenerate_as_ref: true, }, { - type: "sub-category", + type: "category", title: "References", + initialOpen: false, children: [ { type: "link", diff --git a/www/packages/build-scripts/src/generate-sidebar.ts b/www/packages/build-scripts/src/generate-sidebar.ts index a958a59803f0a..a7bd54137a1c9 100644 --- a/www/packages/build-scripts/src/generate-sidebar.ts +++ b/www/packages/build-scripts/src/generate-sidebar.ts @@ -97,13 +97,23 @@ async function getAutogeneratedTagSidebarItems( const parsedTags = parseTags(tags) items.push( - ...parsedTags.map( - (tagItem) => - ({ - type, - ...tagItem, - }) as ItemsToAdd - ) + ...parsedTags + .filter((tagItem) => { + return existingChildren?.every((existingItem) => { + if (existingItem.type !== "link" && existingItem.type !== "ref") { + return true + } + + return existingItem.path !== tagItem.path + }) + }) + .map( + (tagItem) => + ({ + type, + ...tagItem, + }) as ItemsToAdd + ) ) return sidebarAttachHrefCommonOptions([...(existingChildren || []), ...items]) diff --git a/www/packages/tags/src/tags/index.ts b/www/packages/tags/src/tags/index.ts index 01dd6a2272459..03368a0de7535 100644 --- a/www/packages/tags/src/tags/index.ts +++ b/www/packages/tags/src/tags/index.ts @@ -1,32 +1,32 @@ export * from "./product.js" export * from "./storefront.js" export * from "./tax.js" -export * from "./payment.js" export * from "./cart.js" export * from "./order.js" -export * from "./fulfillment.js" +export * from "./payment.js" export * from "./stripe.js" -export * from "./query.js" +export * from "./fulfillment.js" +export * from "./product-category.js" export * from "./auth.js" export * from "./customer.js" -export * from "./product-category.js" -export * from "./server.js" +export * from "./product-collection.js" export * from "./api-key.js" +export * from "./inventory.js" export * from "./publishable-api-key.js" -export * from "./pricing.js" export * from "./region.js" -export * from "./sales-channel.js" export * from "./step.js" +export * from "./server.js" +export * from "./query.js" +export * from "./remote-link.js" +export * from "./pricing.js" +export * from "./sales-channel.js" +export * from "./workflow.js" export * from "./remote-query.js" -export * from "./inventory.js" -export * from "./product-collection.js" export * from "./event-bus.js" -export * from "./workflow.js" -export * from "./file.js" export * from "./store.js" -export * from "./logger.js" -export * from "./locking.js" -export * from "./promotion.js" -export * from "./remote-link.js" +export * from "./file.js" export * from "./stock-location.js" +export * from "./locking.js" +export * from "./logger.js" export * from "./user.js" +export * from "./promotion.js" From 36b67071eee797c3bb8582ecdb8a914e3d531eb7 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Wed, 25 Dec 2024 17:40:09 +0200 Subject: [PATCH 14/21] revise promotion module --- .../app/commerce-modules/api-key/page.mdx | 6 +- .../app/commerce-modules/auth/page.mdx | 2 +- .../app/commerce-modules/cart/page.mdx | 6 +- .../app/commerce-modules/currency/page.mdx | 6 +- .../app/commerce-modules/customer/page.mdx | 6 +- .../app/commerce-modules/fulfillment/page.mdx | 6 +- .../app/commerce-modules/inventory/page.mdx | 6 +- .../app/commerce-modules/order/page.mdx | 6 +- .../app/commerce-modules/payment/page.mdx | 6 +- .../app/commerce-modules/pricing/page.mdx | 6 +- .../app/commerce-modules/product/page.mdx | 6 +- .../promotion/examples/page.mdx | 261 ---------------- .../app/commerce-modules/promotion/page.mdx | 234 +++++++------- www/apps/resources/generated/edit-dates.mjs | 25 +- www/apps/resources/generated/files-map.mjs | 4 - www/apps/resources/generated/sidebar.mjs | 286 +++++++++++++++++- www/apps/resources/sidebars/promotion.mjs | 64 +++- www/packages/tags/src/tags/index.ts | 36 +-- 18 files changed, 516 insertions(+), 456 deletions(-) delete mode 100644 www/apps/resources/app/commerce-modules/promotion/examples/page.mdx diff --git a/www/apps/resources/app/commerce-modules/api-key/page.mdx b/www/apps/resources/app/commerce-modules/api-key/page.mdx index 65e109468224f..dc6151309a565 100644 --- a/www/apps/resources/app/commerce-modules/api-key/page.mdx +++ b/www/apps/resources/app/commerce-modules/api-key/page.mdx @@ -88,7 +88,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or MedusaRequest, MedusaResponse, } from "@medusajs/framework/http" - import createApiKeyWorkflow from "../../workflows/create-api-key" + import {createApiKeyWorkflow} from "../../workflows/create-api-key" export async function GET( req: MedusaRequest, @@ -109,7 +109,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or type SubscriberConfig, type SubscriberArgs, } from "@medusajs/framework" - import createApiKeyWorkflow from "../workflows/create-api-key" + import {createApiKeyWorkflow} from "../workflows/create-api-key" export default async function handleCustomerCreate({ event: { data }, @@ -131,7 +131,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} import { MedusaContainer } from "@medusajs/framework/types" - import createApiKeyWorkflow from "../workflows/create-api-key" + import {createApiKeyWorkflow} from "../workflows/create-api-key" export default async function myCustomJob( container: MedusaContainer diff --git a/www/apps/resources/app/commerce-modules/auth/page.mdx b/www/apps/resources/app/commerce-modules/auth/page.mdx index 8a7ea0db3696c..eb8c05b5b535c 100644 --- a/www/apps/resources/app/commerce-modules/auth/page.mdx +++ b/www/apps/resources/app/commerce-modules/auth/page.mdx @@ -102,7 +102,7 @@ import type { MedusaRequest, MedusaResponse, } from "@medusajs/framework/http" -import authenticateUserWorkflow from "../../workflows/authenticate-user" +import {authenticateUserWorkflow} from "../../workflows/authenticate-user" export async function GET( req: MedusaRequest, diff --git a/www/apps/resources/app/commerce-modules/cart/page.mdx b/www/apps/resources/app/commerce-modules/cart/page.mdx index 4805201dc3075..82a66f2d038e3 100644 --- a/www/apps/resources/app/commerce-modules/cart/page.mdx +++ b/www/apps/resources/app/commerce-modules/cart/page.mdx @@ -97,7 +97,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or MedusaRequest, MedusaResponse, } from "@medusajs/framework/http" - import createCartWorkflow from "../../workflows/create-cart" + import { createCartWorkflow } from "../../workflows/create-cart" export async function GET( req: MedusaRequest, @@ -118,7 +118,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or type SubscriberConfig, type SubscriberArgs, } from "@medusajs/framework" - import createCartWorkflow from "../workflows/create-cart" + import { createCartWorkflow } from "../workflows/create-cart" export default async function handleCustomerCreate({ event: { data }, @@ -140,7 +140,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} import { MedusaContainer } from "@medusajs/framework/types" - import createCartWorkflow from "../workflows/create-cart" + import { createCartWorkflow } from "../workflows/create-cart" export default async function myCustomJob( container: MedusaContainer diff --git a/www/apps/resources/app/commerce-modules/currency/page.mdx b/www/apps/resources/app/commerce-modules/currency/page.mdx index 31403b367adac..17dad70a70fbf 100644 --- a/www/apps/resources/app/commerce-modules/currency/page.mdx +++ b/www/apps/resources/app/commerce-modules/currency/page.mdx @@ -90,7 +90,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or MedusaRequest, MedusaResponse, } from "@medusajs/framework/http" - import retrievePriceWithCurrency from "../../workflows/retrieve-price-with-currency" + import {retrievePriceWithCurrency} from "../../workflows/retrieve-price-with-currency" export async function GET( req: MedusaRequest, @@ -113,7 +113,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or type SubscriberConfig, type SubscriberArgs, } from "@medusajs/framework" - import retrievePriceWithCurrency from "../workflows/retrieve-price-with-currency" + import {retrievePriceWithCurrency} from "../workflows/retrieve-price-with-currency" export default async function handleCustomerCreate({ event: { data }, @@ -137,7 +137,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"], ["9"], ["10"]]} import { MedusaContainer } from "@medusajs/framework/types" - import retrievePriceWithCurrency from "../workflows/retrieve-price-with-currency" + import {retrievePriceWithCurrency} from "../workflows/retrieve-price-with-currency" export default async function myCustomJob( container: MedusaContainer diff --git a/www/apps/resources/app/commerce-modules/customer/page.mdx b/www/apps/resources/app/commerce-modules/customer/page.mdx index b30ea6e4c3e3a..1efa6f76f8e91 100644 --- a/www/apps/resources/app/commerce-modules/customer/page.mdx +++ b/www/apps/resources/app/commerce-modules/customer/page.mdx @@ -86,7 +86,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or MedusaRequest, MedusaResponse, } from "@medusajs/framework/http" - import createCustomerWorkflow from "../../workflows/create-customer" + import {createCustomerWorkflow} from "../../workflows/create-customer" export async function GET( req: MedusaRequest, @@ -107,7 +107,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or type SubscriberConfig, type SubscriberArgs, } from "@medusajs/framework" - import createCustomerWorkflow from "../workflows/create-customer" + import {createCustomerWorkflow} from "../workflows/create-customer" export default async function handleCustomerCreate({ event: { data }, @@ -129,7 +129,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} import { MedusaContainer } from "@medusajs/framework/types" - import createCustomerWorkflow from "../workflows/create-customer" + import {createCustomerWorkflow} from "../workflows/create-customer" export default async function myCustomJob( container: MedusaContainer diff --git a/www/apps/resources/app/commerce-modules/fulfillment/page.mdx b/www/apps/resources/app/commerce-modules/fulfillment/page.mdx index 61617cb311565..f84d19bf998fa 100644 --- a/www/apps/resources/app/commerce-modules/fulfillment/page.mdx +++ b/www/apps/resources/app/commerce-modules/fulfillment/page.mdx @@ -102,7 +102,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or MedusaRequest, MedusaResponse, } from "@medusajs/framework/http" - import createFulfillmentWorkflow from "../../workflows/create-fuilfillment" + import {createFulfillmentWorkflow} from "../../workflows/create-fuilfillment" export async function GET( req: MedusaRequest, @@ -123,7 +123,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or type SubscriberConfig, type SubscriberArgs, } from "@medusajs/framework" - import createFulfillmentWorkflow from "../workflows/create-fuilfillment" + import {createFulfillmentWorkflow} from "../workflows/create-fuilfillment" export default async function handleCustomerCreate({ event: { data }, @@ -145,7 +145,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} import { MedusaContainer } from "@medusajs/framework/types" - import createFulfillmentWorkflow from "../workflows/create-fuilfillment" + import {createFulfillmentWorkflow} from "../workflows/create-fuilfillment" export default async function myCustomJob( container: MedusaContainer diff --git a/www/apps/resources/app/commerce-modules/inventory/page.mdx b/www/apps/resources/app/commerce-modules/inventory/page.mdx index ee13b06abbd83..169c4737c59b1 100644 --- a/www/apps/resources/app/commerce-modules/inventory/page.mdx +++ b/www/apps/resources/app/commerce-modules/inventory/page.mdx @@ -88,7 +88,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or MedusaRequest, MedusaResponse, } from "@medusajs/framework/http" - import createInventoryItemWorkflow from "../../workflows/create-inventory-item" + import {createInventoryItemWorkflow} from "../../workflows/create-inventory-item" export async function GET( req: MedusaRequest, @@ -109,7 +109,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or type SubscriberConfig, type SubscriberArgs, } from "@medusajs/framework" - import createInventoryItemWorkflow from "../workflows/create-inventory-item" + import {createInventoryItemWorkflow} from "../workflows/create-inventory-item" export default async function handleCustomerCreate({ event: { data }, @@ -131,7 +131,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} import { MedusaContainer } from "@medusajs/framework/types" - import createInventoryItemWorkflow from "../workflows/create-inventory-item" + import {createInventoryItemWorkflow} from "../workflows/create-inventory-item" export default async function myCustomJob( container: MedusaContainer diff --git a/www/apps/resources/app/commerce-modules/order/page.mdx b/www/apps/resources/app/commerce-modules/order/page.mdx index 6002dfe9430bd..1ddf411f105c0 100644 --- a/www/apps/resources/app/commerce-modules/order/page.mdx +++ b/www/apps/resources/app/commerce-modules/order/page.mdx @@ -101,7 +101,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or MedusaRequest, MedusaResponse, } from "@medusajs/framework/http" - import createDraftOrderWorkflow from "../../workflows/create-draft-order" + import {createDraftOrderWorkflow} from "../../workflows/create-draft-order" export async function GET( req: MedusaRequest, @@ -122,7 +122,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or type SubscriberConfig, type SubscriberArgs, } from "@medusajs/framework" - import createDraftOrderWorkflow from "../workflows/create-draft-order" + import {createDraftOrderWorkflow} from "../workflows/create-draft-order" export default async function handleCustomerCreate({ event: { data }, @@ -144,7 +144,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} import { MedusaContainer } from "@medusajs/framework/types" - import createDraftOrderWorkflow from "../workflows/create-draft-order" + import {createDraftOrderWorkflow} from "../workflows/create-draft-order" export default async function myCustomJob( container: MedusaContainer diff --git a/www/apps/resources/app/commerce-modules/payment/page.mdx b/www/apps/resources/app/commerce-modules/payment/page.mdx index 8cfae8ae46c4e..4361846265306 100644 --- a/www/apps/resources/app/commerce-modules/payment/page.mdx +++ b/www/apps/resources/app/commerce-modules/payment/page.mdx @@ -88,7 +88,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or MedusaRequest, MedusaResponse, } from "@medusajs/framework/http" - import createPaymentCollectionWorkflow from "../../workflows/create-payment-collection" + import {createPaymentCollectionWorkflow} from "../../workflows/create-payment-collection" export async function GET( req: MedusaRequest, @@ -109,7 +109,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or type SubscriberConfig, type SubscriberArgs, } from "@medusajs/framework" - import createPaymentCollectionWorkflow from "../workflows/create-payment-collection" + import {createPaymentCollectionWorkflow} from "../workflows/create-payment-collection" export default async function handleCustomerCreate({ event: { data }, @@ -131,7 +131,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} import { MedusaContainer } from "@medusajs/framework/types" - import createPaymentCollectionWorkflow from "../workflows/create-payment-collection" + import {createPaymentCollectionWorkflow} from "../workflows/create-payment-collection" export default async function myCustomJob( container: MedusaContainer diff --git a/www/apps/resources/app/commerce-modules/pricing/page.mdx b/www/apps/resources/app/commerce-modules/pricing/page.mdx index 571c4d3eb041b..6f2bd434ddf9e 100644 --- a/www/apps/resources/app/commerce-modules/pricing/page.mdx +++ b/www/apps/resources/app/commerce-modules/pricing/page.mdx @@ -99,7 +99,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or MedusaRequest, MedusaResponse, } from "@medusajs/framework/http" - import createPriceSetWorkflow from "../../workflows/create-price-set" + import {createPriceSetWorkflow} from "../../workflows/create-price-set" export async function GET( req: MedusaRequest, @@ -120,7 +120,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or type SubscriberConfig, type SubscriberArgs, } from "@medusajs/framework" - import createPriceSetWorkflow from "../workflows/create-price-set" + import {createPriceSetWorkflow} from "../workflows/create-price-set" export default async function handleCustomerCreate({ event: { data }, @@ -142,7 +142,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} import { MedusaContainer } from "@medusajs/framework/types" - import createPriceSetWorkflow from "../workflows/create-price-set" + import {createPriceSetWorkflow} from "../workflows/create-price-set" export default async function myCustomJob( container: MedusaContainer diff --git a/www/apps/resources/app/commerce-modules/product/page.mdx b/www/apps/resources/app/commerce-modules/product/page.mdx index 81c9c1742bb56..084f5d3d0d8c9 100644 --- a/www/apps/resources/app/commerce-modules/product/page.mdx +++ b/www/apps/resources/app/commerce-modules/product/page.mdx @@ -98,7 +98,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or MedusaRequest, MedusaResponse, } from "@medusajs/framework/http" - import createProductWorkflow from "../../workflows/create-product" + import {createProductWorkflow} from "../../workflows/create-product" export async function GET( req: MedusaRequest, @@ -119,7 +119,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or type SubscriberConfig, type SubscriberArgs, } from "@medusajs/framework" - import createProductWorkflow from "../workflows/create-product" + import {createProductWorkflow} from "../workflows/create-product" export default async function handleCustomerCreate({ event: { data }, @@ -141,7 +141,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} import { MedusaContainer } from "@medusajs/framework/types" - import createProductWorkflow from "../workflows/create-product" + import {createProductWorkflow} from "../workflows/create-product" export default async function myCustomJob( container: MedusaContainer diff --git a/www/apps/resources/app/commerce-modules/promotion/examples/page.mdx b/www/apps/resources/app/commerce-modules/promotion/examples/page.mdx deleted file mode 100644 index bdbdde6ff103f..0000000000000 --- a/www/apps/resources/app/commerce-modules/promotion/examples/page.mdx +++ /dev/null @@ -1,261 +0,0 @@ -import { CodeTabs, CodeTab } from "docs-ui" - -export const metadata = { - title: `Examples of the Promotion Module`, -} - -# {metadata.title} - -In this document, you’ll find common examples of how you can use the Promotion Module in your application. - - - -You should only use the Promotion Module's main service when implementing complex customizations. For common cases, check out [available workflows instead](../../../medusa-workflows-reference/page.mdx). - - - -## Create a Promotion - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const promotionModuleService = request.scope.resolve( - Modules.PROMOTION - ) - - const promotion = await promotionModuleService.createPromotions({ - code: "10%OFF", - type: "standard", - application_method: { - type: "percentage", - target_type: "order", - value: "10", - currency_code: "usd", - }, - }) - - res.json({ promotion }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializePromotionModule } from "@medusajs/medusa/promotion" - -export async function POST(request: Request) { - const promotionModuleService = await initializePromotionModule() - const body = await request.json() - - const promotion = await promotionModuleService.createPromotions({ - code: "10%OFF", - type: "standard", - application_method: { - type: "percentage", - target_type: "order", - value: "10", - currency_code: "usd", - }, - }) - - return NextResponse.json({ promotion }) -} -``` - - - - ---- - -## Create a Campaign - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const promotionModuleService = request.scope.resolve( - Modules.PROMOTION - ) - - const campaign = await promotionModuleService.createCampaigns({ - name: "Summer Discounts", - campaign_identifier: "G-123445", - starts_at: new Date("2024-05-02"), - ends_at: new Date("2024-07-20"), - }) - - res.json({ campaign }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializePromotionModule } from "@medusajs/medusa/promotion" - -export async function POST(request: Request) { - const promotionModuleService = await initializePromotionModule() - const body = await request.json() - - const campaign = await promotionModuleService.createCampaigns({ - name: "Summer Discounts", - campaign_identifier: "G-123445", - starts_at: new Date("2024-05-02"), - ends_at: new Date("2024-07-20"), - }) - - return NextResponse.json({ campaign }) -} -``` - - - - ---- - -## Create a Promotion with Flexible Rules - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const promotionModuleService = request.scope.resolve( - Modules.PROMOTION - ) - - const promotion = await promotionModuleService.createPromotions({ - code: "10%OFF", - type: "standard", - application_method: { - type: "percentage", - target_type: "order", - value: "10", - currency_code: "usd", - }, - rules: [ - { - attribute: "customer_group_id", - operator: "eq", - values: ["VIP"], - }, - ], - }) - - res.json({ promotion }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializePromotionModule } from "@medusajs/medusa/promotion" - -export async function POST(request: Request) { - const promotionModuleService = await initializePromotionModule() - - const promotion = await promotionModuleService.createPromotions({ - code: "10%OFF", - type: "standard", - application_method: { - type: "percentage", - target_type: "order", - value: "10", - currency_code: "usd", - }, - rules: [ - { - attribute: "customer_group_id", - operator: "eq", - values: ["VIP"], - }, - ], - }) - - return NextResponse.json({ promotion }) -} -``` - - - - ---- - -## List Promotions - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const promotionModuleService = request.scope.resolve( - Modules.PROMOTION - ) - - res.json({ - promotions: await promotionModuleService.listPromotions(), - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializePromotionModule } from "@medusajs/medusa/promotion" - -export async function GET(request: Request) { - const promotionModuleService = await initializePromotionModule() - - return NextResponse.json({ - promotions: await promotionModuleService.listPromotions(), - }) -} -``` - - - - ---- - -## More Examples - -The [Promotion Module's main service reference](/references/promotion) provides a reference to all the methods available for use with examples for each. diff --git a/www/apps/resources/app/commerce-modules/promotion/page.mdx b/www/apps/resources/app/commerce-modules/promotion/page.mdx index 0539c524dcf8a..67aa457e79454 100644 --- a/www/apps/resources/app/commerce-modules/promotion/page.mdx +++ b/www/apps/resources/app/commerce-modules/promotion/page.mdx @@ -6,130 +6,158 @@ export const metadata = { # {metadata.title} -The Promotion Module provides promotion-related features in your Medusa and Node.js applications. +In this section of the documentation, you will find resources to learn more about the Promotion Module and how to use it in your application. -## How to Use the Promotion Module's Service +Medusa has promotion related features available out-of-the-box through the Promotion Module. A [module](!docs!/learn/fundamentals/modules) is a standalone package that provides features for a single domain. Each of Medusa's commerce features are placed in commerce modules, such as this Promotion Module. -You can use the Promotion Module's main service by resolving from the Medusa container the resource `Modules.PROMOTION`. + -For example: +Learn more about why modules are isolated in [this documentation](!docs!/learn/fundamentals/modules/isolation). - - + -```ts title="src/workflows/hello-world/step1.ts" -import { createStep } from "@medusajs/framework/workflows-sdk" -import { Modules } from "@medusajs/framework/utils" +## Promotion Features -const step1 = createStep("step-1", async (_, { container }) => { - const promotionModuleService = container.resolve( - Modules.PROMOTION - ) +- [Discount Functionalities](./concepts/page.mdx): A promotion discounts an amount or percentage of a cart's items, shipping methods, or the entire order. +- [Flexible Promotion Rules](./concepts/page.mdx#flexible-rules): A promotion has rules that restricts when the promotion is applied. +- [Campaign Management](./campaign/page.mdx): A campaign combines promotions under the same conditions, such as start and end dates, and budget configurations. +- [Apply Promotion on Carts and Orders](./actions/page.mdx): Apply promotions on carts and orders to discount items, shipping methods, or the entire order. - const promotions = await promotionModuleService.listPromotions() -}) -``` +--- - - +## How to Use the Promotion Module's Service -```ts title="src/api/store/custom/route.ts" -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" +In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. -export async function GET( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const promotionModuleService = request.scope.resolve( - Modules.PROMOTION - ) - - res.json({ - promotions: await promotionModuleService.listPromotions(), - }) -} -``` +You can build custom workflows and steps. You can also re-use Medusa's workflows and steps, which are provided by the `@medusajs/medusa/core-flows` package. - - +For example: -```ts title="src/subscribers/custom-handler.ts" -import { SubscriberArgs } from "@medusajs/framework" +export const highlights = [ + ["12", "Modules.PROMOTION", "Resolve the module in a step."] +] + +```ts title="src/workflows/create-promotion.ts" highlights={highlights} +import { + createWorkflow, + WorkflowResponse, + createStep, + StepResponse, +} from "@medusajs/framework/workflows-sdk" import { Modules } from "@medusajs/framework/utils" -export default async function subscriberHandler({ container }: SubscriberArgs) { - const promotionModuleService = container.resolve( - Modules.PROMOTION - ) - - const promotions = await promotionModuleService.listPromotions() -} -``` - - - - ---- - -## Features - -### Discount Functionalities - -A promotion discounts an amount or percentage of a cart's items, shipping methods, or the entire order. - -The Promotion Module allows you to store and manage promotions. - -```ts -const promotion = await promotionModuleService.createPromotions({ - code: "10%OFF", - type: "standard", - application_method: { - type: "percentage", - target_type: "order", - value: "10", - currency_code: "usd", +const createPromotionStep = createStep( + "create-promotion", + async ({}, { container }) => { + const promotionModuleService = container.resolve(Modules.PROMOTION) + + const promotion = await promotionModuleService.createPromotions({ + code: "10%OFF", + type: "standard", + application_method: { + type: "percentage", + target_type: "order", + value: "10", + currency_code: "usd", + }, + }) + + return new StepResponse({ promotion }, promotion.id) }, -}) + async (promotionId, { container }) => { + const promotionModuleService = container.resolve(Modules.PROMOTION) + + await promotionModuleService.deletePromotions(promotionId) + } +) + +export const createPromotionWorkflow = createWorkflow( + "create-promotion", + () => { + const { promotion } = createPromotionStep() + + return new WorkflowResponse({ + promotion, + }) + } +) ``` -### Flexible Promotion Rules +You can then execute the workflow in your custom API routes, scheduled jobs, or subscribers: -A promotion has rules that restricts when it's applied. + + + + ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import type { + MedusaRequest, + MedusaResponse, + } from "@medusajs/framework/http" + import { createPromotionWorkflow } from "../../workflows/create-cart" + + export async function GET( + req: MedusaRequest, + res: MedusaResponse + ) { + const { result } = await createPromotionWorkflow(req.scope) + .run() + + res.send(result) + } + ``` -For example, you can create a promotion that's only applied to VIP customers. + + + + ```ts title="src/subscribers/customer-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import { + type SubscriberConfig, + type SubscriberArgs, + } from "@medusajs/framework" + import { createPromotionWorkflow } from "../workflows/create-cart" + + export default async function handleCustomerCreate({ + event: { data }, + container, + }: SubscriberArgs<{ id: string }>) { + const { result } = await createPromotionWorkflow(container) + .run() + + console.log(result) + } + + export const config: SubscriberConfig = { + event: "user.created", + } + ``` -```ts -const promotion = await promotionModuleService.createPromotions({ - code: "10%OFF", - type: "standard", - application_method: { - type: "percentage", - target_type: "order", - value: "10", - currency_code: "usd", - }, - rules: [ - { - attribute: "customer_group_id", - operator: "eq", - values: ["VIP"], - }, - ], -}) -``` + + + + ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} + import { MedusaContainer } from "@medusajs/framework/types" + import { createPromotionWorkflow } from "../workflows/create-cart" + + export default async function myCustomJob( + container: MedusaContainer + ) { + const { result } = await createPromotionWorkflow(container) + .run() + + console.log(result.message) + } + + export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, + }; + ``` -### Campaign Management + + -A campaign combines promotions under the same conditions, such as start and end dates. +Learn more about workflows in [this documentation](!docs!/learn/fundamentals/workflows). -A campaign can also have an identifier for tracking purposes, such as tracking through tools like Google Analytics. +--- -```ts -const campaign = await promotionModuleService.createCampaigns({ - name: "Summer Discounts", - campaign_identifier: "G-123445", - starts_at: new Date("2024-05-02"), - ends_at: new Date("2024-07-20"), -}) -``` + \ No newline at end of file diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index ba7c9223a984f..b07db6b092675 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -4,20 +4,20 @@ export const generatedEditDates = { "app/commerce-modules/auth/authentication-route/page.mdx": "2024-09-05T12:06:38.155Z", "app/commerce-modules/auth/examples/page.mdx": "2024-10-15T15:02:13.794Z", "app/commerce-modules/auth/module-options/page.mdx": "2024-10-15T12:52:08.930Z", - "app/commerce-modules/auth/page.mdx": "2024-12-25T13:54:02.084Z", + "app/commerce-modules/auth/page.mdx": "2024-12-25T15:34:06.324Z", "app/commerce-modules/cart/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/cart/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/cart/concepts/page.mdx": "2024-10-08T07:49:03.737Z", "app/commerce-modules/cart/promotions/page.mdx": "2024-10-08T07:54:31.120Z", "app/commerce-modules/cart/tax-lines/page.mdx": "2024-10-08T07:57:19.168Z", - "app/commerce-modules/cart/page.mdx": "2024-12-25T14:06:23.995Z", + "app/commerce-modules/cart/page.mdx": "2024-12-25T15:34:00.328Z", "app/commerce-modules/currency/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/currency/_events/page.mdx": "2024-07-03T19:27:13+03:00", - "app/commerce-modules/currency/page.mdx": "2024-12-25T13:56:32.681Z", + "app/commerce-modules/currency/page.mdx": "2024-12-25T15:34:34.474Z", "app/commerce-modules/customer/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/customer/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/customer/customer-accounts/page.mdx": "2024-10-08T12:20:44.769Z", - "app/commerce-modules/customer/page.mdx": "2024-12-25T13:55:18.405Z", + "app/commerce-modules/customer/page.mdx": "2024-12-25T15:34:45.522Z", "app/commerce-modules/fulfillment/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/fulfillment/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/fulfillment/concepts/page.mdx": "2024-06-19T13:02:16+00:00", @@ -25,12 +25,12 @@ export const generatedEditDates = { "app/commerce-modules/fulfillment/item-fulfillment/page.mdx": "2024-10-08T14:38:15.496Z", "app/commerce-modules/fulfillment/module-options/page.mdx": "2024-10-15T12:51:56.118Z", "app/commerce-modules/fulfillment/shipping-option/page.mdx": "2024-10-08T14:36:02.660Z", - "app/commerce-modules/fulfillment/page.mdx": "2024-12-25T14:07:33.995Z", + "app/commerce-modules/fulfillment/page.mdx": "2024-12-25T15:34:57.942Z", "app/commerce-modules/inventory/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/inventory/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/inventory/concepts/page.mdx": "2024-10-08T15:11:27.634Z", "app/commerce-modules/inventory/inventory-in-flows/page.mdx": "2024-10-08T15:14:07.327Z", - "app/commerce-modules/inventory/page.mdx": "2024-12-25T14:21:22.529Z", + "app/commerce-modules/inventory/page.mdx": "2024-12-25T15:35:09.948Z", "app/commerce-modules/order/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/order/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/order/claim/page.mdx": "2024-10-09T10:11:12.090Z", @@ -41,7 +41,7 @@ export const generatedEditDates = { "app/commerce-modules/order/return/page.mdx": "2024-10-09T10:19:40.731Z", "app/commerce-modules/order/tax-lines/page.mdx": "2024-10-09T10:22:49.335Z", "app/commerce-modules/order/transactions/page.mdx": "2024-10-09T10:23:36.485Z", - "app/commerce-modules/order/page.mdx": "2024-12-25T14:34:00.973Z", + "app/commerce-modules/order/page.mdx": "2024-12-25T15:35:28.286Z", "app/commerce-modules/payment/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/payment/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/payment/module-options/page.mdx": "2024-10-15T12:51:40.574Z", @@ -52,27 +52,26 @@ export const generatedEditDates = { "app/commerce-modules/payment/payment-provider/page.mdx": "2024-10-09T11:07:27.269Z", "app/commerce-modules/payment/payment-session/page.mdx": "2024-10-09T10:58:00.960Z", "app/commerce-modules/payment/webhook-events/page.mdx": "2024-11-19T11:45:02.167Z", - "app/commerce-modules/payment/page.mdx": "2024-12-25T14:47:19.426Z", + "app/commerce-modules/payment/page.mdx": "2024-12-25T15:35:50.188Z", "app/commerce-modules/pricing/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/pricing/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/pricing/concepts/page.mdx": "2024-10-09T13:37:25.678Z", "app/commerce-modules/pricing/price-calculation/page.mdx": "2024-10-09T13:43:14.038Z", "app/commerce-modules/pricing/price-rules/page.mdx": "2024-10-09T13:38:47.112Z", "app/commerce-modules/pricing/tax-inclusive-pricing/page.mdx": "2024-10-09T13:48:23.261Z", - "app/commerce-modules/pricing/page.mdx": "2024-12-25T15:07:51.830Z", + "app/commerce-modules/pricing/page.mdx": "2024-12-25T15:36:08.572Z", "app/commerce-modules/product/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/product/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/product/guides/price/page.mdx": "2024-12-25T15:10:37.730Z", "app/commerce-modules/product/guides/price-with-taxes/page.mdx": "2024-12-25T15:10:40.879Z", - "app/commerce-modules/product/page.mdx": "2024-12-25T15:15:51.007Z", + "app/commerce-modules/product/page.mdx": "2024-12-25T15:36:22.150Z", "app/commerce-modules/promotion/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/promotion/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/promotion/actions/page.mdx": "2024-10-09T14:49:01.645Z", "app/commerce-modules/promotion/application-method/page.mdx": "2024-06-26T07:55:59+00:00", "app/commerce-modules/promotion/campaign/page.mdx": "2024-05-29T11:08:06+00:00", "app/commerce-modules/promotion/concepts/page.mdx": "2024-10-09T14:50:50.255Z", - "app/commerce-modules/promotion/examples/page.mdx": "2024-10-09T14:46:47.191Z", - "app/commerce-modules/promotion/page.mdx": "2024-12-09T14:48:30.816Z", + "app/commerce-modules/promotion/page.mdx": "2024-12-25T15:36:36.877Z", "app/commerce-modules/region/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/region/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/region/examples/page.mdx": "2024-10-15T15:00:24.388Z", @@ -202,7 +201,7 @@ export const generatedEditDates = { "app/commerce-modules/auth/auth-flows/page.mdx": "2024-09-05T08:50:11.671Z", "app/commerce-modules/auth/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/auth/auth-identity-and-actor-types/page.mdx": "2024-12-09T13:04:01.129Z", - "app/commerce-modules/api-key/page.mdx": "2024-12-25T13:54:14.876Z", + "app/commerce-modules/api-key/page.mdx": "2024-12-25T15:34:22.481Z", "app/commerce-modules/auth/create-actor-type/page.mdx": "2024-12-25T13:26:27.176Z", "app/architectural-modules/page.mdx": "2024-12-11T10:33:53.064Z", "app/architectural-modules/workflow-engine/redis/page.mdx": "2024-10-15T12:50:59.507Z", diff --git a/www/apps/resources/generated/files-map.mjs b/www/apps/resources/generated/files-map.mjs index f11b7cfbd9446..5dc9b7b1e64fe 100644 --- a/www/apps/resources/generated/files-map.mjs +++ b/www/apps/resources/generated/files-map.mjs @@ -475,10 +475,6 @@ export const filesMap = [ "filePath": "/www/apps/resources/app/commerce-modules/promotion/concepts/page.mdx", "pathname": "/commerce-modules/promotion/concepts" }, - { - "filePath": "/www/apps/resources/app/commerce-modules/promotion/examples/page.mdx", - "pathname": "/commerce-modules/promotion/examples" - }, { "filePath": "/www/apps/resources/app/commerce-modules/promotion/extend/page.mdx", "pathname": "/commerce-modules/promotion/extend" diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs index ccfb62d6103f5..ae9f7ec38e1c7 100644 --- a/www/apps/resources/generated/sidebar.mjs +++ b/www/apps/resources/generated/sidebar.mjs @@ -10177,26 +10177,14 @@ export const generatedSidebar = [ "children": [] }, { - "loaded": true, - "isPathHref": true, - "type": "link", - "path": "/commerce-modules/promotion/examples", - "title": "Examples", - "children": [] - }, - { - "loaded": true, - "isPathHref": true, - "type": "link", - "path": "/commerce-modules/promotion/extend", - "title": "Extend Module", - "children": [] + "type": "separator" }, { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", "title": "Concepts", + "initialOpen": false, "children": [ { "loaded": true, @@ -10243,8 +10231,274 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", + "title": "Server Guides", + "autogenerate_tags": "server+promotion", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "link", + "path": "/commerce-modules/promotion/extend", + "title": "Extend Module", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Workflows", + "autogenerate_tags": "workflow+promotion", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createCartWorkflow", + "path": "/references/medusa-workflows/createCartWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateCartPromotionsWorkflow", + "path": "/references/medusa-workflows/updateCartPromotionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "addOrRemoveCampaignPromotionsWorkflow", + "path": "/references/medusa-workflows/addOrRemoveCampaignPromotionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "batchPromotionRulesWorkflow", + "path": "/references/medusa-workflows/batchPromotionRulesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createCampaignsWorkflow", + "path": "/references/medusa-workflows/createCampaignsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createPromotionRulesWorkflow", + "path": "/references/medusa-workflows/createPromotionRulesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createPromotionsWorkflow", + "path": "/references/medusa-workflows/createPromotionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteCampaignsWorkflow", + "path": "/references/medusa-workflows/deleteCampaignsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deletePromotionRulesWorkflow", + "path": "/references/medusa-workflows/deletePromotionRulesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deletePromotionsWorkflow", + "path": "/references/medusa-workflows/deletePromotionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateCampaignsWorkflow", + "path": "/references/medusa-workflows/updateCampaignsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updatePromotionRulesWorkflow", + "path": "/references/medusa-workflows/updatePromotionRulesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updatePromotionsWorkflow", + "path": "/references/medusa-workflows/updatePromotionsWorkflow", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Steps", + "autogenerate_tags": "step+promotion", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "getActionsToComputeFromPromotionsStep", + "path": "/references/medusa-workflows/steps/getActionsToComputeFromPromotionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "getPromotionCodesToApply", + "path": "/references/medusa-workflows/steps/getPromotionCodesToApply", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "prepareAdjustmentsFromPromotionActionsStep", + "path": "/references/medusa-workflows/steps/prepareAdjustmentsFromPromotionActionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateCartPromotionsStep", + "path": "/references/medusa-workflows/steps/updateCartPromotionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "addCampaignPromotionsStep", + "path": "/references/medusa-workflows/steps/addCampaignPromotionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "addRulesToPromotionsStep", + "path": "/references/medusa-workflows/steps/addRulesToPromotionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createCampaignsStep", + "path": "/references/medusa-workflows/steps/createCampaignsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createPromotionsStep", + "path": "/references/medusa-workflows/steps/createPromotionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteCampaignsStep", + "path": "/references/medusa-workflows/steps/deleteCampaignsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deletePromotionsStep", + "path": "/references/medusa-workflows/steps/deletePromotionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "removeCampaignPromotionsStep", + "path": "/references/medusa-workflows/steps/removeCampaignPromotionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "removeRulesFromPromotionsStep", + "path": "/references/medusa-workflows/steps/removeRulesFromPromotionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateCampaignsStep", + "path": "/references/medusa-workflows/steps/updateCampaignsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updatePromotionRulesStep", + "path": "/references/medusa-workflows/steps/updatePromotionRulesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updatePromotionsStep", + "path": "/references/medusa-workflows/steps/updatePromotionsStep", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", "title": "References", + "initialOpen": false, "children": [ { "loaded": true, diff --git a/www/apps/resources/sidebars/promotion.mjs b/www/apps/resources/sidebars/promotion.mjs index 9072b55202cfc..d7877353cf503 100644 --- a/www/apps/resources/sidebars/promotion.mjs +++ b/www/apps/resources/sidebars/promotion.mjs @@ -11,18 +11,12 @@ export const promotionSidebar = [ title: "Overview", }, { - type: "link", - path: "/commerce-modules/promotion/examples", - title: "Examples", - }, - { - type: "link", - path: "/commerce-modules/promotion/extend", - title: "Extend Module", + type: "separator", }, { - type: "sub-category", + type: "category", title: "Concepts", + initialOpen: false, children: [ { type: "link", @@ -52,8 +46,58 @@ export const promotionSidebar = [ ], }, { - type: "sub-category", + type: "category", + title: "Server Guides", + autogenerate_tags: "server+promotion", + initialOpen: false, + autogenerate_as_ref: true, + children: [ + { + type: "link", + path: "/commerce-modules/promotion/extend", + title: "Extend Module", + }, + ], + }, + { + type: "category", + title: "Storefront Guides", + autogenerate_tags: "storefront+promotion", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Admin Guides", + autogenerate_tags: "admin+promotion", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "User Guides", + autogenerate_tags: "userGuides+promotion", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Workflows", + autogenerate_tags: "workflow+promotion", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Steps", + autogenerate_tags: "step+promotion", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", title: "References", + initialOpen: false, children: [ { type: "link", diff --git a/www/packages/tags/src/tags/index.ts b/www/packages/tags/src/tags/index.ts index 03368a0de7535..88301cbfe3f11 100644 --- a/www/packages/tags/src/tags/index.ts +++ b/www/packages/tags/src/tags/index.ts @@ -1,32 +1,32 @@ export * from "./product.js" +export * from "./pricing.js" export * from "./storefront.js" -export * from "./tax.js" export * from "./cart.js" -export * from "./order.js" -export * from "./payment.js" +export * from "./query.js" export * from "./stripe.js" -export * from "./fulfillment.js" -export * from "./product-category.js" +export * from "./payment.js" +export * from "./tax.js" export * from "./auth.js" +export * from "./product-category.js" +export * from "./order.js" +export * from "./server.js" +export * from "./publishable-api-key.js" +export * from "./api-key.js" +export * from "./region.js" export * from "./customer.js" export * from "./product-collection.js" -export * from "./api-key.js" export * from "./inventory.js" -export * from "./publishable-api-key.js" -export * from "./region.js" +export * from "./fulfillment.js" +export * from "./remote-query.js" export * from "./step.js" -export * from "./server.js" -export * from "./query.js" -export * from "./remote-link.js" -export * from "./pricing.js" -export * from "./sales-channel.js" export * from "./workflow.js" -export * from "./remote-query.js" +export * from "./remote-link.js" export * from "./event-bus.js" -export * from "./store.js" -export * from "./file.js" -export * from "./stock-location.js" -export * from "./locking.js" export * from "./logger.js" +export * from "./sales-channel.js" export * from "./user.js" +export * from "./stock-location.js" +export * from "./file.js" +export * from "./locking.js" export * from "./promotion.js" +export * from "./store.js" From 9987398cecc4961ddae4723ffa1ec15e158abbc5 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Wed, 25 Dec 2024 17:48:39 +0200 Subject: [PATCH 15/21] revise region module --- .../app/commerce-modules/api-key/page.mdx | 2 +- .../app/commerce-modules/auth/page.mdx | 2 +- .../app/commerce-modules/cart/page.mdx | 4 +- .../app/commerce-modules/currency/page.mdx | 4 +- .../app/commerce-modules/customer/page.mdx | 4 +- .../app/commerce-modules/fulfillment/page.mdx | 4 +- .../app/commerce-modules/inventory/page.mdx | 4 +- .../app/commerce-modules/order/page.mdx | 4 +- .../app/commerce-modules/payment/page.mdx | 4 +- .../app/commerce-modules/pricing/page.mdx | 4 +- .../app/commerce-modules/product/page.mdx | 4 +- .../app/commerce-modules/promotion/page.mdx | 4 +- .../commerce-modules/region/examples/page.mdx | 256 ------------------ .../app/commerce-modules/region/page.mdx | 224 ++++++++------- www/apps/resources/generated/edit-dates.mjs | 27 +- www/apps/resources/generated/files-map.mjs | 4 - www/apps/resources/generated/sidebar.mjs | 206 +++++++++++++- www/apps/resources/sidebars/region.mjs | 52 +++- www/packages/tags/src/tags/index.ts | 36 +-- 19 files changed, 424 insertions(+), 425 deletions(-) delete mode 100644 www/apps/resources/app/commerce-modules/region/examples/page.mdx diff --git a/www/apps/resources/app/commerce-modules/api-key/page.mdx b/www/apps/resources/app/commerce-modules/api-key/page.mdx index dc6151309a565..375ec2dbd5766 100644 --- a/www/apps/resources/app/commerce-modules/api-key/page.mdx +++ b/www/apps/resources/app/commerce-modules/api-key/page.mdx @@ -139,7 +139,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or const { result } = await createApiKeyWorkflow(container) .run() - console.log(result.message) + console.log(result) } export const config = { diff --git a/www/apps/resources/app/commerce-modules/auth/page.mdx b/www/apps/resources/app/commerce-modules/auth/page.mdx index eb8c05b5b535c..44ae30923e4cb 100644 --- a/www/apps/resources/app/commerce-modules/auth/page.mdx +++ b/www/apps/resources/app/commerce-modules/auth/page.mdx @@ -25,7 +25,7 @@ Learn more about why modules are isolated in [this documentation](!docs!/learn/f --- -## How to Use Auth Module's Service +## How to Use the Auth Module In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. diff --git a/www/apps/resources/app/commerce-modules/cart/page.mdx b/www/apps/resources/app/commerce-modules/cart/page.mdx index 82a66f2d038e3..190e3e638fe68 100644 --- a/www/apps/resources/app/commerce-modules/cart/page.mdx +++ b/www/apps/resources/app/commerce-modules/cart/page.mdx @@ -25,7 +25,7 @@ Learn more about why modules are isolated in [this documentation](!docs!/learn/f --- -## How to Use Cart Module's Service +## How to Use the Cart Module In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. @@ -148,7 +148,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or const { result } = await createCartWorkflow(container) .run() - console.log(result.message) + console.log(result) } export const config = { diff --git a/www/apps/resources/app/commerce-modules/currency/page.mdx b/www/apps/resources/app/commerce-modules/currency/page.mdx index 17dad70a70fbf..f2f0d856ac317 100644 --- a/www/apps/resources/app/commerce-modules/currency/page.mdx +++ b/www/apps/resources/app/commerce-modules/currency/page.mdx @@ -23,7 +23,7 @@ Learn more about why modules are isolated in [this documentation](!docs!/learn/f --- -## How to Use Currency Module's Service +## How to Use the Currency Module In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. @@ -147,7 +147,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or price: 10 }) - console.log(result.message) + console.log(result) } export const config = { diff --git a/www/apps/resources/app/commerce-modules/customer/page.mdx b/www/apps/resources/app/commerce-modules/customer/page.mdx index 1efa6f76f8e91..08df4dd840110 100644 --- a/www/apps/resources/app/commerce-modules/customer/page.mdx +++ b/www/apps/resources/app/commerce-modules/customer/page.mdx @@ -23,7 +23,7 @@ Learn more about why modules are isolated in [this documentation](!docs!/learn/f --- -## How to Use Customer Module's Service +## How to Use the Customer Module In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. @@ -137,7 +137,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or const { result } = await createCustomerWorkflow(container) .run() - console.log(result.message) + console.log(result) } export const config = { diff --git a/www/apps/resources/app/commerce-modules/fulfillment/page.mdx b/www/apps/resources/app/commerce-modules/fulfillment/page.mdx index f84d19bf998fa..52f4c83aba68b 100644 --- a/www/apps/resources/app/commerce-modules/fulfillment/page.mdx +++ b/www/apps/resources/app/commerce-modules/fulfillment/page.mdx @@ -25,7 +25,7 @@ Learn more about why modules are isolated in [this documentation](!docs!/learn/f --- -## How to Use Fulfillment Module's Service +## How to Use the Fulfillment Module In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. @@ -153,7 +153,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or const { result } = await createFulfillmentWorkflow(container) .run() - console.log(result.message) + console.log(result) } export const config = { diff --git a/www/apps/resources/app/commerce-modules/inventory/page.mdx b/www/apps/resources/app/commerce-modules/inventory/page.mdx index 169c4737c59b1..6c43a09c8a4f2 100644 --- a/www/apps/resources/app/commerce-modules/inventory/page.mdx +++ b/www/apps/resources/app/commerce-modules/inventory/page.mdx @@ -25,7 +25,7 @@ Learn more about why modules are isolated in [this documentation](!docs!/learn/f --- -## How to Use Inventory Module's Service +## How to Use the Inventory Module In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. @@ -139,7 +139,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or const { result } = await createInventoryItemWorkflow(container) .run() - console.log(result.message) + console.log(result) } export const config = { diff --git a/www/apps/resources/app/commerce-modules/order/page.mdx b/www/apps/resources/app/commerce-modules/order/page.mdx index 1ddf411f105c0..887ceb7ca8c7c 100644 --- a/www/apps/resources/app/commerce-modules/order/page.mdx +++ b/www/apps/resources/app/commerce-modules/order/page.mdx @@ -26,7 +26,7 @@ Learn more about why modules are isolated in [this documentation](!docs!/learn/f --- -## How to Use Order Module's Service +## How to Use the Order Module In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. @@ -152,7 +152,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or const { result } = await createDraftOrderWorkflow(container) .run() - console.log(result.message) + console.log(result) } export const config = { diff --git a/www/apps/resources/app/commerce-modules/payment/page.mdx b/www/apps/resources/app/commerce-modules/payment/page.mdx index 4361846265306..9b9dfdee88302 100644 --- a/www/apps/resources/app/commerce-modules/payment/page.mdx +++ b/www/apps/resources/app/commerce-modules/payment/page.mdx @@ -25,7 +25,7 @@ Learn more about why modules are isolated in [this documentation](!docs!/learn/f --- -## How to Use Payment Module's Service +## How to Use the Payment Module In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. @@ -139,7 +139,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or const { result } = await createPaymentCollectionWorkflow(container) .run() - console.log(result.message) + console.log(result) } export const config = { diff --git a/www/apps/resources/app/commerce-modules/pricing/page.mdx b/www/apps/resources/app/commerce-modules/pricing/page.mdx index 6f2bd434ddf9e..df558298493e4 100644 --- a/www/apps/resources/app/commerce-modules/pricing/page.mdx +++ b/www/apps/resources/app/commerce-modules/pricing/page.mdx @@ -26,7 +26,7 @@ Learn more about why modules are isolated in [this documentation](!docs!/learn/f --- -## How to Use Pricing Module's Service +## How to Use the Pricing Module In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. @@ -150,7 +150,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or const { result } = await createPriceSetWorkflow(container) .run() - console.log(result.message) + console.log(result) } export const config = { diff --git a/www/apps/resources/app/commerce-modules/product/page.mdx b/www/apps/resources/app/commerce-modules/product/page.mdx index 084f5d3d0d8c9..1753998dc7f19 100644 --- a/www/apps/resources/app/commerce-modules/product/page.mdx +++ b/www/apps/resources/app/commerce-modules/product/page.mdx @@ -23,7 +23,7 @@ Learn more about why modules are isolated in [this documentation](!docs!/learn/f --- -## How to Use Product Module's Service +## How to Use the Product Module In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. @@ -149,7 +149,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or const { result } = await createProductWorkflow(container) .run() - console.log(result.message) + console.log(result) } export const config = { diff --git a/www/apps/resources/app/commerce-modules/promotion/page.mdx b/www/apps/resources/app/commerce-modules/promotion/page.mdx index 67aa457e79454..296116ca9734e 100644 --- a/www/apps/resources/app/commerce-modules/promotion/page.mdx +++ b/www/apps/resources/app/commerce-modules/promotion/page.mdx @@ -25,7 +25,7 @@ Learn more about why modules are isolated in [this documentation](!docs!/learn/f --- -## How to Use the Promotion Module's Service +## How to Use the Promotion Module In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. @@ -144,7 +144,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or const { result } = await createPromotionWorkflow(container) .run() - console.log(result.message) + console.log(result) } export const config = { diff --git a/www/apps/resources/app/commerce-modules/region/examples/page.mdx b/www/apps/resources/app/commerce-modules/region/examples/page.mdx deleted file mode 100644 index 09b9d6b055057..0000000000000 --- a/www/apps/resources/app/commerce-modules/region/examples/page.mdx +++ /dev/null @@ -1,256 +0,0 @@ -import { CodeTabs, CodeTab } from "docs-ui" - -export const metadata = { - title: `Examples of the Region Module`, -} - -# {metadata.title} - -In this guide, you’ll find common examples of how you can use the Region Module in your application. - - - -You should only use the Region Module's main service when implementing complex customizations. For common cases, check out [available workflows instead](../../../medusa-workflows-reference/page.mdx). - - - -## Create a Region - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const regionModuleService = req.scope.resolve( - Modules.REGION - ) - - const region = await regionModuleService.createRegions({ - name: "Europe", - currency_code: "eur", - }) - - res.json({ - region, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeRegionModule } from "@medusajs/medusa/region" - -export async function POST(request: Request) { - const regionModuleService = await initializeRegionModule() - - const region = await regionModuleService.createRegions({ - name: "Europe", - currency_code: "eur", - }) - - res.json({ - region, - }) -} -``` - - - - ---- - -## List Regions - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const regionModuleService = req.scope.resolve( - Modules.REGION - ) - - res.json({ - regions: await regionModuleService.listRegions(), - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeRegionModule } from "@medusajs/medusa/region" - -export async function GET(request: Request) { - const regionModuleService = await initializeRegionModule() - - return NextResponse.json({ - regions: await regionModuleService.listRegions(), - }) -} -``` - - - - ---- - -## Retrieve a Region by its ID - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const regionModuleService = req.scope.resolve( - Modules.REGION - ) - - const region = await regionModuleService.retrieveRegion("reg_123") - - res.json({ region }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeRegionModule } from "@medusajs/medusa/region" - -export async function GET(request: Request) { - const regionModuleService = await initializeRegionModule() - - const region = await regionModuleService.retrieveRegion("reg_123") - - return NextResponse.json({ region }) -} -``` - - - - ---- - -## Update a Region - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const regionModuleService = req.scope.resolve( - Modules.REGION - ) - - const region = await regionModuleService.updateRegions("reg_123", { - automatic_taxes: false, - }) - - res.json({ region }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeRegionModule } from "@medusajs/medusa/region" - -export async function POST(request: Request) { - const regionModuleService = await initializeRegionModule() - - const region = await regionModuleService.updateRegions("reg_123", { - automatic_taxes: false, - }) - - return NextResponse.json({ region }) -} -``` - - - - ---- - -## Delete a Region - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function DELETE( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const regionModuleService = req.scope.resolve( - Modules.REGION - ) - - await regionModuleService.deleteRegions("reg_123") - - res.status(200) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeRegionModule } from "@medusajs/medusa/region" - -export async function DELETE(request: Request) { - const regionModuleService = await initializeRegionModule() - - await regionModuleService.deleteRegions("reg_123") -} -``` - - - - ---- - -## More Examples - -The [Region Module's main service reference](/references/region) provides a reference to all the methods available for use with examples for each. diff --git a/www/apps/resources/app/commerce-modules/region/page.mdx b/www/apps/resources/app/commerce-modules/region/page.mdx index 9c6ebe902b17f..475ab3d19abf1 100644 --- a/www/apps/resources/app/commerce-modules/region/page.mdx +++ b/www/apps/resources/app/commerce-modules/region/page.mdx @@ -6,125 +6,153 @@ export const metadata = { # {metadata.title} -The Region Module provides region-related features in your Medusa and Node.js applications. +In this section of the documentation, you will find resources to learn more about the Region Module and how to use it in your application. -## How to Use Region Module's Service - -You can use the Region Module's main service by resolving from the Medusa container the resource `Modules.REGION`. - -For example: +Medusa has region related features available out-of-the-box through the Region Module. A [module](!docs!/learn/fundamentals/modules) is a standalone package that provides features for a single domain. Each of Medusa's commerce features are placed in commerce modules, such as this Region Module. - - + -```ts title="src/workflows/hello-world/step1.ts" -import { createStep } from "@medusajs/framework/workflows-sdk" -import { Modules } from "@medusajs/framework/utils" +Learn more about why modules are isolated in [this documentation](!docs!/learn/fundamentals/modules/isolation). -const step1 = createStep("step-1", async (_, { container }) => { - const regionModuleService = container.resolve( - Modules.REGION - ) + - const regions = await regionModuleService.listRegions() -}) -``` - - - - -```ts title="src/api/store/custom/route.ts" -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const regionModuleService = req.scope.resolve( - Modules.REGION - ) - - res.json({ - regions: await regionModuleService.listRegions(), - }) -} -``` +--- - - +## Region Features -```ts title="src/subscribers/custom-handler.ts" -import { SubscriberArgs } from "@medusajs/framework" -import { Modules } from "@medusajs/framework/utils" +- [Region Management](/references/region/models/Region): Manage regions in your store. You can create regions with different currencies and settings. +- [Multi-Currency Support](/references/region/models/Region): Each region has a currency. You can support multiple currencies in your store by creating multiple regions. +- [Different Settings Per Region](/references/region/models/Region): Each region has its own settings, such as what countries belong to a region or its tax settings. -export default async function subscriberHandler({ container }: SubscriberArgs) { - const regionModuleService = container.resolve( - Modules.REGION - ) +--- - const regions = await regionModuleService.listRegions() -} -``` +## How to Use Region Module's Service - - +In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. ---- +You can build custom workflows and steps. You can also re-use Medusa's workflows and steps, which are provided by the `@medusajs/medusa/core-flows` package. -## What is a Region? +For example: -A region represents the area you sell products in. Each region can cover multiple countries, but uses a single currency. +export const highlights = [ + ["12", "Modules.REGION", "Resolve the module in a step."] +] + +```ts title="src/workflows/create-region.ts" highlights={highlights} +import { + createWorkflow, + WorkflowResponse, + createStep, + StepResponse, +} from "@medusajs/framework/workflows-sdk" +import { Modules } from "@medusajs/framework/utils" ---- +const createRegionStep = createStep( + "create-region", + async ({}, { container }) => { + const regionModuleService = container.resolve(Modules.REGION) -## Features + const region = await regionModuleService.createRegions({ + name: "Europe", + currency_code: "eur", + }) -### Region Management + return new StepResponse({ region }, region.id) + }, + async (regionId, { container }) => { + const regionModuleService = container.resolve(Modules.REGION) + + await regionModuleService.deleteRegions([regionId]) + } +) + +export const createRegionWorkflow = createWorkflow( + "create-region", + () => { + const { region } = createRegionStep() + + return new WorkflowResponse({ + region, + }) + } +) +``` -You can manage your regions to create, update, retrieve, or delete them. +You can then execute the workflow in your custom API routes, scheduled jobs, or subscribers: -```ts -const region = await regionModuleService.createRegions({ - name: "Europe", - currency_code: "eur", -}) -``` + + + + ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import type { + MedusaRequest, + MedusaResponse, + } from "@medusajs/framework/http" + import { createRegionWorkflow } from "../../workflows/create-region" + + export async function GET( + req: MedusaRequest, + res: MedusaResponse + ) { + const { result } = await createRegionWorkflow(req.scope) + .run() + + res.send(result) + } + ``` -### Multi-Currency Support + + + + ```ts title="src/subscribers/customer-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import { + type SubscriberConfig, + type SubscriberArgs, + } from "@medusajs/framework" + import { createRegionWorkflow } from "../workflows/create-region" + + export default async function handleCustomerCreate({ + event: { data }, + container, + }: SubscriberArgs<{ id: string }>) { + const { result } = await createRegionWorkflow(container) + .run() + + console.log(result) + } + + export const config: SubscriberConfig = { + event: "user.created", + } + ``` -As each region has a currency, you can support multiple currencies in your store by creating multiple regions. + + + + ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} + import { MedusaContainer } from "@medusajs/framework/types" + import { createRegionWorkflow } from "../workflows/create-region" + + export default async function myCustomJob( + container: MedusaContainer + ) { + const { result } = await createRegionWorkflow(container) + .run() + + console.log(result) + } + + export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, + }; + ``` -```ts -const regions = await regionModuleService.createRegions([ - { - name: "Europe", - currency_code: "eur", - }, - { - name: "United States of America", - currency_code: "usd", - }, -]) -``` + + -### Different Settings Per Region +Learn more about workflows in [this documentation](!docs!/learn/fundamentals/workflows). -Each region has its own settings, such as what countries belong to a region or its tax settings. Each region has different tax rates, payment providers, and more provided by other commerce modules. +--- -```ts -const regions = await regionModuleService.createRegions([ - { - name: "Europe", - currency_code: "eur", - countries: ["dk", "de", "fr", "it", "pt"], - automatic_taxes: true, - }, - { - name: "United States of America", - currency_code: "usd", - countries: ["us"], - payment_providers: ["stripe"], - }, -]) -``` + diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index b07db6b092675..c037aec738777 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -4,20 +4,20 @@ export const generatedEditDates = { "app/commerce-modules/auth/authentication-route/page.mdx": "2024-09-05T12:06:38.155Z", "app/commerce-modules/auth/examples/page.mdx": "2024-10-15T15:02:13.794Z", "app/commerce-modules/auth/module-options/page.mdx": "2024-10-15T12:52:08.930Z", - "app/commerce-modules/auth/page.mdx": "2024-12-25T15:34:06.324Z", + "app/commerce-modules/auth/page.mdx": "2024-12-25T15:40:37.154Z", "app/commerce-modules/cart/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/cart/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/cart/concepts/page.mdx": "2024-10-08T07:49:03.737Z", "app/commerce-modules/cart/promotions/page.mdx": "2024-10-08T07:54:31.120Z", "app/commerce-modules/cart/tax-lines/page.mdx": "2024-10-08T07:57:19.168Z", - "app/commerce-modules/cart/page.mdx": "2024-12-25T15:34:00.328Z", + "app/commerce-modules/cart/page.mdx": "2024-12-25T15:45:12.795Z", "app/commerce-modules/currency/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/currency/_events/page.mdx": "2024-07-03T19:27:13+03:00", - "app/commerce-modules/currency/page.mdx": "2024-12-25T15:34:34.474Z", + "app/commerce-modules/currency/page.mdx": "2024-12-25T15:45:12.796Z", "app/commerce-modules/customer/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/customer/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/customer/customer-accounts/page.mdx": "2024-10-08T12:20:44.769Z", - "app/commerce-modules/customer/page.mdx": "2024-12-25T15:34:45.522Z", + "app/commerce-modules/customer/page.mdx": "2024-12-25T15:45:12.796Z", "app/commerce-modules/fulfillment/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/fulfillment/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/fulfillment/concepts/page.mdx": "2024-06-19T13:02:16+00:00", @@ -25,12 +25,12 @@ export const generatedEditDates = { "app/commerce-modules/fulfillment/item-fulfillment/page.mdx": "2024-10-08T14:38:15.496Z", "app/commerce-modules/fulfillment/module-options/page.mdx": "2024-10-15T12:51:56.118Z", "app/commerce-modules/fulfillment/shipping-option/page.mdx": "2024-10-08T14:36:02.660Z", - "app/commerce-modules/fulfillment/page.mdx": "2024-12-25T15:34:57.942Z", + "app/commerce-modules/fulfillment/page.mdx": "2024-12-25T15:45:12.796Z", "app/commerce-modules/inventory/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/inventory/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/inventory/concepts/page.mdx": "2024-10-08T15:11:27.634Z", "app/commerce-modules/inventory/inventory-in-flows/page.mdx": "2024-10-08T15:14:07.327Z", - "app/commerce-modules/inventory/page.mdx": "2024-12-25T15:35:09.948Z", + "app/commerce-modules/inventory/page.mdx": "2024-12-25T15:45:12.796Z", "app/commerce-modules/order/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/order/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/order/claim/page.mdx": "2024-10-09T10:11:12.090Z", @@ -41,7 +41,7 @@ export const generatedEditDates = { "app/commerce-modules/order/return/page.mdx": "2024-10-09T10:19:40.731Z", "app/commerce-modules/order/tax-lines/page.mdx": "2024-10-09T10:22:49.335Z", "app/commerce-modules/order/transactions/page.mdx": "2024-10-09T10:23:36.485Z", - "app/commerce-modules/order/page.mdx": "2024-12-25T15:35:28.286Z", + "app/commerce-modules/order/page.mdx": "2024-12-25T15:45:12.800Z", "app/commerce-modules/payment/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/payment/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/payment/module-options/page.mdx": "2024-10-15T12:51:40.574Z", @@ -52,30 +52,29 @@ export const generatedEditDates = { "app/commerce-modules/payment/payment-provider/page.mdx": "2024-10-09T11:07:27.269Z", "app/commerce-modules/payment/payment-session/page.mdx": "2024-10-09T10:58:00.960Z", "app/commerce-modules/payment/webhook-events/page.mdx": "2024-11-19T11:45:02.167Z", - "app/commerce-modules/payment/page.mdx": "2024-12-25T15:35:50.188Z", + "app/commerce-modules/payment/page.mdx": "2024-12-25T15:45:12.801Z", "app/commerce-modules/pricing/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/pricing/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/pricing/concepts/page.mdx": "2024-10-09T13:37:25.678Z", "app/commerce-modules/pricing/price-calculation/page.mdx": "2024-10-09T13:43:14.038Z", "app/commerce-modules/pricing/price-rules/page.mdx": "2024-10-09T13:38:47.112Z", "app/commerce-modules/pricing/tax-inclusive-pricing/page.mdx": "2024-10-09T13:48:23.261Z", - "app/commerce-modules/pricing/page.mdx": "2024-12-25T15:36:08.572Z", + "app/commerce-modules/pricing/page.mdx": "2024-12-25T15:45:12.800Z", "app/commerce-modules/product/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/product/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/product/guides/price/page.mdx": "2024-12-25T15:10:37.730Z", "app/commerce-modules/product/guides/price-with-taxes/page.mdx": "2024-12-25T15:10:40.879Z", - "app/commerce-modules/product/page.mdx": "2024-12-25T15:36:22.150Z", + "app/commerce-modules/product/page.mdx": "2024-12-25T15:45:12.800Z", "app/commerce-modules/promotion/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/promotion/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/promotion/actions/page.mdx": "2024-10-09T14:49:01.645Z", "app/commerce-modules/promotion/application-method/page.mdx": "2024-06-26T07:55:59+00:00", "app/commerce-modules/promotion/campaign/page.mdx": "2024-05-29T11:08:06+00:00", "app/commerce-modules/promotion/concepts/page.mdx": "2024-10-09T14:50:50.255Z", - "app/commerce-modules/promotion/page.mdx": "2024-12-25T15:36:36.877Z", + "app/commerce-modules/promotion/page.mdx": "2024-12-25T15:45:12.800Z", "app/commerce-modules/region/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/region/_events/page.mdx": "2024-07-03T19:27:13+03:00", - "app/commerce-modules/region/examples/page.mdx": "2024-10-15T15:00:24.388Z", - "app/commerce-modules/region/page.mdx": "2024-12-09T14:48:34.729Z", + "app/commerce-modules/region/page.mdx": "2024-12-25T15:45:29.483Z", "app/commerce-modules/sales-channel/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/sales-channel/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/sales-channel/examples/page.mdx": "2024-10-15T15:00:33.322Z", @@ -201,7 +200,7 @@ export const generatedEditDates = { "app/commerce-modules/auth/auth-flows/page.mdx": "2024-09-05T08:50:11.671Z", "app/commerce-modules/auth/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/auth/auth-identity-and-actor-types/page.mdx": "2024-12-09T13:04:01.129Z", - "app/commerce-modules/api-key/page.mdx": "2024-12-25T15:34:22.481Z", + "app/commerce-modules/api-key/page.mdx": "2024-12-25T15:45:12.796Z", "app/commerce-modules/auth/create-actor-type/page.mdx": "2024-12-25T13:26:27.176Z", "app/architectural-modules/page.mdx": "2024-12-11T10:33:53.064Z", "app/architectural-modules/workflow-engine/redis/page.mdx": "2024-10-15T12:50:59.507Z", diff --git a/www/apps/resources/generated/files-map.mjs b/www/apps/resources/generated/files-map.mjs index 5dc9b7b1e64fe..d045c52c08bb5 100644 --- a/www/apps/resources/generated/files-map.mjs +++ b/www/apps/resources/generated/files-map.mjs @@ -495,10 +495,6 @@ export const filesMap = [ "filePath": "/www/apps/resources/app/commerce-modules/region/events/page.mdx", "pathname": "/commerce-modules/region/events" }, - { - "filePath": "/www/apps/resources/app/commerce-modules/region/examples/page.mdx", - "pathname": "/commerce-modules/region/examples" - }, { "filePath": "/www/apps/resources/app/commerce-modules/region/links-to-other-modules/page.mdx", "pathname": "/commerce-modules/region/links-to-other-modules" diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs index ae9f7ec38e1c7..826867f06740f 100644 --- a/www/apps/resources/generated/sidebar.mjs +++ b/www/apps/resources/generated/sidebar.mjs @@ -10850,18 +10850,14 @@ export const generatedSidebar = [ "children": [] }, { - "loaded": true, - "isPathHref": true, - "type": "link", - "path": "/commerce-modules/region/examples", - "title": "Examples", - "children": [] + "type": "separator" }, { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", "title": "Concepts", + "initialOpen": false, "children": [ { "loaded": true, @@ -10876,8 +10872,202 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", + "title": "Storefront Guides", + "autogenerate_tags": "storefront+region", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Region Context in Storefront", + "path": "/storefront-development/regions/context", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "List Regions in Storefront", + "path": "/storefront-development/regions/list", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Store and Retrieve Region", + "path": "/storefront-development/regions/store-retrieve-region", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Workflows", + "autogenerate_tags": "workflow+region", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createCartWorkflow", + "path": "/references/medusa-workflows/createCartWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "addOrderLineItemsWorkflow", + "path": "/references/medusa-workflows/addOrderLineItemsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createOrderWorkflow", + "path": "/references/medusa-workflows/createOrderWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderClaimAddNewItemWorkflow", + "path": "/references/medusa-workflows/orderClaimAddNewItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderEditAddNewItemWorkflow", + "path": "/references/medusa-workflows/orderEditAddNewItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderExchangeAddNewItemWorkflow", + "path": "/references/medusa-workflows/orderExchangeAddNewItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "exportProductsWorkflow", + "path": "/references/medusa-workflows/exportProductsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "importProductsWorkflow", + "path": "/references/medusa-workflows/importProductsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createRegionsWorkflow", + "path": "/references/medusa-workflows/createRegionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteRegionsWorkflow", + "path": "/references/medusa-workflows/deleteRegionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateRegionsWorkflow", + "path": "/references/medusa-workflows/updateRegionsWorkflow", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Steps", + "autogenerate_tags": "step+region", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "findOneOrAnyRegionStep", + "path": "/references/medusa-workflows/steps/findOneOrAnyRegionStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "generateProductCsvStep", + "path": "/references/medusa-workflows/steps/generateProductCsvStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "parseProductCsvStep", + "path": "/references/medusa-workflows/steps/parseProductCsvStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createRegionsStep", + "path": "/references/medusa-workflows/steps/createRegionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteRegionsStep", + "path": "/references/medusa-workflows/steps/deleteRegionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateRegionsStep", + "path": "/references/medusa-workflows/steps/updateRegionsStep", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", "title": "References", + "initialOpen": false, "children": [ { "loaded": true, diff --git a/www/apps/resources/sidebars/region.mjs b/www/apps/resources/sidebars/region.mjs index d8515c01cc061..0b9d93d94ee0a 100644 --- a/www/apps/resources/sidebars/region.mjs +++ b/www/apps/resources/sidebars/region.mjs @@ -11,13 +11,12 @@ export const regionSidebar = [ title: "Overview", }, { - type: "link", - path: "/commerce-modules/region/examples", - title: "Examples", + type: "separator", }, { - type: "sub-category", + type: "category", title: "Concepts", + initialOpen: false, children: [ { type: "link", @@ -27,8 +26,51 @@ export const regionSidebar = [ ], }, { - type: "sub-category", + type: "category", + title: "Server Guides", + autogenerate_tags: "server+region", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Storefront Guides", + autogenerate_tags: "storefront+region", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Admin Guides", + autogenerate_tags: "admin+region", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "User Guides", + autogenerate_tags: "userGuides+region", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Workflows", + autogenerate_tags: "workflow+region", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Steps", + autogenerate_tags: "step+region", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", title: "References", + initialOpen: false, children: [ { type: "link", diff --git a/www/packages/tags/src/tags/index.ts b/www/packages/tags/src/tags/index.ts index 88301cbfe3f11..1aa4ef94c36e9 100644 --- a/www/packages/tags/src/tags/index.ts +++ b/www/packages/tags/src/tags/index.ts @@ -1,32 +1,32 @@ export * from "./product.js" -export * from "./pricing.js" export * from "./storefront.js" -export * from "./cart.js" -export * from "./query.js" -export * from "./stripe.js" -export * from "./payment.js" export * from "./tax.js" -export * from "./auth.js" -export * from "./product-category.js" +export * from "./payment.js" +export * from "./cart.js" export * from "./order.js" +export * from "./stripe.js" +export * from "./pricing.js" export * from "./server.js" -export * from "./publishable-api-key.js" +export * from "./auth.js" +export * from "./fulfillment.js" +export * from "./query.js" +export * from "./customer.js" export * from "./api-key.js" +export * from "./publishable-api-key.js" export * from "./region.js" -export * from "./customer.js" +export * from "./step.js" +export * from "./remote-link.js" +export * from "./workflow.js" export * from "./product-collection.js" export * from "./inventory.js" -export * from "./fulfillment.js" +export * from "./product-category.js" export * from "./remote-query.js" -export * from "./step.js" -export * from "./workflow.js" -export * from "./remote-link.js" -export * from "./event-bus.js" -export * from "./logger.js" export * from "./sales-channel.js" -export * from "./user.js" +export * from "./store.js" +export * from "./event-bus.js" export * from "./stock-location.js" -export * from "./file.js" +export * from "./user.js" export * from "./locking.js" +export * from "./logger.js" +export * from "./file.js" export * from "./promotion.js" -export * from "./store.js" From c591ea462b67a74103e043369eb7482f8b727594 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Wed, 25 Dec 2024 18:01:05 +0200 Subject: [PATCH 16/21] revise sales channel module --- .../app/commerce-modules/api-key/page.mdx | 6 +- .../app/commerce-modules/cart/page.mdx | 6 +- .../app/commerce-modules/currency/page.mdx | 6 +- .../commerce-modules/customer/extend/page.mdx | 4 +- .../app/commerce-modules/customer/page.mdx | 6 +- .../app/commerce-modules/fulfillment/page.mdx | 6 +- .../app/commerce-modules/inventory/page.mdx | 6 +- .../app/commerce-modules/order/page.mdx | 6 +- .../app/commerce-modules/payment/page.mdx | 6 +- .../app/commerce-modules/pricing/page.mdx | 6 +- .../app/commerce-modules/product/page.mdx | 6 +- .../app/commerce-modules/promotion/page.mdx | 6 +- .../app/commerce-modules/region/page.mdx | 6 +- .../sales-channel/examples/page.mdx | 257 ------------------ .../commerce-modules/sales-channel/page.mdx | 214 ++++++++++----- .../publishable-api-keys/page.mdx | 1 + www/apps/resources/generated/edit-dates.mjs | 31 +-- www/apps/resources/generated/files-map.mjs | 4 - www/apps/resources/generated/sidebar.mjs | 214 ++++++++++++++- www/apps/resources/sidebars/sales-channel.mjs | 52 +++- www/packages/tags/src/tags/index.ts | 36 +-- www/packages/tags/src/tags/sales-channel.ts | 4 + 22 files changed, 468 insertions(+), 421 deletions(-) delete mode 100644 www/apps/resources/app/commerce-modules/sales-channel/examples/page.mdx diff --git a/www/apps/resources/app/commerce-modules/api-key/page.mdx b/www/apps/resources/app/commerce-modules/api-key/page.mdx index 375ec2dbd5766..6c13ea825fd4d 100644 --- a/www/apps/resources/app/commerce-modules/api-key/page.mdx +++ b/www/apps/resources/app/commerce-modules/api-key/page.mdx @@ -104,14 +104,14 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/subscribers/customer-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" import { type SubscriberConfig, type SubscriberArgs, } from "@medusajs/framework" import {createApiKeyWorkflow} from "../workflows/create-api-key" - export default async function handleCustomerCreate({ + export default async function handleUserCreated({ event: { data }, container, }: SubscriberArgs<{ id: string }>) { @@ -129,7 +129,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} + ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} import { MedusaContainer } from "@medusajs/framework/types" import {createApiKeyWorkflow} from "../workflows/create-api-key" diff --git a/www/apps/resources/app/commerce-modules/cart/page.mdx b/www/apps/resources/app/commerce-modules/cart/page.mdx index 190e3e638fe68..5ad6d042e35ed 100644 --- a/www/apps/resources/app/commerce-modules/cart/page.mdx +++ b/www/apps/resources/app/commerce-modules/cart/page.mdx @@ -113,14 +113,14 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/subscribers/customer-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" import { type SubscriberConfig, type SubscriberArgs, } from "@medusajs/framework" import { createCartWorkflow } from "../workflows/create-cart" - export default async function handleCustomerCreate({ + export default async function handleUserCreated({ event: { data }, container, }: SubscriberArgs<{ id: string }>) { @@ -138,7 +138,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} + ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} import { MedusaContainer } from "@medusajs/framework/types" import { createCartWorkflow } from "../workflows/create-cart" diff --git a/www/apps/resources/app/commerce-modules/currency/page.mdx b/www/apps/resources/app/commerce-modules/currency/page.mdx index f2f0d856ac317..05bc4845d69fa 100644 --- a/www/apps/resources/app/commerce-modules/currency/page.mdx +++ b/www/apps/resources/app/commerce-modules/currency/page.mdx @@ -108,14 +108,14 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/subscribers/customer-created.ts" highlights={[["11"], ["12"], ["13"], ["14"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"], ["13"], ["14"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" import { type SubscriberConfig, type SubscriberArgs, } from "@medusajs/framework" import {retrievePriceWithCurrency} from "../workflows/retrieve-price-with-currency" - export default async function handleCustomerCreate({ + export default async function handleUserCreated({ event: { data }, container, }: SubscriberArgs<{ id: string }>) { @@ -135,7 +135,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"], ["9"], ["10"]]} + ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"], ["9"], ["10"]]} import { MedusaContainer } from "@medusajs/framework/types" import {retrievePriceWithCurrency} from "../workflows/retrieve-price-with-currency" diff --git a/www/apps/resources/app/commerce-modules/customer/extend/page.mdx b/www/apps/resources/app/commerce-modules/customer/extend/page.mdx index a511077780cd7..74298d409777c 100644 --- a/www/apps/resources/app/commerce-modules/customer/extend/page.mdx +++ b/www/apps/resources/app/commerce-modules/customer/extend/page.mdx @@ -276,9 +276,9 @@ You'll next execute the workflow in the hook handler. You can now consume the `customersCreated` hook, which is executed in the `createCustomersWorkflow` after the customer is created. -To consume the hook, create the file `src/workflow/hooks/customer-created.ts` with the following content: +To consume the hook, create the file `src/workflow/hooks/user-created.ts` with the following content: -```ts title="src/workflow/hooks/customer-created.ts" collapsibleLines="1-6" expandButtonLabel="Show Imports" +```ts title="src/workflow/hooks/user-created.ts" collapsibleLines="1-6" expandButtonLabel="Show Imports" import { createCustomersWorkflow } from "@medusajs/medusa/core-flows" import { createCustomFromCustomerWorkflow, diff --git a/www/apps/resources/app/commerce-modules/customer/page.mdx b/www/apps/resources/app/commerce-modules/customer/page.mdx index 08df4dd840110..7bebcd43b1c7b 100644 --- a/www/apps/resources/app/commerce-modules/customer/page.mdx +++ b/www/apps/resources/app/commerce-modules/customer/page.mdx @@ -102,14 +102,14 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/subscribers/customer-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" import { type SubscriberConfig, type SubscriberArgs, } from "@medusajs/framework" import {createCustomerWorkflow} from "../workflows/create-customer" - export default async function handleCustomerCreate({ + export default async function handleUserCreated({ event: { data }, container, }: SubscriberArgs<{ id: string }>) { @@ -127,7 +127,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} + ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} import { MedusaContainer } from "@medusajs/framework/types" import {createCustomerWorkflow} from "../workflows/create-customer" diff --git a/www/apps/resources/app/commerce-modules/fulfillment/page.mdx b/www/apps/resources/app/commerce-modules/fulfillment/page.mdx index 52f4c83aba68b..4fd2282e24e00 100644 --- a/www/apps/resources/app/commerce-modules/fulfillment/page.mdx +++ b/www/apps/resources/app/commerce-modules/fulfillment/page.mdx @@ -118,14 +118,14 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/subscribers/customer-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" import { type SubscriberConfig, type SubscriberArgs, } from "@medusajs/framework" import {createFulfillmentWorkflow} from "../workflows/create-fuilfillment" - export default async function handleCustomerCreate({ + export default async function handleUserCreated({ event: { data }, container, }: SubscriberArgs<{ id: string }>) { @@ -143,7 +143,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} + ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} import { MedusaContainer } from "@medusajs/framework/types" import {createFulfillmentWorkflow} from "../workflows/create-fuilfillment" diff --git a/www/apps/resources/app/commerce-modules/inventory/page.mdx b/www/apps/resources/app/commerce-modules/inventory/page.mdx index 6c43a09c8a4f2..56838a830d604 100644 --- a/www/apps/resources/app/commerce-modules/inventory/page.mdx +++ b/www/apps/resources/app/commerce-modules/inventory/page.mdx @@ -104,14 +104,14 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/subscribers/customer-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" import { type SubscriberConfig, type SubscriberArgs, } from "@medusajs/framework" import {createInventoryItemWorkflow} from "../workflows/create-inventory-item" - export default async function handleCustomerCreate({ + export default async function handleUserCreated({ event: { data }, container, }: SubscriberArgs<{ id: string }>) { @@ -129,7 +129,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} + ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} import { MedusaContainer } from "@medusajs/framework/types" import {createInventoryItemWorkflow} from "../workflows/create-inventory-item" diff --git a/www/apps/resources/app/commerce-modules/order/page.mdx b/www/apps/resources/app/commerce-modules/order/page.mdx index 887ceb7ca8c7c..2b5b8b1ef0bd4 100644 --- a/www/apps/resources/app/commerce-modules/order/page.mdx +++ b/www/apps/resources/app/commerce-modules/order/page.mdx @@ -117,14 +117,14 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/subscribers/customer-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" import { type SubscriberConfig, type SubscriberArgs, } from "@medusajs/framework" import {createDraftOrderWorkflow} from "../workflows/create-draft-order" - export default async function handleCustomerCreate({ + export default async function handleUserCreated({ event: { data }, container, }: SubscriberArgs<{ id: string }>) { @@ -142,7 +142,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} + ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} import { MedusaContainer } from "@medusajs/framework/types" import {createDraftOrderWorkflow} from "../workflows/create-draft-order" diff --git a/www/apps/resources/app/commerce-modules/payment/page.mdx b/www/apps/resources/app/commerce-modules/payment/page.mdx index 9b9dfdee88302..9e530f964c06f 100644 --- a/www/apps/resources/app/commerce-modules/payment/page.mdx +++ b/www/apps/resources/app/commerce-modules/payment/page.mdx @@ -104,14 +104,14 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/subscribers/customer-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" import { type SubscriberConfig, type SubscriberArgs, } from "@medusajs/framework" import {createPaymentCollectionWorkflow} from "../workflows/create-payment-collection" - export default async function handleCustomerCreate({ + export default async function handleUserCreated({ event: { data }, container, }: SubscriberArgs<{ id: string }>) { @@ -129,7 +129,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} + ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} import { MedusaContainer } from "@medusajs/framework/types" import {createPaymentCollectionWorkflow} from "../workflows/create-payment-collection" diff --git a/www/apps/resources/app/commerce-modules/pricing/page.mdx b/www/apps/resources/app/commerce-modules/pricing/page.mdx index df558298493e4..cb65399da1a1f 100644 --- a/www/apps/resources/app/commerce-modules/pricing/page.mdx +++ b/www/apps/resources/app/commerce-modules/pricing/page.mdx @@ -115,14 +115,14 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/subscribers/customer-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" import { type SubscriberConfig, type SubscriberArgs, } from "@medusajs/framework" import {createPriceSetWorkflow} from "../workflows/create-price-set" - export default async function handleCustomerCreate({ + export default async function handleUserCreated({ event: { data }, container, }: SubscriberArgs<{ id: string }>) { @@ -140,7 +140,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} + ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} import { MedusaContainer } from "@medusajs/framework/types" import {createPriceSetWorkflow} from "../workflows/create-price-set" diff --git a/www/apps/resources/app/commerce-modules/product/page.mdx b/www/apps/resources/app/commerce-modules/product/page.mdx index 1753998dc7f19..64d5cf7aee2c8 100644 --- a/www/apps/resources/app/commerce-modules/product/page.mdx +++ b/www/apps/resources/app/commerce-modules/product/page.mdx @@ -114,14 +114,14 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/subscribers/customer-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" import { type SubscriberConfig, type SubscriberArgs, } from "@medusajs/framework" import {createProductWorkflow} from "../workflows/create-product" - export default async function handleCustomerCreate({ + export default async function handleUserCreated({ event: { data }, container, }: SubscriberArgs<{ id: string }>) { @@ -139,7 +139,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} + ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} import { MedusaContainer } from "@medusajs/framework/types" import {createProductWorkflow} from "../workflows/create-product" diff --git a/www/apps/resources/app/commerce-modules/promotion/page.mdx b/www/apps/resources/app/commerce-modules/promotion/page.mdx index 296116ca9734e..4d3cadc6e95f1 100644 --- a/www/apps/resources/app/commerce-modules/promotion/page.mdx +++ b/www/apps/resources/app/commerce-modules/promotion/page.mdx @@ -109,14 +109,14 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/subscribers/customer-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" import { type SubscriberConfig, type SubscriberArgs, } from "@medusajs/framework" import { createPromotionWorkflow } from "../workflows/create-cart" - export default async function handleCustomerCreate({ + export default async function handleUserCreated({ event: { data }, container, }: SubscriberArgs<{ id: string }>) { @@ -134,7 +134,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} + ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} import { MedusaContainer } from "@medusajs/framework/types" import { createPromotionWorkflow } from "../workflows/create-cart" diff --git a/www/apps/resources/app/commerce-modules/region/page.mdx b/www/apps/resources/app/commerce-modules/region/page.mdx index 475ab3d19abf1..d2708c902bac5 100644 --- a/www/apps/resources/app/commerce-modules/region/page.mdx +++ b/www/apps/resources/app/commerce-modules/region/page.mdx @@ -104,14 +104,14 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/subscribers/customer-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" import { type SubscriberConfig, type SubscriberArgs, } from "@medusajs/framework" import { createRegionWorkflow } from "../workflows/create-region" - export default async function handleCustomerCreate({ + export default async function handleUserCreated({ event: { data }, container, }: SubscriberArgs<{ id: string }>) { @@ -129,7 +129,7 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"]]} + ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} import { MedusaContainer } from "@medusajs/framework/types" import { createRegionWorkflow } from "../workflows/create-region" diff --git a/www/apps/resources/app/commerce-modules/sales-channel/examples/page.mdx b/www/apps/resources/app/commerce-modules/sales-channel/examples/page.mdx deleted file mode 100644 index f32b492bcda07..0000000000000 --- a/www/apps/resources/app/commerce-modules/sales-channel/examples/page.mdx +++ /dev/null @@ -1,257 +0,0 @@ -import { CodeTabs, CodeTab } from "docs-ui" - -export const metadata = { - title: `Examples of the Sales Channel Module`, -} - -# {metadata.title} - -In this guide, you’ll find common examples of how you can use the Sales Channel Module in your application. - - - -You should only use the Sales Channel Module's main service when implementing complex customizations. For common cases, check out [available workflows instead](../../../medusa-workflows-reference/page.mdx). - - - -## Create a Sales Channel - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const salesChannelModuleService = - request.scope.resolve(Modules.SALES_CHANNEL) - - const salesChannel = await salesChannelModuleService.createSalesChannels({ - name: "B2B", - }) - - res.json({ - sales_channel: salesChannel, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeSalesChannelModule } from "@medusajs/medusa/sales-channel" - -export async function POST(request: Request) { - const salesChannelModuleService = await initializeSalesChannelModule() - - const salesChannel = await salesChannelModuleService.createSalesChannels({ - name: "B2B", - }) - - return NextResponse.json({ sales_channel: salesChannel }) -} -``` - - - - ---- - -## List Sales Channels - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const salesChannelModuleService = - request.scope.resolve(Modules.SALES_CHANNEL) - - res.json({ - sales_channels: salesChannelModuleService.listSalesChannels(), - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeSalesChannelModule } from "@medusajs/medusa/sales-channel" - -export async function GET(request: Request) { - const salesChannelModuleService = await initializeSalesChannelModule() - - const salesChannels = await salesChannelModuleService.listSalesChannels() - - return NextResponse.json({ sales_channels: salesChannels }) -} -``` - - - - ---- - -## Retrieve a Sales Channel by its ID - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const salesChannelModuleService = - request.scope.resolve(Modules.SALES_CHANNEL) - - const salesChannel = await salesChannelModuleService.retrieveSalesChannel( - "sc_123" - ) - - res.json({ - sales_channel: salesChannel, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeSalesChannelModule } from "@medusajs/medusa/sales-channel" - -export async function GET(request: Request) { - const salesChannelModuleService = await initializeSalesChannelModule() - - const salesChannel = await salesChannelModuleService.retrieveSalesChannel( - "sc_123" - ) - - return NextResponse.json({ sales_channel: salesChannel }) -} -``` - - - - ---- - -## Update a Sales Channel - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const salesChannelModuleService = - request.scope.resolve(Modules.SALES_CHANNEL) - - const salesChannel = await salesChannelModuleService.updateSalesChannels({ - id: "sc_123", - description: "Sales channel for B2B customers", - }) - - res.json({ - sales_channel: salesChannel, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeSalesChannelModule } from "@medusajs/medusa/sales-channel" - -export async function POST(request: Request) { - const salesChannelModuleService = await initializeSalesChannelModule() - - const salesChannel = await salesChannelModuleService.updateSalesChannels({ - id: "sc_123", - description: "Sales channel for B2B customers", - }) - - return NextResponse.json({ sales_channel: salesChannel }) -} -``` - - - - ---- - -## Delete a Sales Channel - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function DELETE( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const salesChannelModuleService = - request.scope.resolve(Modules.SALES_CHANNEL) - - await salesChannelModuleService.deleteSalesChannels("sc_123") - - res.status(200) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeSalesChannelModule } from "@medusajs/medusa/sales-channel" - -export async function DELETE(request: Request) { - const salesChannelModuleService = await initializeSalesChannelModule() - - await salesChannelModuleService.deleteSalesChannels("sc_123") -} -``` - - - - ---- - -## More Examples - -The [Sales Channel Module's main service reference](/references/sales-channel) provides a reference to all the methods available for use with examples for each. diff --git a/www/apps/resources/app/commerce-modules/sales-channel/page.mdx b/www/apps/resources/app/commerce-modules/sales-channel/page.mdx index ba84f12dff45a..25deebfa1185e 100644 --- a/www/apps/resources/app/commerce-modules/sales-channel/page.mdx +++ b/www/apps/resources/app/commerce-modules/sales-channel/page.mdx @@ -6,68 +6,15 @@ export const metadata = { # {metadata.title} -The Sales Channel Module provides sales-channel-related features in your Medusa and Node.js applications. +In this section of the documentation, you will find resources to learn more about the Sales Channel Module and how to use it in your application. -## How to Use Sales Channel Module's Service - -You can use the Sales Channel Module's main service by resolving from the Medusa container the resource `Modules.SALES_CHANNEL`. - -For example: - - - - -```ts title="src/workflows/hello-world/step1.ts" -import { createStep } from "@medusajs/framework/workflows-sdk" -import { Modules } from "@medusajs/framework/utils" - -const step1 = createStep("step-1", async (_, { container }) => { - const salesChannelModuleService = - container.resolve(Modules.SALES_CHANNEL) - - const salesChannels = await salesChannelModuleService.listSalesChannels() -}) -``` - - - - -```ts title="src/api/store/custom/route.ts" -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const salesChannelModuleService = - request.scope.resolve(Modules.SALES_CHANNEL) - - res.json({ - sales_channels: await salesChannelModuleService.listSalesChannels(), - }) -} -``` - - - +Medusa has sales channel related features available out-of-the-box through the Sales Channel Module. A [module](!docs!/learn/fundamentals/modules) is a standalone package that provides features for a single domain. Each of Medusa's commerce features are placed in commerce modules, such as this Sales Channel Module. -```ts title="src/subscribers/custom-handler.ts" -import { SubscriberArgs } from "@medusajs/framework" -import { Modules } from "@medusajs/framework/utils" + -export default async function subscriberHandler({ container }: SubscriberArgs) { - const salesChannelModuleService = - container.resolve(Modules.SALES_CHANNEL) +Learn more about why modules are isolated in [this documentation](!docs!/learn/fundamentals/modules/isolation). - const salesChannels = await salesChannelModuleService.listSalesChannels() -} -``` - - - - ---- + ## What's a Sales Channel? @@ -81,31 +28,148 @@ Some use case examples for using a sales channel: --- -## Features +## Sales Channel Features + +- [Sales Channel Management](/references/sales-channel/models/SalesChannel): Manage sales channels in your store. Each sales channel has different meta information such as name or description, allowing you to easily differentiate between sales channels. +- [Product Availability](./links-to-other-modules/page.mdx): Medusa uses the Product and Sales Channel modules to allow merchants to specify a product's availability per sales channel. +- [Cart and Order Scoping](./links-to-other-modules/page.mdx): Carts, available through the Cart Module, are scoped to a sales channel. Paired with the product availability feature, you benefit from more features like allowing only products available in sales channel in a cart. +- [Inventory Availability Per Sales Channel](./links-to-other-modules/page.mdx): Medusa links sales channels to stock locations, allowing you to retrieve available inventory of products based on the specified sales channel. + +--- + +## How to Use Sales Channel Module's Service -### Sales Channel Management +In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. -Manage sales channels in your store. Each sales channel has different meta information such as name or description, allowing you to easily differentiate between sales channels. +You can build custom workflows and steps. You can also re-use Medusa's workflows and steps, which are provided by the `@medusajs/medusa/core-flows` package. -```ts -const salesChannels = await salesChannelModuleService.createSalesChannels([ - { - name: "B2B", - }, - { - name: "Mobile App", +For example: + +export const highlights = [ + ["12", "Modules.SALES_CHANNEL", "Resolve the module in a step."] +] + +```ts title="src/workflows/create-sales-channel.ts" highlights={highlights} +import { + createWorkflow, + WorkflowResponse, + createStep, + StepResponse, +} from "@medusajs/framework/workflows-sdk" +import { Modules } from "@medusajs/framework/utils" + +const createSalesChannelStep = createStep( + "create-sales-channel", + async ({}, { container }) => { + const salesChannelModuleService = container.resolve(Modules.SALES_CHANNEL) + + const salesChannels = await salesChannelModuleService.createSalesChannels([ + { + name: "B2B", + }, + { + name: "Mobile App", + }, + ]) + + return new StepResponse({ salesChannels }, salesChannels.map(sc => sc.id)) }, -]) + async (salesChannelIds, { container }) => { + const salesChannelModuleService = container.resolve(Modules.SALES_CHANNEL) + + const salesChannels = await salesChannelModuleService.deleteSalesChannels( + salesChannelIds + ) + } +) + +export const createSalesChannelWorkflow = createWorkflow( + "create-sales-channel", + () => { + const { salesChannels } = createSalesChannelStep() + + return new WorkflowResponse({ + salesChannels, + }) + } +) ``` -### Product Availability +You can then execute the workflow in your custom API routes, scheduled jobs, or subscribers: -Medusa uses the Product and Sales Channel modules to allow merchants to specify a product's availability per sales channel. + + + + ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import type { + MedusaRequest, + MedusaResponse, + } from "@medusajs/framework/http" + import { createSalesChannelWorkflow } from "../../workflows/create-sales-channel" + + export async function GET( + req: MedusaRequest, + res: MedusaResponse + ) { + const { result } = await createSalesChannelWorkflow(req.scope) + .run() + + res.send(result) + } + ``` -For example, B2B customers viewing products only see products in the B2B sales channel. + + + + ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import { + type SubscriberConfig, + type SubscriberArgs, + } from "@medusajs/framework" + import { createSalesChannelWorkflow } from "../workflows/create-sales-channel" + + export default async function handleUserCreated({ + event: { data }, + container, + }: SubscriberArgs<{ id: string }>) { + const { result } = await createSalesChannelWorkflow(container) + .run() + + console.log(result) + } + + export const config: SubscriberConfig = { + event: "user.created", + } + ``` -### Cart and Order Scoping + + + + ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} + import { MedusaContainer } from "@medusajs/framework/types" + import { createSalesChannelWorkflow } from "../workflows/create-sales-channel" + + export default async function myCustomJob( + container: MedusaContainer + ) { + const { result } = await createSalesChannelWorkflow(container) + .run() + + console.log(result) + } + + export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, + }; + ``` -Carts, available through the Cart Module, are scoped to a sales channel. Paired with the product availability feature, you benefit from more features like allowing only products available in sales channel in a cart. + + + +Learn more about workflows in [this documentation](!docs!/learn/fundamentals/workflows). + +--- -Orders are also scoped to a sales channel due to the relation between the Sales Channel and Order modules. + \ No newline at end of file diff --git a/www/apps/resources/app/storefront-development/publishable-api-keys/page.mdx b/www/apps/resources/app/storefront-development/publishable-api-keys/page.mdx index 58085b425afce..38fe011c02fb7 100644 --- a/www/apps/resources/app/storefront-development/publishable-api-keys/page.mdx +++ b/www/apps/resources/app/storefront-development/publishable-api-keys/page.mdx @@ -3,6 +3,7 @@ tags: - publishable api key - api key - storefront + - sales channel --- export const metadata = { diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index c037aec738777..7e05cef868b84 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -10,14 +10,14 @@ export const generatedEditDates = { "app/commerce-modules/cart/concepts/page.mdx": "2024-10-08T07:49:03.737Z", "app/commerce-modules/cart/promotions/page.mdx": "2024-10-08T07:54:31.120Z", "app/commerce-modules/cart/tax-lines/page.mdx": "2024-10-08T07:57:19.168Z", - "app/commerce-modules/cart/page.mdx": "2024-12-25T15:45:12.795Z", + "app/commerce-modules/cart/page.mdx": "2024-12-25T15:55:02.850Z", "app/commerce-modules/currency/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/currency/_events/page.mdx": "2024-07-03T19:27:13+03:00", - "app/commerce-modules/currency/page.mdx": "2024-12-25T15:45:12.796Z", + "app/commerce-modules/currency/page.mdx": "2024-12-25T15:55:02.850Z", "app/commerce-modules/customer/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/customer/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/customer/customer-accounts/page.mdx": "2024-10-08T12:20:44.769Z", - "app/commerce-modules/customer/page.mdx": "2024-12-25T15:45:12.796Z", + "app/commerce-modules/customer/page.mdx": "2024-12-25T15:55:02.850Z", "app/commerce-modules/fulfillment/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/fulfillment/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/fulfillment/concepts/page.mdx": "2024-06-19T13:02:16+00:00", @@ -25,12 +25,12 @@ export const generatedEditDates = { "app/commerce-modules/fulfillment/item-fulfillment/page.mdx": "2024-10-08T14:38:15.496Z", "app/commerce-modules/fulfillment/module-options/page.mdx": "2024-10-15T12:51:56.118Z", "app/commerce-modules/fulfillment/shipping-option/page.mdx": "2024-10-08T14:36:02.660Z", - "app/commerce-modules/fulfillment/page.mdx": "2024-12-25T15:45:12.796Z", + "app/commerce-modules/fulfillment/page.mdx": "2024-12-25T15:55:02.850Z", "app/commerce-modules/inventory/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/inventory/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/inventory/concepts/page.mdx": "2024-10-08T15:11:27.634Z", "app/commerce-modules/inventory/inventory-in-flows/page.mdx": "2024-10-08T15:14:07.327Z", - "app/commerce-modules/inventory/page.mdx": "2024-12-25T15:45:12.796Z", + "app/commerce-modules/inventory/page.mdx": "2024-12-25T15:55:02.850Z", "app/commerce-modules/order/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/order/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/order/claim/page.mdx": "2024-10-09T10:11:12.090Z", @@ -41,7 +41,7 @@ export const generatedEditDates = { "app/commerce-modules/order/return/page.mdx": "2024-10-09T10:19:40.731Z", "app/commerce-modules/order/tax-lines/page.mdx": "2024-10-09T10:22:49.335Z", "app/commerce-modules/order/transactions/page.mdx": "2024-10-09T10:23:36.485Z", - "app/commerce-modules/order/page.mdx": "2024-12-25T15:45:12.800Z", + "app/commerce-modules/order/page.mdx": "2024-12-25T15:55:02.851Z", "app/commerce-modules/payment/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/payment/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/payment/module-options/page.mdx": "2024-10-15T12:51:40.574Z", @@ -52,34 +52,33 @@ export const generatedEditDates = { "app/commerce-modules/payment/payment-provider/page.mdx": "2024-10-09T11:07:27.269Z", "app/commerce-modules/payment/payment-session/page.mdx": "2024-10-09T10:58:00.960Z", "app/commerce-modules/payment/webhook-events/page.mdx": "2024-11-19T11:45:02.167Z", - "app/commerce-modules/payment/page.mdx": "2024-12-25T15:45:12.801Z", + "app/commerce-modules/payment/page.mdx": "2024-12-25T15:55:02.850Z", "app/commerce-modules/pricing/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/pricing/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/pricing/concepts/page.mdx": "2024-10-09T13:37:25.678Z", "app/commerce-modules/pricing/price-calculation/page.mdx": "2024-10-09T13:43:14.038Z", "app/commerce-modules/pricing/price-rules/page.mdx": "2024-10-09T13:38:47.112Z", "app/commerce-modules/pricing/tax-inclusive-pricing/page.mdx": "2024-10-09T13:48:23.261Z", - "app/commerce-modules/pricing/page.mdx": "2024-12-25T15:45:12.800Z", + "app/commerce-modules/pricing/page.mdx": "2024-12-25T15:55:02.851Z", "app/commerce-modules/product/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/product/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/product/guides/price/page.mdx": "2024-12-25T15:10:37.730Z", "app/commerce-modules/product/guides/price-with-taxes/page.mdx": "2024-12-25T15:10:40.879Z", - "app/commerce-modules/product/page.mdx": "2024-12-25T15:45:12.800Z", + "app/commerce-modules/product/page.mdx": "2024-12-25T15:55:02.850Z", "app/commerce-modules/promotion/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/promotion/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/promotion/actions/page.mdx": "2024-10-09T14:49:01.645Z", "app/commerce-modules/promotion/application-method/page.mdx": "2024-06-26T07:55:59+00:00", "app/commerce-modules/promotion/campaign/page.mdx": "2024-05-29T11:08:06+00:00", "app/commerce-modules/promotion/concepts/page.mdx": "2024-10-09T14:50:50.255Z", - "app/commerce-modules/promotion/page.mdx": "2024-12-25T15:45:12.800Z", + "app/commerce-modules/promotion/page.mdx": "2024-12-25T15:55:02.850Z", "app/commerce-modules/region/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/region/_events/page.mdx": "2024-07-03T19:27:13+03:00", - "app/commerce-modules/region/page.mdx": "2024-12-25T15:45:29.483Z", + "app/commerce-modules/region/page.mdx": "2024-12-25T15:55:02.851Z", "app/commerce-modules/sales-channel/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/sales-channel/_events/page.mdx": "2024-07-03T19:27:13+03:00", - "app/commerce-modules/sales-channel/examples/page.mdx": "2024-10-15T15:00:33.322Z", "app/commerce-modules/sales-channel/publishable-api-keys/page.mdx": "2024-10-15T14:21:38.353Z", - "app/commerce-modules/sales-channel/page.mdx": "2024-12-09T14:48:38.646Z", + "app/commerce-modules/sales-channel/page.mdx": "2024-12-25T15:55:17.802Z", "app/commerce-modules/stock-location/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/stock-location/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/stock-location/concepts/page.mdx": "2024-10-15T14:32:21.875Z", @@ -200,7 +199,7 @@ export const generatedEditDates = { "app/commerce-modules/auth/auth-flows/page.mdx": "2024-09-05T08:50:11.671Z", "app/commerce-modules/auth/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/auth/auth-identity-and-actor-types/page.mdx": "2024-12-09T13:04:01.129Z", - "app/commerce-modules/api-key/page.mdx": "2024-12-25T15:45:12.796Z", + "app/commerce-modules/api-key/page.mdx": "2024-12-25T15:55:02.846Z", "app/commerce-modules/auth/create-actor-type/page.mdx": "2024-12-25T13:26:27.176Z", "app/architectural-modules/page.mdx": "2024-12-11T10:33:53.064Z", "app/architectural-modules/workflow-engine/redis/page.mdx": "2024-10-15T12:50:59.507Z", @@ -976,7 +975,7 @@ export const generatedEditDates = { "references/order/IOrderModuleService/methods/order.IOrderModuleService.updateOrderChangeActions/page.mdx": "2024-12-23T12:30:30.337Z", "references/types/ModulesSdkTypes/types/types.ModulesSdkTypes.RemoteQueryFunction/page.mdx": "2024-12-23T12:30:29.466Z", "references/types/types.CommonTypes/page.mdx": "2024-11-25T17:49:25.351Z", - "app/storefront-development/publishable-api-keys/page.mdx": "2024-12-19T16:35:56.322Z", + "app/storefront-development/publishable-api-keys/page.mdx": "2024-12-25T16:00:18.474Z", "references/api_key/types/api_key.ExpandScalar/page.mdx": "2024-09-17T00:10:59.563Z", "references/api_key/types/api_key.FilterQuery/page.mdx": "2024-11-27T16:33:40.706Z", "references/api_key/types/api_key.FilterValue/page.mdx": "2024-09-17T00:10:59.571Z", @@ -2141,7 +2140,7 @@ export const generatedEditDates = { "app/commerce-modules/api-key/links-to-other-modules/page.mdx": "2024-12-24T14:36:06.109Z", "app/commerce-modules/cart/extend/page.mdx": "2024-12-25T12:48:59.149Z", "app/commerce-modules/cart/links-to-other-modules/page.mdx": "2024-12-24T14:46:49.847Z", - "app/commerce-modules/customer/extend/page.mdx": "2024-12-16T14:11:47.517Z", + "app/commerce-modules/customer/extend/page.mdx": "2024-12-25T15:54:37.789Z", "app/commerce-modules/fulfillment/links-to-other-modules/page.mdx": "2024-12-24T14:49:54.535Z", "app/commerce-modules/inventory/links-to-other-modules/page.mdx": "2024-12-24T14:50:25.574Z", "app/commerce-modules/pricing/links-to-other-modules/page.mdx": "2024-12-24T14:53:39.198Z", diff --git a/www/apps/resources/generated/files-map.mjs b/www/apps/resources/generated/files-map.mjs index d045c52c08bb5..2c8927722edfd 100644 --- a/www/apps/resources/generated/files-map.mjs +++ b/www/apps/resources/generated/files-map.mjs @@ -511,10 +511,6 @@ export const filesMap = [ "filePath": "/www/apps/resources/app/commerce-modules/sales-channel/events/page.mdx", "pathname": "/commerce-modules/sales-channel/events" }, - { - "filePath": "/www/apps/resources/app/commerce-modules/sales-channel/examples/page.mdx", - "pathname": "/commerce-modules/sales-channel/examples" - }, { "filePath": "/www/apps/resources/app/commerce-modules/sales-channel/links-to-other-modules/page.mdx", "pathname": "/commerce-modules/sales-channel/links-to-other-modules" diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs index 826867f06740f..d42af3b693732 100644 --- a/www/apps/resources/generated/sidebar.mjs +++ b/www/apps/resources/generated/sidebar.mjs @@ -11257,18 +11257,14 @@ export const generatedSidebar = [ "children": [] }, { - "loaded": true, - "isPathHref": true, - "type": "link", - "path": "/commerce-modules/sales-channel/examples", - "title": "Examples", - "children": [] + "type": "separator" }, { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", "title": "Concepts", + "initialOpen": false, "children": [ { "loaded": true, @@ -11291,8 +11287,210 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", + "title": "Storefront Guides", + "autogenerate_tags": "storefront+salesChannel", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Use a Publishable API Key in the Storefront", + "path": "/storefront-development/publishable-api-keys", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Workflows", + "autogenerate_tags": "workflow+salesChannel", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "linkSalesChannelsToApiKeyWorkflow", + "path": "/references/medusa-workflows/linkSalesChannelsToApiKeyWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createCartWorkflow", + "path": "/references/medusa-workflows/createCartWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateCartWorkflow", + "path": "/references/medusa-workflows/updateCartWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createDefaultsWorkflow", + "path": "/references/medusa-workflows/createDefaultsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "addOrderLineItemsWorkflow", + "path": "/references/medusa-workflows/addOrderLineItemsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createOrderWorkflow", + "path": "/references/medusa-workflows/createOrderWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderClaimAddNewItemWorkflow", + "path": "/references/medusa-workflows/orderClaimAddNewItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderEditAddNewItemWorkflow", + "path": "/references/medusa-workflows/orderEditAddNewItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderExchangeAddNewItemWorkflow", + "path": "/references/medusa-workflows/orderExchangeAddNewItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "importProductsWorkflow", + "path": "/references/medusa-workflows/importProductsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createSalesChannelsWorkflow", + "path": "/references/medusa-workflows/createSalesChannelsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteSalesChannelsWorkflow", + "path": "/references/medusa-workflows/deleteSalesChannelsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateSalesChannelsWorkflow", + "path": "/references/medusa-workflows/updateSalesChannelsWorkflow", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Steps", + "autogenerate_tags": "step+salesChannel", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "validateSalesChannelsExistStep", + "path": "/references/medusa-workflows/steps/validateSalesChannelsExistStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "findSalesChannelStep", + "path": "/references/medusa-workflows/steps/findSalesChannelStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "parseProductCsvStep", + "path": "/references/medusa-workflows/steps/parseProductCsvStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createDefaultSalesChannelStep", + "path": "/references/medusa-workflows/steps/createDefaultSalesChannelStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createSalesChannelsStep", + "path": "/references/medusa-workflows/steps/createSalesChannelsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteSalesChannelsStep", + "path": "/references/medusa-workflows/steps/deleteSalesChannelsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateSalesChannelsStep", + "path": "/references/medusa-workflows/steps/updateSalesChannelsStep", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", "title": "References", + "initialOpen": false, "children": [ { "loaded": true, diff --git a/www/apps/resources/sidebars/sales-channel.mjs b/www/apps/resources/sidebars/sales-channel.mjs index de38d90b5b176..d1aa355a2a05c 100644 --- a/www/apps/resources/sidebars/sales-channel.mjs +++ b/www/apps/resources/sidebars/sales-channel.mjs @@ -11,13 +11,12 @@ export const salesChannelSidebar = [ title: "Overview", }, { - type: "link", - path: "/commerce-modules/sales-channel/examples", - title: "Examples", + type: "separator", }, { - type: "sub-category", + type: "category", title: "Concepts", + initialOpen: false, children: [ { type: "link", @@ -32,8 +31,51 @@ export const salesChannelSidebar = [ ], }, { - type: "sub-category", + type: "category", + title: "Server Guides", + autogenerate_tags: "server+salesChannel", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Storefront Guides", + autogenerate_tags: "storefront+salesChannel", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Admin Guides", + autogenerate_tags: "admin+salesChannel", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "User Guides", + autogenerate_tags: "userGuides+salesChannel", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Workflows", + autogenerate_tags: "workflow+salesChannel", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Steps", + autogenerate_tags: "step+salesChannel", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", title: "References", + initialOpen: false, children: [ { type: "link", diff --git a/www/packages/tags/src/tags/index.ts b/www/packages/tags/src/tags/index.ts index 1aa4ef94c36e9..02a323bc12d65 100644 --- a/www/packages/tags/src/tags/index.ts +++ b/www/packages/tags/src/tags/index.ts @@ -1,32 +1,32 @@ export * from "./product.js" -export * from "./storefront.js" -export * from "./tax.js" +export * from "./pricing.js" +export * from "./query.js" export * from "./payment.js" export * from "./cart.js" -export * from "./order.js" -export * from "./stripe.js" -export * from "./pricing.js" +export * from "./storefront.js" +export * from "./tax.js" export * from "./server.js" -export * from "./auth.js" +export * from "./stripe.js" +export * from "./order.js" export * from "./fulfillment.js" -export * from "./query.js" export * from "./customer.js" +export * from "./inventory.js" export * from "./api-key.js" export * from "./publishable-api-key.js" export * from "./region.js" -export * from "./step.js" +export * from "./sales-channel.js" export * from "./remote-link.js" -export * from "./workflow.js" -export * from "./product-collection.js" -export * from "./inventory.js" export * from "./product-category.js" -export * from "./remote-query.js" -export * from "./sales-channel.js" +export * from "./product-collection.js" +export * from "./auth.js" +export * from "./step.js" +export * from "./workflow.js" export * from "./store.js" -export * from "./event-bus.js" -export * from "./stock-location.js" -export * from "./user.js" +export * from "./promotion.js" export * from "./locking.js" -export * from "./logger.js" +export * from "./user.js" export * from "./file.js" -export * from "./promotion.js" +export * from "./stock-location.js" +export * from "./logger.js" +export * from "./event-bus.js" +export * from "./remote-query.js" diff --git a/www/packages/tags/src/tags/sales-channel.ts b/www/packages/tags/src/tags/sales-channel.ts index 9f40edcd6c0be..8bdd634c185e1 100644 --- a/www/packages/tags/src/tags/sales-channel.ts +++ b/www/packages/tags/src/tags/sales-channel.ts @@ -1,4 +1,8 @@ export const salesChannel = [ + { + "title": "Use a Publishable API Key in the Storefront", + "path": "/storefront-development/publishable-api-keys" + }, { "title": "validateSalesChannelsExistStep", "path": "/references/medusa-workflows/steps/validateSalesChannelsExistStep" From 7e71b7f78e55151b4540e4ee00e0e22fbc8c941b Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Wed, 25 Dec 2024 18:06:44 +0200 Subject: [PATCH 17/21] revise stock location module --- .../stock-location/examples/page.mdx | 219 ------------------ .../commerce-modules/stock-location/page.mdx | 186 +++++++++------ www/apps/resources/generated/edit-dates.mjs | 3 +- www/apps/resources/generated/files-map.mjs | 4 - www/apps/resources/generated/sidebar.mjs | 83 ++++++- .../resources/sidebars/stock-location.mjs | 52 ++++- www/packages/tags/src/tags/index.ts | 32 +-- 7 files changed, 258 insertions(+), 321 deletions(-) delete mode 100644 www/apps/resources/app/commerce-modules/stock-location/examples/page.mdx diff --git a/www/apps/resources/app/commerce-modules/stock-location/examples/page.mdx b/www/apps/resources/app/commerce-modules/stock-location/examples/page.mdx deleted file mode 100644 index e530c4f797ad2..0000000000000 --- a/www/apps/resources/app/commerce-modules/stock-location/examples/page.mdx +++ /dev/null @@ -1,219 +0,0 @@ -import { CodeTabs, CodeTab } from "docs-ui" - -export const metadata = { - title: `Examples of the Stock Location Module`, -} - -# {metadata.title} - -In this document, you’ll find common examples of how you can use the Stock Location Module in your application. - - - -You should only use the Stock Location Module's main service when implementing complex customizations. For common cases, check out [available workflows instead](../../../medusa-workflows-reference/page.mdx). - - - -## Create a Stock Location - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const stockLocationModuleService = - request.scope.resolve(Modules.STOCK_LOCATION) - - const stockLocation = await stockLocationModuleService.createStockLocations({ - name: "Warehouse 1", - }) - - res.json({ - stock_location: stockLocation, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeStockLocationModule } from "@medusajs/medusa/stock-location" - -export async function POST(request: Request) { - const stockLocationModuleService = await initializeStockLocationModule({}) - - const stockLocation = await stockLocationModuleService.createStockLocations({ - name: "Warehouse 1", - }) - - return NextResponse.json({ stock_location: stockLocation }) -} -``` - - - - ---- - -## List Stock Locations - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const stockLocationModuleService = - request.scope.resolve(Modules.STOCK_LOCATION) - - res.json({ - stock_locations: await stockLocationModuleService.listStockLocations({}), - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeStockLocationModule } from "@medusajs/medusa/stock-location" - -export async function GET(request: Request) { - const stockLocationModuleService = await initializeStockLocationModule({}) - - return NextResponse.json({ - stock_locations: await stockLocationModuleService.listStockLocations({}), - }) -} -``` - - - - ---- - -## Add Address to Stock Location - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const stockLocationModuleService = - request.scope.resolve(Modules.STOCK_LOCATION) - - const stockLocation = await stockLocationModuleService.updateStockLocations({ - id: "sloc_123", - address: { - country_code: "US", - city: "New York City", - address_1: "52 Stone St", - postal_code: "10004", - }, - }) - - res.json({ - stock_location: stockLocation, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeStockLocationModule } from "@medusajs/medusa/stock-location" - -export async function POST(request: Request) { - const stockLocationModuleService = await initializeStockLocationModule({}) - - const stockLocation = await stockLocationModuleService.updateStockLocations({ - id: "sloc_123", - address: { - country_code: "us", - city: "New York City", - address_1: "52 Stone St", - postal_code: "10004", - }, - }) - - return NextResponse.json({ - stock_location: stockLocation, - }) -} -``` - - - - ---- - -## Delete a Stock Location - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function DELETE( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const stockLocationModuleService = - request.scope.resolve(Modules.STOCK_LOCATION) - - await stockLocationModuleService.deleteStockLocations("sloc_123") - - res.status(200) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeStockLocationModule } from "@medusajs/medusa/stock-location" - -export async function DELETE(request: Request) { - const stockLocationModuleService = await initializeStockLocationModule({}) - - await stockLocationModuleService.deleteStockLocations("sloc_123") -} -``` - - - - ---- - -## More Examples - -The [Stock Location Module's main service reference](/references/stock-location) provides a reference to all the methods available for use with examples for each. diff --git a/www/apps/resources/app/commerce-modules/stock-location/page.mdx b/www/apps/resources/app/commerce-modules/stock-location/page.mdx index 1b07e039108d9..e7a550a3e9bb7 100644 --- a/www/apps/resources/app/commerce-modules/stock-location/page.mdx +++ b/www/apps/resources/app/commerce-modules/stock-location/page.mdx @@ -6,95 +6,147 @@ export const metadata = { # {metadata.title} -The Stock Location Module provides stock-location-related features in your Medusa and Node.js applications. +In this section of the documentation, you will find resources to learn more about the Stock Location Module and how to use it in your application. -## How to Use Stock Location Module's Service +Medusa has stock location related features available out-of-the-box through the Stock Location Module. A [module](!docs!/learn/fundamentals/modules) is a standalone package that provides features for a single domain. Each of Medusa's commerce features are placed in commerce modules, such as this Stock Location Module. -You can use the Stock Location Module's main service by resolving from the Medusa container the resource `Modules.STOCK_LOCATION`. + -For example: +Learn more about why modules are isolated in [this documentation](!docs!/learn/fundamentals/modules/isolation). - - + -```ts title="src/workflows/hello-world/step1.ts" -import { createStep } from "@medusajs/framework/workflows-sdk" -import { Modules } from "@medusajs/framework/utils" +## Stock Location Features -const step1 = createStep("step-1", async (_, { container }) => { - const stockLocationModuleService = container.resolve( - Modules.STOCK_LOCATION - ) +- [Stock Location Management](/references/stock-location-next/models): Store and manage stock locations. Medusa links stock locations with data models of other modules that require a location, such as the [Inventory Module's InventoryLevel](./links-to-other-modules/page.mdx). +- [Address Management](/references/stock-location-next/models/StockLocationAddress): Manage the address of each stock location. - const stockLocations = await stockLocationModuleService.listStockLocations({}) -}) -``` +--- - - +## How to Use Stock Location Module's Service -```ts title="src/api/store/custom/route.ts" -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" +In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. + +You can build custom workflows and steps. You can also re-use Medusa's workflows and steps, which are provided by the `@medusajs/medusa/core-flows` package. + +For example: + +export const highlights = [ + ["12", "Modules.STOCK_LOCATION", "Resolve the module in a step."] +] + +```ts title="src/workflows/create-stock-location.ts" highlights={highlights} +import { + createWorkflow, + WorkflowResponse, + createStep, + StepResponse, +} from "@medusajs/framework/workflows-sdk" import { Modules } from "@medusajs/framework/utils" -export async function GET( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const stockLocationModuleService = - request.scope.resolve(Modules.STOCK_LOCATION) +const createStockLocationStep = createStep( + "create-stock-location", + async ({}, { container }) => { + const stockLocationModuleService = container.resolve(Modules.STOCK_LOCATION) - res.json({ - stock_locations: await stockLocationModuleService.listStockLocations({}), - }) -} -``` + const stockLocation = await stockLocationModuleService.createStockLocations({ + name: "Warehouse 1", + }) - - + return new StepResponse({ stockLocation }, stockLocation.id) + }, + async (stockLocationId, { container }) => { + const stockLocationModuleService = container.resolve(Modules.STOCK_LOCATION) -```ts title="src/subscribers/custom-handler.ts" -import { SubscriberArgs } from "@medusajs/framework" -import { Modules } from "@medusajs/framework/utils" + await stockLocationModuleService.deleteStockLocations([stockLocationId]) + } +) -export default async function subscriberHandler({ container }: SubscriberArgs) { - const stockLocationModuleService = container.resolve( - Modules.STOCK_LOCATION - ) +export const createStockLocation = createWorkflow( + "create-stock-location", + () => { + const { stockLocation } = createStockLocationStep() - const stockLocations = await stockLocationModuleService.listStockLocations({}) -} + return new WorkflowResponse({ stockLocation }) + } +) ``` - - - ---- +You can then execute the workflow in your custom API routes, scheduled jobs, or subscribers: -## Features + + + + ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import type { + MedusaRequest, + MedusaResponse, + } from "@medusajs/framework/http" + import { createStockLocation } from "../../workflows/create-stock-location" + + export async function GET( + req: MedusaRequest, + res: MedusaResponse + ) { + const { result } = await createStockLocation(req.scope) + .run() + + res.send(result) + } + ``` -### Stock Location Management + + + + ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import { + type SubscriberConfig, + type SubscriberArgs, + } from "@medusajs/framework" + import { createStockLocation } from "../workflows/create-stock-location" + + export default async function handleUserCreated({ + event: { data }, + container, + }: SubscriberArgs<{ id: string }>) { + const { result } = await createStockLocation(container) + .run() + + console.log(result) + } + + export const config: SubscriberConfig = { + event: "user.created", + } + ``` -Store and manage stock locations. Stock locations are associated with data models of other modules that require a location, such as the [Inventory Module's InventoryLevel](../inventory/concepts/page.mdx#inventory-level). + + + + ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} + import { MedusaContainer } from "@medusajs/framework/types" + import { createStockLocation } from "../workflows/create-stock-location" + + export default async function myCustomJob( + container: MedusaContainer + ) { + const { result } = await createStockLocation(container) + .run() + + console.log(result) + } + + export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, + }; + ``` -```ts -const stockLocation = await stockLocationModuleService.createStockLocations({ - name: "Warehouse 1", -}) -``` + + -### Address Management +Learn more about workflows in [this documentation](!docs!/learn/fundamentals/workflows). -Manage the address of each stock location. +--- -```ts -const stockLocation = await stockLocationModuleService.updateStockLocations({ - id: "sloc_123", - address: { - country_code: "us", - city: "New York City", - address_1: "52 Stone St", - postal_code: "10004", - }, -}) -``` + diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index 7e05cef868b84..5f9e57bf3273a 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -82,8 +82,7 @@ export const generatedEditDates = { "app/commerce-modules/stock-location/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/stock-location/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/stock-location/concepts/page.mdx": "2024-10-15T14:32:21.875Z", - "app/commerce-modules/stock-location/examples/page.mdx": "2024-10-15T15:00:41.265Z", - "app/commerce-modules/stock-location/page.mdx": "2024-12-09T14:48:42.516Z", + "app/commerce-modules/stock-location/page.mdx": "2024-12-25T16:04:28.247Z", "app/commerce-modules/store/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/store/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/store/examples/page.mdx": "2024-10-15T15:00:47.283Z", diff --git a/www/apps/resources/generated/files-map.mjs b/www/apps/resources/generated/files-map.mjs index 2c8927722edfd..a4e791fe52e4a 100644 --- a/www/apps/resources/generated/files-map.mjs +++ b/www/apps/resources/generated/files-map.mjs @@ -531,10 +531,6 @@ export const filesMap = [ "filePath": "/www/apps/resources/app/commerce-modules/stock-location/concepts/page.mdx", "pathname": "/commerce-modules/stock-location/concepts" }, - { - "filePath": "/www/apps/resources/app/commerce-modules/stock-location/examples/page.mdx", - "pathname": "/commerce-modules/stock-location/examples" - }, { "filePath": "/www/apps/resources/app/commerce-modules/stock-location/links-to-other-modules/page.mdx", "pathname": "/commerce-modules/stock-location/links-to-other-modules" diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs index d42af3b693732..a1c46f68c3b9d 100644 --- a/www/apps/resources/generated/sidebar.mjs +++ b/www/apps/resources/generated/sidebar.mjs @@ -11648,18 +11648,14 @@ export const generatedSidebar = [ "children": [] }, { - "loaded": true, - "isPathHref": true, - "type": "link", - "path": "/commerce-modules/stock-location/examples", - "title": "Examples", - "children": [] + "type": "separator" }, { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", "title": "Concepts", + "initialOpen": false, "children": [ { "loaded": true, @@ -11682,8 +11678,79 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", + "title": "Workflows", + "autogenerate_tags": "workflow+stockLocation", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createStockLocationsWorkflow", + "path": "/references/medusa-workflows/createStockLocationsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteStockLocationsWorkflow", + "path": "/references/medusa-workflows/deleteStockLocationsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateStockLocationsWorkflow", + "path": "/references/medusa-workflows/updateStockLocationsWorkflow", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Steps", + "autogenerate_tags": "step+stockLocation", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createStockLocations", + "path": "/references/medusa-workflows/steps/createStockLocations", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteStockLocationsStep", + "path": "/references/medusa-workflows/steps/deleteStockLocationsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateStockLocationsStep", + "path": "/references/medusa-workflows/steps/updateStockLocationsStep", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", "title": "References", + "initialOpen": false, "children": [ { "loaded": true, diff --git a/www/apps/resources/sidebars/stock-location.mjs b/www/apps/resources/sidebars/stock-location.mjs index daa2c277f516a..39b4cc02a3a8f 100644 --- a/www/apps/resources/sidebars/stock-location.mjs +++ b/www/apps/resources/sidebars/stock-location.mjs @@ -11,13 +11,12 @@ export const stockLocationSidebar = [ title: "Overview", }, { - type: "link", - path: "/commerce-modules/stock-location/examples", - title: "Examples", + type: "separator", }, { - type: "sub-category", + type: "category", title: "Concepts", + initialOpen: false, children: [ { type: "link", @@ -32,8 +31,51 @@ export const stockLocationSidebar = [ ], }, { - type: "sub-category", + type: "category", + title: "Server Guides", + autogenerate_tags: "server+stockLocation", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Storefront Guides", + autogenerate_tags: "storefront+stockLocation", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Admin Guides", + autogenerate_tags: "admin+stockLocation", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "User Guides", + autogenerate_tags: "userGuides+stockLocation", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Workflows", + autogenerate_tags: "workflow+stockLocation", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Steps", + autogenerate_tags: "step+stockLocation", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", title: "References", + initialOpen: false, children: [ { type: "link", diff --git a/www/packages/tags/src/tags/index.ts b/www/packages/tags/src/tags/index.ts index 02a323bc12d65..037f5c17a3464 100644 --- a/www/packages/tags/src/tags/index.ts +++ b/www/packages/tags/src/tags/index.ts @@ -1,32 +1,32 @@ export * from "./product.js" -export * from "./pricing.js" -export * from "./query.js" -export * from "./payment.js" -export * from "./cart.js" -export * from "./storefront.js" export * from "./tax.js" -export * from "./server.js" +export * from "./storefront.js" +export * from "./cart.js" +export * from "./payment.js" export * from "./stripe.js" export * from "./order.js" export * from "./fulfillment.js" export * from "./customer.js" +export * from "./auth.js" +export * from "./product-collection.js" +export * from "./product-category.js" export * from "./inventory.js" -export * from "./api-key.js" +export * from "./query.js" +export * from "./server.js" export * from "./publishable-api-key.js" +export * from "./pricing.js" +export * from "./step.js" export * from "./region.js" export * from "./sales-channel.js" export * from "./remote-link.js" -export * from "./product-category.js" -export * from "./product-collection.js" -export * from "./auth.js" -export * from "./step.js" +export * from "./api-key.js" export * from "./workflow.js" +export * from "./event-bus.js" +export * from "./remote-query.js" +export * from "./locking.js" export * from "./store.js" +export * from "./logger.js" +export * from "./file.js" export * from "./promotion.js" -export * from "./locking.js" export * from "./user.js" -export * from "./file.js" export * from "./stock-location.js" -export * from "./logger.js" -export * from "./event-bus.js" -export * from "./remote-query.js" From 40a65a96958c04a8265b8900be9653dfc5d5b679 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Wed, 25 Dec 2024 18:12:50 +0200 Subject: [PATCH 18/21] revise store module --- .../commerce-modules/stock-location/page.mdx | 14 +- .../commerce-modules/store/examples/page.mdx | 272 ------------------ .../app/commerce-modules/store/page.mdx | 192 ++++++++----- www/apps/resources/generated/edit-dates.mjs | 5 +- www/apps/resources/generated/files-map.mjs | 4 - www/apps/resources/generated/sidebar.mjs | 171 ++++++++++- www/apps/resources/sidebars/store.mjs | 52 +++- www/packages/tags/src/tags/index.ts | 30 +- 8 files changed, 355 insertions(+), 385 deletions(-) delete mode 100644 www/apps/resources/app/commerce-modules/store/examples/page.mdx diff --git a/www/apps/resources/app/commerce-modules/stock-location/page.mdx b/www/apps/resources/app/commerce-modules/stock-location/page.mdx index e7a550a3e9bb7..278cc85579199 100644 --- a/www/apps/resources/app/commerce-modules/stock-location/page.mdx +++ b/www/apps/resources/app/commerce-modules/stock-location/page.mdx @@ -62,7 +62,7 @@ const createStockLocationStep = createStep( } ) -export const createStockLocation = createWorkflow( +export const createStockLocationWorkflow = createWorkflow( "create-stock-location", () => { const { stockLocation } = createStockLocationStep() @@ -82,13 +82,13 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or MedusaRequest, MedusaResponse, } from "@medusajs/framework/http" - import { createStockLocation } from "../../workflows/create-stock-location" + import { createStockLocationWorkflow } from "../../workflows/create-stock-location" export async function GET( req: MedusaRequest, res: MedusaResponse ) { - const { result } = await createStockLocation(req.scope) + const { result } = await createStockLocationWorkflow(req.scope) .run() res.send(result) @@ -103,13 +103,13 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or type SubscriberConfig, type SubscriberArgs, } from "@medusajs/framework" - import { createStockLocation } from "../workflows/create-stock-location" + import { createStockLocationWorkflow } from "../workflows/create-stock-location" export default async function handleUserCreated({ event: { data }, container, }: SubscriberArgs<{ id: string }>) { - const { result } = await createStockLocation(container) + const { result } = await createStockLocationWorkflow(container) .run() console.log(result) @@ -125,12 +125,12 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} import { MedusaContainer } from "@medusajs/framework/types" - import { createStockLocation } from "../workflows/create-stock-location" + import { createStockLocationWorkflow } from "../workflows/create-stock-location" export default async function myCustomJob( container: MedusaContainer ) { - const { result } = await createStockLocation(container) + const { result } = await createStockLocationWorkflow(container) .run() console.log(result) diff --git a/www/apps/resources/app/commerce-modules/store/examples/page.mdx b/www/apps/resources/app/commerce-modules/store/examples/page.mdx deleted file mode 100644 index 29eb615e28c02..0000000000000 --- a/www/apps/resources/app/commerce-modules/store/examples/page.mdx +++ /dev/null @@ -1,272 +0,0 @@ -import { CodeTabs, CodeTab } from "docs-ui" - -export const metadata = { - title: `Examples of the Store Module`, -} - -# {metadata.title} - -In this guide, you’ll find common examples of how you can use the Store Module in your application. - - - -You should only use the Store Module's main service when implementing complex customizations. For common cases, check out [available workflows instead](../../../medusa-workflows-reference/page.mdx). - - - -## Create a Store - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const storeModuleService = request.scope.resolve( - Modules.STORE - ) - - const store = await storeModuleService.createStores({ - name: "My Store", - supported_currencies: [ - { - currency_code: "usd", - is_default: true, - }, - ], - }) - - res.json({ - store, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeStoreModule } from "@medusajs/medusa/store" - -export async function POST(request: Request) { - const storeModuleService = await initializeStoreModule() - - const store = await storeModuleService.createStores({ - name: "My Store", - supported_currencies: [ - { - currency_code: "usd", - is_default: true, - }, - ], - }) - - res.json({ - store, - }) -} -``` - - - - ---- - -## List Stores - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const storeModuleService = request.scope.resolve( - Modules.STORE - ) - - res.json({ - stores: await storeModuleService.listStores(), - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeStoreModule } from "@medusajs/medusa/store" - -export async function GET(request: Request) { - const storeModuleService = await initializeStoreModule() - - const salesChannels = await storeModuleService.listStores() - - return NextResponse.json({ - stores: await storeModuleService.list(), - }) -} -``` - - - - ---- - -## Retrieve a Store by its ID - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const storeModuleService = request.scope.resolve( - Modules.STORE - ) - - const store = await storeModuleService.retrieveStore("store_123") - - res.json({ - store, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeStoreModule } from "@medusajs/medusa/store" - -export async function GET(request: Request, { params }: ContextType) { - const storeModuleService = await initializeStoreModule() - - const store = await storeModuleService.retrieveStore("store_123") - - return NextResponse.json({ store }) -} -``` - - - - ---- - -## Update a Store - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const storeModuleService = request.scope.resolve( - Modules.STORE - ) - - const store = await storeModuleService.updateStores("store_123", { - name: "Change Store", - }) - - res.json({ - store, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeStoreModule } from "@medusajs/medusa/store" - -export async function POST(request: Request, { params }: ContextType) { - const storeModuleService = await initializeStoreModule() - - const store = await storeModuleService.updateStores("store_123", { - name: "Change Store", - }) - - return NextResponse.json({ store }) -} -``` - - - - ---- - -## Delete a Store - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function DELETE( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const storeModuleService = request.scope.resolve( - Modules.STORE - ) - - await storeModuleService.deleteStores("store_123") - - res.status(200) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeStoreModule } from "@medusajs/medusa/store" - -export async function DELETE(request: Request, { params }: ContextType) { - const storeModuleService = await initializeStoreModule() - - await storeModuleService.deleteStores("store_123") -} -``` - - - - ---- - -## More Examples - -The [Store Module's main service reference](/references/store) provides a reference to all the methods available for use with examples for each. diff --git a/www/apps/resources/app/commerce-modules/store/page.mdx b/www/apps/resources/app/commerce-modules/store/page.mdx index 55936301a9cfa..7287b367c6746 100644 --- a/www/apps/resources/app/commerce-modules/store/page.mdx +++ b/www/apps/resources/app/commerce-modules/store/page.mdx @@ -6,98 +6,148 @@ export const metadata = { # {metadata.title} -The Store Module provides store-related features in your Medusa and Node.js applications. +In this section of the documentation, you will find resources to learn more about the Store Module and how to use it in your application. -## How to Use Store Module's Service +Medusa has store related features available out-of-the-box through the Store Module. A [module](!docs!/learn/fundamentals/modules) is a standalone package that provides features for a single domain. Each of Medusa's commerce features are placed in commerce modules, such as this Store Module. -You can use the Store Module's main service by resolving from the Medusa container the resource `Modules.STORE`. + -For example: +Learn more about why modules are isolated in [this documentation](!docs!/learn/fundamentals/modules/isolation). - - + -```ts title="src/workflows/hello-world/step1.ts" -import { createStep } from "@medusajs/framework/workflows-sdk" -import { Modules } from "@medusajs/framework/utils" +## Store Features -const step1 = createStep("step-1", async (_, { container }) => { - const storeModuleService: IStoreModuleService = container.resolve( - Modules.STORE - ) +- [Store Management](/references/store/models/Store): Create and manage stores in your application. +- [Multi-Tenancy Support](/references/store/models/Store): Create multiple stores, each having its own configurations. - const stores = await storeModuleService.listStores() -}) -``` +--- - - +## How to Use Store Module's Service -```ts title="src/api/store/custom/route.ts" -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" +In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. -export async function GET( - request: MedusaRequest, - res: MedusaResponse -): Promise { - const storeModuleService: IStoreModuleService = request.scope.resolve( - Modules.STORE - ) - - res.json({ - stores: await storeModuleService.listStores(), - }) -} -``` +You can build custom workflows and steps. You can also re-use Medusa's workflows and steps, which are provided by the `@medusajs/medusa/core-flows` package. - - +For example: -```ts title="src/subscribers/custom-handler.ts" -import { SubscriberArgs } from "@medusajs/framework" +export const highlights = [ + ["12", "Modules.STORE", "Resolve the module in a step."] +] + +```ts title="src/workflows/create-store.ts" highlights={highlights} +import { + createWorkflow, + WorkflowResponse, + createStep, + StepResponse, +} from "@medusajs/framework/workflows-sdk" import { Modules } from "@medusajs/framework/utils" -export default async function subscriberHandler({ container }: SubscriberArgs) { - const storeModuleService: IStoreModuleService = container.resolve( - Modules.STORE - ) +const createStoreStep = createStep( + "create-store", + async ({}, { container }) => { + const storeModuleService = container.resolve(Modules.STORE) - const stores = await storeModuleService.listStores() -} -``` + const store = await storeModuleService.createStores({ + name: "My Store", + supported_currency_codes: ["usd"], + }) - - + return new StepResponse({ store }, store.id) + }, + async (storeId, { container }) => { + const storeModuleService = container.resolve(Modules.STORE) + + await storeModuleService.deleteStores([storeId]) + } +) + +export const createStoreWorkflow = createWorkflow( + "create-store", + () => { + const { store } = createStoreStep() + + return new WorkflowResponse({ store }) + } +) +``` ---- +You can then execute the workflow in your custom API routes, scheduled jobs, or subscribers: -## Features + + + + ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import type { + MedusaRequest, + MedusaResponse, + } from "@medusajs/framework/http" + import { createStoreWorkflow } from "../../workflows/create-store" + + export async function GET( + req: MedusaRequest, + res: MedusaResponse + ) { + const { result } = await createStoreWorkflow(req.scope) + .run() + + res.send(result) + } + ``` -### Store Management + + + + ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import { + type SubscriberConfig, + type SubscriberArgs, + } from "@medusajs/framework" + import { createStoreWorkflow } from "../workflows/create-store" + + export default async function handleUserCreated({ + event: { data }, + container, + }: SubscriberArgs<{ id: string }>) { + const { result } = await createStoreWorkflow(container) + .run() + + console.log(result) + } + + export const config: SubscriberConfig = { + event: "user.created", + } + ``` -A store holds the main configurations of your commerce store, such as supported currencies, default region and sales channel, and more. + + + + ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} + import { MedusaContainer } from "@medusajs/framework/types" + import { createStoreWorkflow } from "../workflows/create-store" + + export default async function myCustomJob( + container: MedusaContainer + ) { + const { result } = await createStoreWorkflow(container) + .run() + + console.log(result) + } + + export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, + }; + ``` -```ts -const store = await storeModuleService.createStores({ - name: "My Store", - supported_currency_codes: ["usd"], -}) -``` + + -### Multi-Tenancy Support +Learn more about workflows in [this documentation](!docs!/learn/fundamentals/workflows). -You can create multiple stores, each having its own configurations. +--- -```ts -const stores = await storeModuleService.createStores([ - { - name: "USA Store", - supported_currency_codes: ["usd"], - }, - { - name: "Europe Store", - supported_currency_codes: ["eur"], - }, -]) -``` + diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index 5f9e57bf3273a..737b73b28db47 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -82,11 +82,10 @@ export const generatedEditDates = { "app/commerce-modules/stock-location/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/stock-location/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/stock-location/concepts/page.mdx": "2024-10-15T14:32:21.875Z", - "app/commerce-modules/stock-location/page.mdx": "2024-12-25T16:04:28.247Z", + "app/commerce-modules/stock-location/page.mdx": "2024-12-25T16:09:26.781Z", "app/commerce-modules/store/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/store/_events/page.mdx": "2024-07-03T19:27:13+03:00", - "app/commerce-modules/store/examples/page.mdx": "2024-10-15T15:00:47.283Z", - "app/commerce-modules/store/page.mdx": "2024-12-09T14:48:46.363Z", + "app/commerce-modules/store/page.mdx": "2024-12-25T16:09:12.124Z", "app/commerce-modules/tax/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/tax/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/tax/examples/page.mdx": "2024-10-15T15:00:52.899Z", diff --git a/www/apps/resources/generated/files-map.mjs b/www/apps/resources/generated/files-map.mjs index a4e791fe52e4a..f8dfe2a300e2f 100644 --- a/www/apps/resources/generated/files-map.mjs +++ b/www/apps/resources/generated/files-map.mjs @@ -543,10 +543,6 @@ export const filesMap = [ "filePath": "/www/apps/resources/app/commerce-modules/store/admin-widget-zones/page.mdx", "pathname": "/commerce-modules/store/admin-widget-zones" }, - { - "filePath": "/www/apps/resources/app/commerce-modules/store/examples/page.mdx", - "pathname": "/commerce-modules/store/examples" - }, { "filePath": "/www/apps/resources/app/commerce-modules/store/links-to-other-modules/page.mdx", "pathname": "/commerce-modules/store/links-to-other-modules" diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs index a1c46f68c3b9d..a5e6ecb0657d3 100644 --- a/www/apps/resources/generated/sidebar.mjs +++ b/www/apps/resources/generated/sidebar.mjs @@ -11908,18 +11908,14 @@ export const generatedSidebar = [ "children": [] }, { - "loaded": true, - "isPathHref": true, - "type": "link", - "path": "/commerce-modules/store/examples", - "title": "Examples", - "children": [] + "type": "separator" }, { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", "title": "Concepts", + "initialOpen": false, "children": [ { "loaded": true, @@ -11934,8 +11930,167 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", + "title": "Workflows", + "autogenerate_tags": "workflow+store", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createCartWorkflow", + "path": "/references/medusa-workflows/createCartWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateCartWorkflow", + "path": "/references/medusa-workflows/updateCartWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createDefaultsWorkflow", + "path": "/references/medusa-workflows/createDefaultsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "addOrderLineItemsWorkflow", + "path": "/references/medusa-workflows/addOrderLineItemsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createOrderWorkflow", + "path": "/references/medusa-workflows/createOrderWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderClaimAddNewItemWorkflow", + "path": "/references/medusa-workflows/orderClaimAddNewItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderEditAddNewItemWorkflow", + "path": "/references/medusa-workflows/orderEditAddNewItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderExchangeAddNewItemWorkflow", + "path": "/references/medusa-workflows/orderExchangeAddNewItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createStoresWorkflow", + "path": "/references/medusa-workflows/createStoresWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteStoresWorkflow", + "path": "/references/medusa-workflows/deleteStoresWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateStoresWorkflow", + "path": "/references/medusa-workflows/updateStoresWorkflow", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Steps", + "autogenerate_tags": "step+store", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "findOneOrAnyRegionStep", + "path": "/references/medusa-workflows/steps/findOneOrAnyRegionStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "findSalesChannelStep", + "path": "/references/medusa-workflows/steps/findSalesChannelStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createDefaultStoreStep", + "path": "/references/medusa-workflows/steps/createDefaultStoreStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createStoresStep", + "path": "/references/medusa-workflows/steps/createStoresStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteStoresStep", + "path": "/references/medusa-workflows/steps/deleteStoresStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateStoresStep", + "path": "/references/medusa-workflows/steps/updateStoresStep", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", "title": "References", + "initialOpen": false, "children": [ { "loaded": true, diff --git a/www/apps/resources/sidebars/store.mjs b/www/apps/resources/sidebars/store.mjs index 08d87591ba8f8..ecb00d450e1ad 100644 --- a/www/apps/resources/sidebars/store.mjs +++ b/www/apps/resources/sidebars/store.mjs @@ -11,13 +11,12 @@ export const storeSidebar = [ title: "Overview", }, { - type: "link", - path: "/commerce-modules/store/examples", - title: "Examples", + type: "separator", }, { - type: "sub-category", + type: "category", title: "Concepts", + initialOpen: false, children: [ { type: "link", @@ -27,8 +26,51 @@ export const storeSidebar = [ ], }, { - type: "sub-category", + type: "category", + title: "Server Guides", + autogenerate_tags: "server+store", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Storefront Guides", + autogenerate_tags: "storefront+store", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Admin Guides", + autogenerate_tags: "admin+store", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "User Guides", + autogenerate_tags: "userGuides+store", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Workflows", + autogenerate_tags: "workflow+store", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Steps", + autogenerate_tags: "step+store", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", title: "References", + initialOpen: false, children: [ { type: "link", diff --git a/www/packages/tags/src/tags/index.ts b/www/packages/tags/src/tags/index.ts index 037f5c17a3464..aa13b7c863585 100644 --- a/www/packages/tags/src/tags/index.ts +++ b/www/packages/tags/src/tags/index.ts @@ -1,32 +1,32 @@ export * from "./product.js" -export * from "./tax.js" export * from "./storefront.js" -export * from "./cart.js" export * from "./payment.js" +export * from "./pricing.js" +export * from "./cart.js" export * from "./stripe.js" -export * from "./order.js" export * from "./fulfillment.js" -export * from "./customer.js" -export * from "./auth.js" -export * from "./product-collection.js" -export * from "./product-category.js" -export * from "./inventory.js" +export * from "./order.js" export * from "./query.js" +export * from "./tax.js" export * from "./server.js" +export * from "./inventory.js" export * from "./publishable-api-key.js" -export * from "./pricing.js" -export * from "./step.js" +export * from "./api-key.js" +export * from "./product-collection.js" export * from "./region.js" export * from "./sales-channel.js" -export * from "./remote-link.js" -export * from "./api-key.js" +export * from "./step.js" +export * from "./product-category.js" +export * from "./auth.js" +export * from "./remote-query.js" export * from "./workflow.js" +export * from "./remote-link.js" export * from "./event-bus.js" -export * from "./remote-query.js" -export * from "./locking.js" +export * from "./customer.js" export * from "./store.js" export * from "./logger.js" export * from "./file.js" +export * from "./stock-location.js" +export * from "./locking.js" export * from "./promotion.js" export * from "./user.js" -export * from "./stock-location.js" From af9eb03cb11e97ed449eb2f82f19312d92f7b092 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Wed, 25 Dec 2024 18:20:25 +0200 Subject: [PATCH 19/21] revise tax module --- .../commerce-modules/tax/examples/page.mdx | 344 ------------------ .../app/commerce-modules/tax/page.mdx | 230 ++++++------ www/apps/resources/generated/edit-dates.mjs | 3 +- www/apps/resources/generated/files-map.mjs | 4 - www/apps/resources/generated/sidebar.mjs | 293 ++++++++++++++- www/apps/resources/sidebars/tax.mjs | 52 ++- www/packages/tags/src/tags/index.ts | 36 +- 7 files changed, 468 insertions(+), 494 deletions(-) delete mode 100644 www/apps/resources/app/commerce-modules/tax/examples/page.mdx diff --git a/www/apps/resources/app/commerce-modules/tax/examples/page.mdx b/www/apps/resources/app/commerce-modules/tax/examples/page.mdx deleted file mode 100644 index 3a68baa07256b..0000000000000 --- a/www/apps/resources/app/commerce-modules/tax/examples/page.mdx +++ /dev/null @@ -1,344 +0,0 @@ -import { CodeTabs, CodeTab } from "docs-ui" - -export const metadata = { - title: `Examples of the Tax Module`, -} - -# {metadata.title} - -In this guide, you’ll find common examples of how you can use the Tax Module in your application. - - - -You should only use the Tax Module's main service when implementing complex customizations. For common cases, check out [available workflows instead](../../../medusa-workflows-reference/page.mdx). - - - -## Create a Tax Region - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const taxModuleService = req.scope.resolve( - Modules.TAX - ) - - const taxRegion = await taxModuleService.createTaxRegions({ - country_code: "us", - default_tax_rate: { - rate: 10, - name: "Default rate", - }, - }) - - res.json({ - tax_region: taxRegion, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeTaxModule } from "@medusajs/medusa/tax" - -export async function POST(request: Request) { - const taxModuleService = await initializeTaxModule() - - const taxRegion = await taxModuleService.createTaxRegions({ - country_code: "us", - default_tax_rate: { - rate: 10, - name: "Default rate", - }, - }) - - return NextResponse.json({ - tax_region: taxRegion, - }) -} -``` - - - - ---- - -## List Tax Regions - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const taxModuleService = req.scope.resolve( - Modules.TAX - ) - - res.json({ - tax_regions: await taxModuleService.listTaxRegions(), - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeTaxModule } from "@medusajs/medusa/tax" - -export async function GET(request: Request) { - const taxModuleService = await initializeTaxModule() - - return NextResponse.json({ - tax_regions: await taxModuleService.listTaxRegions(), - }) -} -``` - - - - ---- - -## Create Tax Rate with Rules - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const taxModuleService = req.scope.resolve( - Modules.TAX - ) - - const taxRate = await taxModuleService.createTaxRates({ - tax_region_id: "txreg_123", - name: "Custom rate", - rate: 15, - rules: [ - { - reference: "product_type", - reference_id: "ptyp_1", - }, - { - reference: "product", - reference_id: "prod_123", - }, - ], - }) - - res.json({ - tax_rate: taxRate, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeTaxModule } from "@medusajs/medusa/tax" - -export async function POST(request: Request) { - const taxModuleService = await initializeTaxModule() - - const taxRate = await taxModuleService.createTaxRates({ - tax_region_id: "txreg_123", - name: "Custom rate", - rate: 15, - rules: [ - { - reference: "product_type", - reference_id: "ptyp_1", - }, - { - reference: "product", - reference_id: "prod_123", - }, - ], - }) - - return NextResponse.json({ - tax_rate: taxRate, - }) -} -``` - - - - ---- - -## List Tax Rates - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const taxModuleService = req.scope.resolve( - Modules.TAX - ) - - res.json({ - tax_rates: await taxModuleService.listTaxRates(), - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeTaxModule } from "@medusajs/medusa/tax" - -export async function GET(request: Request) { - const taxModuleService = await initializeTaxModule() - - return NextResponse.json({ - tax_rates: await taxModuleService.listTaxRates(), - }) -} -``` - - - - ---- - -## Get Tax Lines - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const taxModuleService = req.scope.resolve( - Modules.TAX - ) - - const taxLines = await taxModuleService.getTaxLines( - [ - { - id: "cali_123", - product_id: "prod_123", - unit_price: 1000, - }, - { - id: "casm_123", - shipping_option_id: "so_123", - unit_price: 2000, - }, - ], - { - address: { - country_code: "us", - postal_code: "123456", - }, - customer: { - id: "cus_123", - email: "user@example.com", - customer_groups: ["VIP"], - }, - } - ) - - res.json({ - tax_lines: taxLines, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeTaxModule } from "@medusajs/medusa/tax" - -export async function GET(request: Request) { - const taxModuleService = await initializeTaxModule() - - const taxLines = await taxModuleService.getTaxLines( - [ - { - id: "cali_123", - product_id: "prod_123", - unit_price: 1000, - }, - { - id: "casm_123", - shipping_option_id: "so_123", - unit_price: 2000, - }, - ], - { - address: { - country_code: "us", - postal_code: "123456", - }, - customer: { - id: "cus_123", - email: "user@example.com", - customer_groups: ["VIP"], - }, - } - ) - - return NextResponse.json({ - tax_lines: taxLines, - }) -} -``` - - - - ---- - -## More Examples - -The [Tax Module's main service reference](/references/tax) provides a reference to all the methods available for use with examples for each. diff --git a/www/apps/resources/app/commerce-modules/tax/page.mdx b/www/apps/resources/app/commerce-modules/tax/page.mdx index 615e7f5b1e002..a8b0bfa15c1e1 100644 --- a/www/apps/resources/app/commerce-modules/tax/page.mdx +++ b/www/apps/resources/app/commerce-modules/tax/page.mdx @@ -6,142 +6,154 @@ export const metadata = { # {metadata.title} -The Tax Module provides tax-related features in your Medusa and Node.js applications. +In this section of the documentation, you will find resources to learn more about the Tax Module and how to use it in your application. -## How to Use Tax Module's Service +Medusa has tax related features available out-of-the-box through the Tax Module. A [module](!docs!/learn/fundamentals/modules) is a standalone package that provides features for a single domain. Each of Medusa's commerce features are placed in commerce modules, such as this Tax Module. -You can use the Tax Module's main service by resolving from the Medusa container the resource `Modules.TAX`. + -For example: +Learn more about why modules are isolated in [this documentation](!docs!/learn/fundamentals/modules/isolation). - - + -```ts title="src/workflows/hello-world/step1.ts" -import { createStep } from "@medusajs/framework/workflows-sdk" -import { Modules } from "@medusajs/framework/utils" +## Tax Features -const step1 = createStep("step-1", async (_, { container }) => { - const taxModuleService = container.resolve( - Modules.TAX - ) +- [Tax Settings Per Region](./tax-region/page.mdx): Set different tax settings for each tax region. +- [Tax Rates and Rules](./tax-rates-and-rules/page.mdx): Manage each region's default tax rates and override them with conditioned tax rates. +- [Retrieve Tax Lines for carts and orders](./tax-calculation-with-provider/page.mdx): Calculate and retrieve the tax lines of a cart or order's line items and shipping methods with tax providers. - const taxRegions = await taxModuleService.listTaxRegions() -}) -``` +--- - - +## How to Use Tax Module's Service -```ts title="src/api/store/custom/route.ts" -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" +In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. -export async function GET( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const taxModuleService = req.scope.resolve( - Modules.TAX - ) - - res.json({ - tax_regions: await taxModuleService.listTaxRegions(), - }) -} -``` +You can build custom workflows and steps. You can also re-use Medusa's workflows and steps, which are provided by the `@medusajs/medusa/core-flows` package. - - +For example: -```ts title="src/subscribers/custom-handler.ts" -import { SubscriberArgs } from "@medusajs/framework" +export const highlights = [ + ["12", "Modules.TAX", "Resolve the module in a step."] +] + +```ts title="src/workflows/create-tax-region.ts" highlights={highlights} +import { + createWorkflow, + WorkflowResponse, + createStep, + StepResponse, +} from "@medusajs/framework/workflows-sdk" import { Modules } from "@medusajs/framework/utils" -export default async function subscriberHandler({ container }: SubscriberArgs) { - const taxModuleService = container.resolve( - Modules.TAX - ) - - const taxRegions = await taxModuleService.listTaxRegions() -} -``` - - - +const createTaxRegionStep = createStep( + "create-tax-region", + async ({}, { container }) => { + const taxModuleService = container.resolve(Modules.TAX) ---- + const taxRegion = await taxModuleService.createTaxRegions({ + country_code: "us", + }) -## Features + return new StepResponse({ taxRegion }, taxRegion.id) + }, + async (taxRegionId, { container }) => { + const taxModuleService = container.resolve(Modules.TAX) -### Tax Settings Per Region + await taxModuleService.deleteTaxRegions([taxRegionId]) + } +) -Set different tax settings for each tax region. +export const createTaxRegionWorkflow = createWorkflow( + "create-tax-region", + () => { + const { taxRegion } = await createTaxRegionStep() -```ts -const taxRegion = await taxModuleService.createTaxRegions({ - country_code: "us", -}) + return new WorkflowResponse({ taxRegion }) + } +) ``` -### Tax Rates and Rules +You can then execute the workflow in your custom API routes, scheduled jobs, or subscribers: -Manage each region's default tax rates and override them with conditioned tax rates. + + + + ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import type { + MedusaRequest, + MedusaResponse, + } from "@medusajs/framework/http" + import { createTaxRegionWorkflow } from "../../workflows/create-tax-region" + + export async function GET( + req: MedusaRequest, + res: MedusaResponse + ) { + const { result } = await createTaxRegionWorkflow(req.scope) + .run() + + res.send(result) + } + ``` -```ts -const taxRates = await taxModuleService.createTaxRates([ - { - tax_region_id: "txreg_123", - name: "Default tax rate", - is_default: true, - rate: 10, - }, - { - tax_region_id: "txreg_123", - name: "Shirt product type", - is_default: false, - rate: 15, - rules: [ - { - reference: "product_type", - reference_id: "ptyp_1", - }, - ], - }, -]) -``` + + + + ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import { + type SubscriberConfig, + type SubscriberArgs, + } from "@medusajs/framework" + import { createTaxRegionWorkflow } from "../workflows/create-tax-region" + + export default async function handleUserCreated({ + event: { data }, + container, + }: SubscriberArgs<{ id: string }>) { + const { result } = await createTaxRegionWorkflow(container) + .run() + + console.log(result) + } + + export const config: SubscriberConfig = { + event: "user.created", + } + ``` -### Retrieve Cart's Tax Lines - -Calculate and retrieve the tax lines of a cart's line items and shipping methods with tax providers. - -```ts -const taxLines = await taxModuleService.getTaxLines( - [ - { - id: "cali_123", - product_id: "prod_123", - unit_price: 1000, - quantity: 1, - }, - { - id: "casm_123", - shipping_option_id: "so_123", - unit_price: 2000, - }, - ], - { - address: { - country_code: "us", - }, - } -) -``` + + + + ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} + import { MedusaContainer } from "@medusajs/framework/types" + import { createTaxRegionWorkflow } from "../workflows/create-tax-region" + + export default async function myCustomJob( + container: MedusaContainer + ) { + const { result } = await createTaxRegionWorkflow(container) + .run() + + console.log(result) + } + + export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, + }; + ``` + + + -You can use different tax providers for each region to handle tax-line retrieval differently. +Learn more about workflows in [this documentation](!docs!/learn/fundamentals/workflows). --- ## Configure Tax Module -Refer to [this documentation](./module-options/page.mdx) for details on the module's options. +The Tax Module accepts options for further configurations. Refer to [this documentation](./module-options/page.mdx) for details on the module's options. + +--- + + \ No newline at end of file diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index 737b73b28db47..430dc322d2c91 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -88,12 +88,11 @@ export const generatedEditDates = { "app/commerce-modules/store/page.mdx": "2024-12-25T16:09:12.124Z", "app/commerce-modules/tax/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/tax/_events/page.mdx": "2024-07-03T19:27:13+03:00", - "app/commerce-modules/tax/examples/page.mdx": "2024-10-15T15:00:52.899Z", "app/commerce-modules/tax/module-options/page.mdx": "2024-10-15T14:35:46.117Z", "app/commerce-modules/tax/tax-calculation-with-provider/page.mdx": "2024-10-15T14:43:00.700Z", "app/commerce-modules/tax/tax-rates-and-rules/page.mdx": "2024-10-15T14:38:06.889Z", "app/commerce-modules/tax/tax-region/page.mdx": "2024-10-15T14:36:47.028Z", - "app/commerce-modules/tax/page.mdx": "2024-12-09T14:48:50.327Z", + "app/commerce-modules/tax/page.mdx": "2024-12-25T16:17:00.782Z", "app/commerce-modules/user/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/user/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/user/examples/page.mdx": "2024-10-15T15:00:59.626Z", diff --git a/www/apps/resources/generated/files-map.mjs b/www/apps/resources/generated/files-map.mjs index f8dfe2a300e2f..4cf58ac9ca177 100644 --- a/www/apps/resources/generated/files-map.mjs +++ b/www/apps/resources/generated/files-map.mjs @@ -555,10 +555,6 @@ export const filesMap = [ "filePath": "/www/apps/resources/app/commerce-modules/tax/admin-widget-zones/page.mdx", "pathname": "/commerce-modules/tax/admin-widget-zones" }, - { - "filePath": "/www/apps/resources/app/commerce-modules/tax/examples/page.mdx", - "pathname": "/commerce-modules/tax/examples" - }, { "filePath": "/www/apps/resources/app/commerce-modules/tax/module-options/page.mdx", "pathname": "/commerce-modules/tax/module-options" diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs index a5e6ecb0657d3..1661bf282dfe3 100644 --- a/www/apps/resources/generated/sidebar.mjs +++ b/www/apps/resources/generated/sidebar.mjs @@ -12256,18 +12256,14 @@ export const generatedSidebar = [ "children": [] }, { - "loaded": true, - "isPathHref": true, - "type": "link", - "path": "/commerce-modules/tax/examples", - "title": "Examples", - "children": [] + "type": "separator" }, { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", "title": "Concepts", + "initialOpen": false, "children": [ { "loaded": true, @@ -12298,8 +12294,11 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "sub-category", - "title": "Guides", + "type": "category", + "title": "Server Guides", + "autogenerate_tags": "server+tax", + "initialOpen": false, + "autogenerate_as_ref": true, "children": [ { "loaded": true, @@ -12308,14 +12307,288 @@ export const generatedSidebar = [ "path": "/references/tax/provider", "title": "Tax Provider Reference", "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Get Variant Price with Taxes", + "path": "/commerce-modules/product/guides/price-with-taxes", + "children": [] } ] }, { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", + "title": "Storefront Guides", + "autogenerate_tags": "storefront+tax", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Example: Show Price with Taxes", + "path": "/storefront-development/products/price/examples/tax-price", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Workflows", + "autogenerate_tags": "workflow+tax", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createCartWorkflow", + "path": "/references/medusa-workflows/createCartWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateTaxLinesWorkflow", + "path": "/references/medusa-workflows/updateTaxLinesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createClaimShippingMethodWorkflow", + "path": "/references/medusa-workflows/createClaimShippingMethodWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createExchangeShippingMethodWorkflow", + "path": "/references/medusa-workflows/createExchangeShippingMethodWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createOrderEditShippingMethodWorkflow", + "path": "/references/medusa-workflows/createOrderEditShippingMethodWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createOrderWorkflow", + "path": "/references/medusa-workflows/createOrderWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createReturnShippingMethodWorkflow", + "path": "/references/medusa-workflows/createReturnShippingMethodWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderClaimAddNewItemWorkflow", + "path": "/references/medusa-workflows/orderClaimAddNewItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderEditAddNewItemWorkflow", + "path": "/references/medusa-workflows/orderEditAddNewItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "orderExchangeAddNewItemWorkflow", + "path": "/references/medusa-workflows/orderExchangeAddNewItemWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateOrderTaxLinesWorkflow", + "path": "/references/medusa-workflows/updateOrderTaxLinesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createTaxRateRulesWorkflow", + "path": "/references/medusa-workflows/createTaxRateRulesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createTaxRatesWorkflow", + "path": "/references/medusa-workflows/createTaxRatesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createTaxRegionsWorkflow", + "path": "/references/medusa-workflows/createTaxRegionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteTaxRateRulesWorkflow", + "path": "/references/medusa-workflows/deleteTaxRateRulesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteTaxRatesWorkflow", + "path": "/references/medusa-workflows/deleteTaxRatesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteTaxRegionsWorkflow", + "path": "/references/medusa-workflows/deleteTaxRegionsWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "setTaxRateRulesWorkflow", + "path": "/references/medusa-workflows/setTaxRateRulesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateTaxRatesWorkflow", + "path": "/references/medusa-workflows/updateTaxRatesWorkflow", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Steps", + "autogenerate_tags": "step+tax", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createTaxRateRulesStep", + "path": "/references/medusa-workflows/steps/createTaxRateRulesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createTaxRatesStep", + "path": "/references/medusa-workflows/steps/createTaxRatesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createTaxRegionsStep", + "path": "/references/medusa-workflows/steps/createTaxRegionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteTaxRateRulesStep", + "path": "/references/medusa-workflows/steps/deleteTaxRateRulesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteTaxRatesStep", + "path": "/references/medusa-workflows/steps/deleteTaxRatesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteTaxRegionsStep", + "path": "/references/medusa-workflows/steps/deleteTaxRegionsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "getItemTaxLinesStep", + "path": "/references/medusa-workflows/steps/getItemTaxLinesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "listTaxRateRuleIdsStep", + "path": "/references/medusa-workflows/steps/listTaxRateRuleIdsStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateTaxRatesStep", + "path": "/references/medusa-workflows/steps/updateTaxRatesStep", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", "title": "References", + "initialOpen": false, "children": [ { "loaded": true, diff --git a/www/apps/resources/sidebars/tax.mjs b/www/apps/resources/sidebars/tax.mjs index 59f30262f0eb8..0aaea5b753369 100644 --- a/www/apps/resources/sidebars/tax.mjs +++ b/www/apps/resources/sidebars/tax.mjs @@ -16,13 +16,12 @@ export const taxSidebar = [ title: "Module Options", }, { - type: "link", - path: "/commerce-modules/tax/examples", - title: "Examples", + type: "separator", }, { - type: "sub-category", + type: "category", title: "Concepts", + initialOpen: false, children: [ { type: "link", @@ -42,8 +41,11 @@ export const taxSidebar = [ ], }, { - type: "sub-category", - title: "Guides", + type: "category", + title: "Server Guides", + autogenerate_tags: "server+tax", + initialOpen: false, + autogenerate_as_ref: true, children: [ { type: "link", @@ -53,8 +55,44 @@ export const taxSidebar = [ ], }, { - type: "sub-category", + type: "category", + title: "Storefront Guides", + autogenerate_tags: "storefront+tax", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Admin Guides", + autogenerate_tags: "admin+tax", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "User Guides", + autogenerate_tags: "userGuides+tax", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Workflows", + autogenerate_tags: "workflow+tax", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Steps", + autogenerate_tags: "step+tax", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", title: "References", + initialOpen: false, children: [ { type: "link", diff --git a/www/packages/tags/src/tags/index.ts b/www/packages/tags/src/tags/index.ts index aa13b7c863585..9af0f705034ba 100644 --- a/www/packages/tags/src/tags/index.ts +++ b/www/packages/tags/src/tags/index.ts @@ -1,32 +1,32 @@ export * from "./product.js" +export * from "./query.js" export * from "./storefront.js" -export * from "./payment.js" -export * from "./pricing.js" export * from "./cart.js" +export * from "./payment.js" +export * from "./order.js" export * from "./stripe.js" export * from "./fulfillment.js" -export * from "./order.js" -export * from "./query.js" -export * from "./tax.js" export * from "./server.js" -export * from "./inventory.js" -export * from "./publishable-api-key.js" -export * from "./api-key.js" +export * from "./auth.js" export * from "./product-collection.js" -export * from "./region.js" +export * from "./product-category.js" +export * from "./tax.js" +export * from "./api-key.js" +export * from "./pricing.js" export * from "./sales-channel.js" +export * from "./customer.js" +export * from "./inventory.js" export * from "./step.js" -export * from "./product-category.js" -export * from "./auth.js" -export * from "./remote-query.js" -export * from "./workflow.js" +export * from "./region.js" export * from "./remote-link.js" -export * from "./event-bus.js" -export * from "./customer.js" +export * from "./publishable-api-key.js" +export * from "./promotion.js" export * from "./store.js" +export * from "./event-bus.js" +export * from "./workflow.js" +export * from "./remote-query.js" +export * from "./locking.js" export * from "./logger.js" +export * from "./user.js" export * from "./file.js" export * from "./stock-location.js" -export * from "./locking.js" -export * from "./promotion.js" -export * from "./user.js" From 5e89744688a8e75ba4911c924a4bf09933ed2aad Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Wed, 25 Dec 2024 18:27:22 +0200 Subject: [PATCH 20/21] revise user module --- .../app/commerce-modules/tax/page.mdx | 2 +- .../commerce-modules/user/examples/page.mdx | 384 ------------------ .../app/commerce-modules/user/page.mdx | 198 +++++---- www/apps/resources/generated/edit-dates.mjs | 5 +- www/apps/resources/generated/files-map.mjs | 4 - www/apps/resources/generated/sidebar.mjs | 167 +++++++- www/apps/resources/sidebars/user.mjs | 49 ++- www/packages/tags/src/tags/index.ts | 36 +- 8 files changed, 349 insertions(+), 496 deletions(-) delete mode 100644 www/apps/resources/app/commerce-modules/user/examples/page.mdx diff --git a/www/apps/resources/app/commerce-modules/tax/page.mdx b/www/apps/resources/app/commerce-modules/tax/page.mdx index a8b0bfa15c1e1..76d079d453336 100644 --- a/www/apps/resources/app/commerce-modules/tax/page.mdx +++ b/www/apps/resources/app/commerce-modules/tax/page.mdx @@ -66,7 +66,7 @@ const createTaxRegionStep = createStep( export const createTaxRegionWorkflow = createWorkflow( "create-tax-region", () => { - const { taxRegion } = await createTaxRegionStep() + const { taxRegion } = createTaxRegionStep() return new WorkflowResponse({ taxRegion }) } diff --git a/www/apps/resources/app/commerce-modules/user/examples/page.mdx b/www/apps/resources/app/commerce-modules/user/examples/page.mdx deleted file mode 100644 index 4cc7c3b573485..0000000000000 --- a/www/apps/resources/app/commerce-modules/user/examples/page.mdx +++ /dev/null @@ -1,384 +0,0 @@ -import { CodeTabs, CodeTab } from "docs-ui" - -export const metadata = { - title: `Examples of the User Module`, -} - -# {metadata.title} - -In this guide, you’ll find common examples of how you can use the User Module in your application. - - - -You should only use the User Module's main service when implementing complex customizations. For common cases, check out [available workflows instead](../../../medusa-workflows-reference/page.mdx). - - - -## Create a User - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const userModuleService = req.scope.resolve( - Modules.USER - ) - - const user = await userModuleService.createUsers({ - email: "user@example.com", - first_name: "John", - last_name: "Smith", - }) - - res.json({ user }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeUserModule } from "@medusajs/medusa/user" - -export async function POST(request: Request) { - const userModuleService = await initializeUserModule() - - const user = await userModuleService.createUsers({ - email: "user@example.com", - first_name: "John", - last_name: "Smith", - }) - - return NextResponse.json({ - user, - }) -} -``` - - - - ---- - -## List Users - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function GET( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const userModuleService = req.scope.resolve( - Modules.USER - ) - - res.json({ - users: await userModuleService.listUsers(), - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeUserModule } from "@medusajs/medusa/user" - -export async function GET(request: Request) { - const userModuleService = await initializeUserModule() - - return NextResponse.json({ - users: await userModuleService.listUsers(), - }) -} -``` - - - - ---- - -## Update a User - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const userModuleService = req.scope.resolve( - Modules.USER - ) - - const user = await userModuleService.updateUsers({ - id: "user_123", - last_name: "Smith", - }) - - res.json({ user }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeUserModule } from "@medusajs/medusa/user" - -export async function POST(request: Request) { - const userModuleService = await initializeUserModule() - - const user = await userModuleService.updateUsers({ - id: "user_123", - last_name: "Smith", - }) - - return NextResponse.json({ - user, - }) -} -``` - - - - ---- - -## Delete a User - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function DELETE( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const userModuleService = req.scope.resolve( - Modules.USER - ) - - await userModuleService.deleteUsers(["user_123"]) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeUserModule } from "@medusajs/medusa/user" - -export async function DELETE(request: Request) { - const userModuleService = await initializeUserModule() - - await userModuleService.deleteUsers(["user_123"]) -} -``` - - - - ---- - -## Invite User - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const userModuleService = req.scope.resolve( - Modules.USER - ) - - const invite = await userModuleService.createInvites({ - email: "user2@example.com", - }) - - res.json({ - invite, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeUserModule } from "@medusajs/medusa/user" - -export async function POST(request: Request, { params }: ContextType) { - const userModuleService = await initializeUserModule() - - const invite = await userModuleService.createInvites({ - email: "user2@example.com", - }) - - return NextResponse.json({ - invite, - }) -} -``` - - - - ---- - -## Accept Invite - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const userModuleService = req.scope.resolve( - Modules.USER - ) - - const invite = await userModuleService.validateInviteToken("secret_123") - - const user = await userModuleService.createUsers({ - email: invite.email, - metadata: invite.metadata, - }) - - await userModuleService.updateInvites({ - id: invite.id, - accepted: true, - }) - - res.json({ - user, - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeUserModule } from "@medusajs/medusa/user" - -export async function POST(request: Request, { params }: ContextType) { - const userModuleService = await initializeUserModule() - - const invite = await userModuleService.validateInviteToken("secret_123") - - const user = await userModuleService.createUsers({ - email: invite.email, - metadata: invite.metadata, - }) - - await userModuleService.updateInvites({ - id: invite.id, - accepted: true, - }) - - return NextResponse.json({ - user, - }) -} -``` - - - - ---- - -## Refresh Invite - - - - -```ts -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" - -export async function POST( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const userModuleService = req.scope.resolve( - Modules.USER - ) - - const invites = await userModuleService.refreshInviteTokens(["invite_123"]) - - res.json({ - invite: invites[0], - }) -} -``` - - - - -```ts -import { NextResponse } from "next/server" - -import { initialize as initializeUserModule } from "@medusajs/medusa/user" - -export async function POST(request: Request, { params }: ContextType) { - const userModuleService = await initializeUserModule() - - const invites = await userModuleService.refreshInviteTokens(["invite_123"]) - - return NextResponse.json({ - invite: invites[0], - }) -} -``` - - - - ---- - -## More Examples - -The [User Module's main service reference](/references/user) provides a reference to all the methods available for use with examples for each. diff --git a/www/apps/resources/app/commerce-modules/user/page.mdx b/www/apps/resources/app/commerce-modules/user/page.mdx index bdbb39bfecd6f..69f661d640cca 100644 --- a/www/apps/resources/app/commerce-modules/user/page.mdx +++ b/www/apps/resources/app/commerce-modules/user/page.mdx @@ -6,101 +6,157 @@ export const metadata = { # {metadata.title} -The User Module provides user-related features in your Medusa and Node.js applications. +In this section of the documentation, you will find resources to learn more about the User Module and how to use it in your application. -## How to Use User Module's Service +Medusa has user related features available out-of-the-box through the User Module. A [module](!docs!/learn/fundamentals/modules) is a standalone package that provides features for a single domain. Each of Medusa's commerce features are placed in commerce modules, such as this User Module. -You can use the User Module's main service by resolving from the Medusa container the resource `Modules.USER`. + -For example: +Learn more about why modules are isolated in [this documentation](!docs!/learn/fundamentals/modules/isolation). - - + -```ts title="src/workflows/hello-world/step1.ts" -import { createStep } from "@medusajs/framework/workflows-sdk" -import { Modules } from "@medusajs/framework/utils" +## User Features -const step1 = createStep("step-1", async (_, { container }) => { - const userModuleService = container.resolve( - Modules.USER - ) +- [User Management](./user-creation-flows/page.mdx): Store and manage users in your store. +- [Invite Users](./user-creation-flows/page.mdx#invite-users): Invite users to join your store and manage those invites. - const users = await userModuleService.listUsers() -}) -``` +--- - - +## How to Use User Module's Service -```ts title="src/api/store/custom/route.ts" -import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http" -import { Modules } from "@medusajs/framework/utils" +In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism. -export async function GET( - req: MedusaRequest, - res: MedusaResponse -): Promise { - const userModuleService = req.scope.resolve( - Modules.USER - ) - - res.json({ - users: await userModuleService.listUsers(), - }) -} -``` +You can build custom workflows and steps. You can also re-use Medusa's workflows and steps, which are provided by the `@medusajs/medusa/core-flows` package. - - +For example: -```ts title="src/subscribers/custom-handler.ts" -import { SubscriberArgs } from "@medusajs/framework" +export const highlights = [ + ["12", "Modules.USER", "Resolve the module in a step."] +] + +```ts title="src/workflows/create-user.ts" highlights={highlights} +import { + createWorkflow, + WorkflowResponse, + createStep, + StepResponse, +} from "@medusajs/framework/workflows-sdk" import { Modules } from "@medusajs/framework/utils" -export default async function subscriberHandler({ container }: SubscriberArgs) { - const userModuleService = container.resolve( - Modules.USER - ) - - const users = await userModuleService.listUsers() -} +const createUserStep = createStep( + "create-user", + async ({}, { container }) => { + const userModuleService = container.resolve(Modules.USER) + + const user = await userModuleService.createUsers({ + email: "user@example.com", + first_name: "John", + last_name: "Smith", + }) + + return new StepResponse({ user }, user.id) + }, + async (userId, { container }) => { + const userModuleService = container.resolve(Modules.USER) + + await userModuleService.deleteUsers([userId]) + } +) + +export const createUserWorkflow = createWorkflow( + "create-user", + () => { + const { user } = createUserStep() + + return new WorkflowResponse({ + user, + }) + } +) ``` - - - ---- +You can then execute the workflow in your custom API routes, scheduled jobs, or subscribers: -## Features + + + + ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import type { + MedusaRequest, + MedusaResponse, + } from "@medusajs/framework/http" + import { createUserWorkflow } from "../../workflows/create-user" + + export async function GET( + req: MedusaRequest, + res: MedusaResponse + ) { + const { result } = await createUserWorkflow(req.scope) + .run() + + res.send(result) + } + ``` -### User Management + + + + ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" + import { + type SubscriberConfig, + type SubscriberArgs, + } from "@medusajs/framework" + import { createUserWorkflow } from "../workflows/create-user" + + export default async function handleUserCreated({ + event: { data }, + container, + }: SubscriberArgs<{ id: string }>) { + const { result } = await createUserWorkflow(container) + .run() + + console.log(result) + } + + export const config: SubscriberConfig = { + event: "user.created", + } + ``` -Manage and store your users through Create, Read, Update, and Delete (CRUD) operations: + + + + ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} + import { MedusaContainer } from "@medusajs/framework/types" + import { createUserWorkflow } from "../workflows/create-user" + + export default async function myCustomJob( + container: MedusaContainer + ) { + const { result } = await createUserWorkflow(container) + .run() + + console.log(result) + } + + export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, + }; + ``` -```ts -const user = await userModuleService.createUsers({ - email: "user@example.com", - first_name: "John", - last_name: "Smith", -}) -``` + + -### Invite Users +Learn more about workflows in [this documentation](!docs!/learn/fundamentals/workflows). -Invite users to join your store and manage those invites, with expiry and revalidation features. +--- -```ts -const invite = await userModuleService.createInvites({ - email: "user2@example.com", -}) +## Configure User Module -// refresh token later -await userModuleService.refreshInviteTokens([invite.id]) -``` +The User Module accepts options for further configurations. Refer to [this documentation](./module-options/page.mdx) for details on the module's options. --- -## Configure User Module - -Refer to [this documentation](./module-options/page.mdx) for details on the module's options. + \ No newline at end of file diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index 430dc322d2c91..a1d907577b574 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -92,13 +92,12 @@ export const generatedEditDates = { "app/commerce-modules/tax/tax-calculation-with-provider/page.mdx": "2024-10-15T14:43:00.700Z", "app/commerce-modules/tax/tax-rates-and-rules/page.mdx": "2024-10-15T14:38:06.889Z", "app/commerce-modules/tax/tax-region/page.mdx": "2024-10-15T14:36:47.028Z", - "app/commerce-modules/tax/page.mdx": "2024-12-25T16:17:00.782Z", + "app/commerce-modules/tax/page.mdx": "2024-12-25T16:22:51.953Z", "app/commerce-modules/user/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/user/_events/page.mdx": "2024-07-03T19:27:13+03:00", - "app/commerce-modules/user/examples/page.mdx": "2024-10-15T15:00:59.626Z", "app/commerce-modules/user/module-options/page.mdx": "2024-09-30T08:43:53.171Z", "app/commerce-modules/user/user-creation-flows/page.mdx": "2024-10-15T14:51:37.311Z", - "app/commerce-modules/user/page.mdx": "2024-12-09T14:48:54.225Z", + "app/commerce-modules/user/page.mdx": "2024-12-25T16:24:26.837Z", "app/commerce-modules/page.mdx": "2024-12-23T14:38:21.064Z", "app/contribution-guidelines/docs/page.mdx": "2024-12-12T11:06:12.250Z", "app/create-medusa-app/page.mdx": "2024-08-05T11:10:55+03:00", diff --git a/www/apps/resources/generated/files-map.mjs b/www/apps/resources/generated/files-map.mjs index 4cf58ac9ca177..f925a51426636 100644 --- a/www/apps/resources/generated/files-map.mjs +++ b/www/apps/resources/generated/files-map.mjs @@ -583,10 +583,6 @@ export const filesMap = [ "filePath": "/www/apps/resources/app/commerce-modules/user/events/page.mdx", "pathname": "/commerce-modules/user/events" }, - { - "filePath": "/www/apps/resources/app/commerce-modules/user/examples/page.mdx", - "pathname": "/commerce-modules/user/examples" - }, { "filePath": "/www/apps/resources/app/commerce-modules/user/module-options/page.mdx", "pathname": "/commerce-modules/user/module-options" diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs index 1661bf282dfe3..63d27ae864a44 100644 --- a/www/apps/resources/generated/sidebar.mjs +++ b/www/apps/resources/generated/sidebar.mjs @@ -12866,18 +12866,16 @@ export const generatedSidebar = [ "children": [] }, { - "loaded": true, - "isPathHref": true, - "type": "link", - "path": "/commerce-modules/user/examples", - "title": "Examples", - "children": [] + "type": "separator" }, { "loaded": true, "isPathHref": true, - "type": "sub-category", - "title": "Guides", + "type": "category", + "title": "Server Guides", + "autogenerate_tags": "server+user", + "initialOpen": false, + "autogenerate_as_ref": true, "children": [ { "loaded": true, @@ -12892,8 +12890,159 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "type": "sub-category", + "type": "category", + "title": "Workflows", + "autogenerate_tags": "workflow+user", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "acceptInviteWorkflow", + "path": "/references/medusa-workflows/acceptInviteWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createInvitesWorkflow", + "path": "/references/medusa-workflows/createInvitesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteInvitesWorkflow", + "path": "/references/medusa-workflows/deleteInvitesWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "refreshInviteTokensWorkflow", + "path": "/references/medusa-workflows/refreshInviteTokensWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createUserAccountWorkflow", + "path": "/references/medusa-workflows/createUserAccountWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createUsersWorkflow", + "path": "/references/medusa-workflows/createUsersWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteUsersWorkflow", + "path": "/references/medusa-workflows/deleteUsersWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "removeUserAccountWorkflow", + "path": "/references/medusa-workflows/removeUserAccountWorkflow", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateUsersWorkflow", + "path": "/references/medusa-workflows/updateUsersWorkflow", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", + "title": "Steps", + "autogenerate_tags": "step+user", + "initialOpen": false, + "autogenerate_as_ref": true, + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createInviteStep", + "path": "/references/medusa-workflows/steps/createInviteStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteInvitesStep", + "path": "/references/medusa-workflows/steps/deleteInvitesStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "refreshInviteTokensStep", + "path": "/references/medusa-workflows/steps/refreshInviteTokensStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "validateTokenStep", + "path": "/references/medusa-workflows/steps/validateTokenStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "createUsersStep", + "path": "/references/medusa-workflows/steps/createUsersStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "deleteUsersStep", + "path": "/references/medusa-workflows/steps/deleteUsersStep", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "updateUsersStep", + "path": "/references/medusa-workflows/steps/updateUsersStep", + "children": [] + } + ] + }, + { + "loaded": true, + "isPathHref": true, + "type": "category", "title": "References", + "initialOpen": false, "children": [ { "loaded": true, diff --git a/www/apps/resources/sidebars/user.mjs b/www/apps/resources/sidebars/user.mjs index 7bd33cbc12a8a..a8144829a4bbc 100644 --- a/www/apps/resources/sidebars/user.mjs +++ b/www/apps/resources/sidebars/user.mjs @@ -16,13 +16,14 @@ export const userSidebar = [ title: "Module Options", }, { - type: "link", - path: "/commerce-modules/user/examples", - title: "Examples", + type: "separator", }, { - type: "sub-category", - title: "Guides", + type: "category", + title: "Server Guides", + autogenerate_tags: "server+user", + initialOpen: false, + autogenerate_as_ref: true, children: [ { type: "link", @@ -32,8 +33,44 @@ export const userSidebar = [ ], }, { - type: "sub-category", + type: "category", + title: "Storefront Guides", + autogenerate_tags: "storefront+user", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Admin Guides", + autogenerate_tags: "admin+user", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "User Guides", + autogenerate_tags: "userGuides+user", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Workflows", + autogenerate_tags: "workflow+user", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", + title: "Steps", + autogenerate_tags: "step+user", + initialOpen: false, + autogenerate_as_ref: true, + }, + { + type: "category", title: "References", + initialOpen: false, children: [ { type: "link", diff --git a/www/packages/tags/src/tags/index.ts b/www/packages/tags/src/tags/index.ts index 9af0f705034ba..88d36d1db676d 100644 --- a/www/packages/tags/src/tags/index.ts +++ b/www/packages/tags/src/tags/index.ts @@ -1,32 +1,32 @@ export * from "./product.js" -export * from "./query.js" +export * from "./server.js" export * from "./storefront.js" -export * from "./cart.js" export * from "./payment.js" +export * from "./cart.js" export * from "./order.js" export * from "./stripe.js" export * from "./fulfillment.js" -export * from "./server.js" -export * from "./auth.js" -export * from "./product-collection.js" -export * from "./product-category.js" -export * from "./tax.js" -export * from "./api-key.js" -export * from "./pricing.js" -export * from "./sales-channel.js" export * from "./customer.js" +export * from "./tax.js" export * from "./inventory.js" -export * from "./step.js" +export * from "./pricing.js" +export * from "./api-key.js" +export * from "./query.js" +export * from "./publishable-api-key.js" +export * from "./auth.js" export * from "./region.js" +export * from "./product-collection.js" export * from "./remote-link.js" -export * from "./publishable-api-key.js" +export * from "./workflow.js" +export * from "./sales-channel.js" +export * from "./product-category.js" +export * from "./step.js" export * from "./promotion.js" -export * from "./store.js" export * from "./event-bus.js" -export * from "./workflow.js" -export * from "./remote-query.js" -export * from "./locking.js" -export * from "./logger.js" -export * from "./user.js" +export * from "./store.js" export * from "./file.js" export * from "./stock-location.js" +export * from "./locking.js" +export * from "./user.js" +export * from "./remote-query.js" +export * from "./logger.js" From 69bfbf640e03a6e5258612dc27b3d2a82a59609a Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Thu, 26 Dec 2024 10:08:36 +0200 Subject: [PATCH 21/21] lint content + fix snippets --- .../api-key/links-to-other-modules/page.mdx | 8 +- .../app/commerce-modules/api-key/page.mdx | 112 +++++++-------- .../app/commerce-modules/auth/page.mdx | 20 ++- .../cart/links-to-other-modules/page.mdx | 56 ++++---- .../app/commerce-modules/cart/page.mdx | 107 +++++++------- .../currency/links-to-other-modules/page.mdx | 8 +- .../app/commerce-modules/currency/page.mdx | 132 +++++++++--------- .../customer/links-to-other-modules/page.mdx | 16 +-- .../app/commerce-modules/customer/page.mdx | 109 ++++++++------- .../links-to-other-modules/page.mdx | 24 ++-- .../app/commerce-modules/fulfillment/page.mdx | 107 +++++++------- .../inventory/links-to-other-modules/page.mdx | 16 +-- .../app/commerce-modules/inventory/page.mdx | 107 +++++++------- .../order/links-to-other-modules/page.mdx | 64 ++++----- .../app/commerce-modules/order/page.mdx | 109 ++++++++------- .../payment/links-to-other-modules/page.mdx | 24 ++-- .../app/commerce-modules/payment/page.mdx | 107 +++++++------- .../pricing/links-to-other-modules/page.mdx | 16 +-- .../app/commerce-modules/pricing/page.mdx | 107 +++++++------- .../product/links-to-other-modules/page.mdx | 40 +++--- .../app/commerce-modules/product/page.mdx | 107 +++++++------- .../promotion/links-to-other-modules/page.mdx | 16 +-- .../app/commerce-modules/promotion/page.mdx | 109 ++++++++------- .../region/links-to-other-modules/page.mdx | 24 ++-- .../app/commerce-modules/region/page.mdx | 107 +++++++------- .../links-to-other-modules/page.mdx | 40 +++--- .../commerce-modules/sales-channel/page.mdx | 111 ++++++++------- .../links-to-other-modules/page.mdx | 24 ++-- .../commerce-modules/stock-location/page.mdx | 107 +++++++------- .../store/links-to-other-modules/page.mdx | 8 +- .../app/commerce-modules/store/page.mdx | 112 ++++++++------- .../app/commerce-modules/tax/page.mdx | 107 +++++++------- .../app/commerce-modules/user/page.mdx | 107 +++++++------- 33 files changed, 1162 insertions(+), 1106 deletions(-) diff --git a/www/apps/resources/app/commerce-modules/api-key/links-to-other-modules/page.mdx b/www/apps/resources/app/commerce-modules/api-key/links-to-other-modules/page.mdx index ed4bc382efc22..43a4548efb134 100644 --- a/www/apps/resources/app/commerce-modules/api-key/links-to-other-modules/page.mdx +++ b/www/apps/resources/app/commerce-modules/api-key/links-to-other-modules/page.mdx @@ -37,8 +37,8 @@ To retrieve the sales channels of an API key with [Query](!docs!/learn/fundament const { data: apiKeys } = await query.graph({ entity: "api_key", fields: [ - "sales_channels.*" - ] + "sales_channels.*", + ], }) // apiKeys.sales_channels @@ -55,8 +55,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: apiKeys } = useQueryGraphStep({ entity: "api_key", fields: [ - "sales_channels.*" - ] + "sales_channels.*", + ], }) // apiKeys.sales_channels diff --git a/www/apps/resources/app/commerce-modules/api-key/page.mdx b/www/apps/resources/app/commerce-modules/api-key/page.mdx index 6c13ea825fd4d..79811aa0b404a 100644 --- a/www/apps/resources/app/commerce-modules/api-key/page.mdx +++ b/www/apps/resources/app/commerce-modules/api-key/page.mdx @@ -83,70 +83,70 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import type { - MedusaRequest, - MedusaResponse, - } from "@medusajs/framework/http" - import {createApiKeyWorkflow} from "../../workflows/create-api-key" - - export async function GET( - req: MedusaRequest, - res: MedusaResponse - ) { - const { result } = await createApiKeyWorkflow(req.scope) - .run() - - res.send(result) - } - ``` +```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import type { + MedusaRequest, + MedusaResponse, +} from "@medusajs/framework/http" +import { createApiKeyWorkflow } from "../../workflows/create-api-key" + +export async function GET( + req: MedusaRequest, + res: MedusaResponse +) { + const { result } = await createApiKeyWorkflow(req.scope) + .run() + + res.send(result) +} +``` - ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import { - type SubscriberConfig, - type SubscriberArgs, - } from "@medusajs/framework" - import {createApiKeyWorkflow} from "../workflows/create-api-key" - - export default async function handleUserCreated({ - event: { data }, - container, - }: SubscriberArgs<{ id: string }>) { - const { result } = await createApiKeyWorkflow(container) - .run() - - console.log(result) - } - - export const config: SubscriberConfig = { - event: "user.created", - } - ``` +```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import { + type SubscriberConfig, + type SubscriberArgs, +} from "@medusajs/framework" +import { createApiKeyWorkflow } from "../workflows/create-api-key" + +export default async function handleUserCreated({ + event: { data }, + container, +}: SubscriberArgs<{ id: string }>) { + const { result } = await createApiKeyWorkflow(container) + .run() + + console.log(result) +} + +export const config: SubscriberConfig = { + event: "user.created", +} +``` - ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} - import { MedusaContainer } from "@medusajs/framework/types" - import {createApiKeyWorkflow} from "../workflows/create-api-key" - - export default async function myCustomJob( - container: MedusaContainer - ) { - const { result } = await createApiKeyWorkflow(container) - .run() - - console.log(result) - } - - export const config = { - name: "run-once-a-day", - schedule: `0 0 * * *`, - }; - ``` +```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} +import { MedusaContainer } from "@medusajs/framework/types" +import { createApiKeyWorkflow } from "../workflows/create-api-key" + +export default async function myCustomJob( + container: MedusaContainer +) { + const { result } = await createApiKeyWorkflow(container) + .run() + + console.log(result) +} + +export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, +} +``` diff --git a/www/apps/resources/app/commerce-modules/auth/page.mdx b/www/apps/resources/app/commerce-modules/auth/page.mdx index 44ae30923e4cb..c80d7f266dd1e 100644 --- a/www/apps/resources/app/commerce-modules/auth/page.mdx +++ b/www/apps/resources/app/commerce-modules/auth/page.mdx @@ -34,7 +34,7 @@ You can build custom workflows and steps. You can also re-use Medusa's workflows For example: export const highlights = [ - ["17", "Modules.AUTH", "Resolve the module in a step."] + ["18", "Modules.AUTH", "Resolve the module in a step."] ] ```ts title="src/workflows/authenticate-user.ts" highlights={highlights} @@ -46,6 +46,7 @@ import { } from "@medusajs/framework/workflows-sdk" import { Modules, MedusaError } from "@medusajs/framework/utils" import { MedusaRequest } from "@medusajs/framework/http" +import { AuthenticationInput } from "@medusajs/framework/types" type Input = { req: MedusaRequest @@ -66,17 +67,24 @@ const authenticateUserStep = createStep( body: req.body, authScope: "admin", // or custom actor type protocol: req.protocol, - } + } as AuthenticationInput ) if (!success) { // incorrect authentication details - throw new MedusaError(error) + throw new MedusaError( + MedusaError.Types.UNAUTHORIZED, + error || "Incorrect authentication details" + ) } - return new StepResponse({ authIdentity }, authIdentity.id) + return new StepResponse({ authIdentity }, authIdentity?.id) }, async (authIdentityId, { container }) => { + if (!authIdentityId) { + return + } + const authModuleService = container.resolve(Modules.AUTH) await authModuleService.deleteAuthIdentities([authIdentityId]) @@ -102,7 +110,7 @@ import type { MedusaRequest, MedusaResponse, } from "@medusajs/framework/http" -import {authenticateUserWorkflow} from "../../workflows/authenticate-user" +import { authenticateUserWorkflow } from "../../workflows/authenticate-user" export async function GET( req: MedusaRequest, @@ -110,7 +118,7 @@ export async function GET( ) { const { result } = await authenticateUserWorkflow(req.scope) .run({ - req + req, }) res.send(result) diff --git a/www/apps/resources/app/commerce-modules/cart/links-to-other-modules/page.mdx b/www/apps/resources/app/commerce-modules/cart/links-to-other-modules/page.mdx index 341ec6d153eb9..aa23a8ca90aa7 100644 --- a/www/apps/resources/app/commerce-modules/cart/links-to-other-modules/page.mdx +++ b/www/apps/resources/app/commerce-modules/cart/links-to-other-modules/page.mdx @@ -44,8 +44,8 @@ To retrieve the customer of a cart with [Query](!docs!/learn/fundamentals/module const { data: carts } = await query.graph({ entity: "cart", fields: [ - "customer.*" - ] + "customer.*", + ], }) // carts.order @@ -62,8 +62,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: carts } = useQueryGraphStep({ entity: "cart", fields: [ - "customer.*" - ] + "customer.*", + ], }) // carts.order @@ -93,8 +93,8 @@ To retrieve the order of a cart with [Query](!docs!/learn/fundamentals/module-li const { data: carts } = await query.graph({ entity: "cart", fields: [ - "order.*" - ] + "order.*", + ], }) // carts.order @@ -111,8 +111,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: carts } = useQueryGraphStep({ entity: "cart", fields: [ - "order.*" - ] + "order.*", + ], }) // carts.order @@ -186,8 +186,8 @@ To retrieve the payment collection of a cart with [Query](!docs!/learn/fundament const { data: carts } = await query.graph({ entity: "cart", fields: [ - "payment_collection.*" - ] + "payment_collection.*", + ], }) // carts.payment_collection @@ -204,8 +204,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: carts } = useQueryGraphStep({ entity: "cart", fields: [ - "payment_collection.*" - ] + "payment_collection.*", + ], }) // carts.payment_collection @@ -283,8 +283,8 @@ To retrieve the product, pass `product.*` in `fields`. const { data: lineItems } = await query.graph({ entity: "line_item", fields: [ - "variant.*" - ] + "variant.*", + ], }) // lineItems.variant @@ -301,8 +301,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: lineItems } = useQueryGraphStep({ entity: "line_item", fields: [ - "variant.*" - ] + "variant.*", + ], }) // lineItems.variant @@ -340,8 +340,8 @@ To retrieve the promotion of a line item adjustment, pass `promotion.*` in `fiel const { data: carts } = await query.graph({ entity: "cart", fields: [ - "promotions.*" - ] + "promotions.*", + ], }) // carts.promotions @@ -358,8 +358,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: carts } = useQueryGraphStep({ entity: "cart", fields: [ - "promotions.*" - ] + "promotions.*", + ], }) // carts.promotions @@ -429,8 +429,8 @@ To retrieve the region of a cart with [Query](!docs!/learn/fundamentals/module-l const { data: carts } = await query.graph({ entity: "cart", fields: [ - "region.*" - ] + "region.*", + ], }) // carts.region @@ -447,8 +447,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: carts } = useQueryGraphStep({ entity: "cart", fields: [ - "region.*" - ] + "region.*", + ], }) // carts.region @@ -474,8 +474,8 @@ To retrieve the sales channel of a cart with [Query](!docs!/learn/fundamentals/m const { data: carts } = await query.graph({ entity: "cart", fields: [ - "sales_channel.*" - ] + "sales_channel.*", + ], }) // carts.sales_channel @@ -492,8 +492,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: carts } = useQueryGraphStep({ entity: "cart", fields: [ - "sales_channel.*" - ] + "sales_channel.*", + ], }) // carts.sales_channel diff --git a/www/apps/resources/app/commerce-modules/cart/page.mdx b/www/apps/resources/app/commerce-modules/cart/page.mdx index 5ad6d042e35ed..52231a4ffecd1 100644 --- a/www/apps/resources/app/commerce-modules/cart/page.mdx +++ b/www/apps/resources/app/commerce-modules/cart/page.mdx @@ -69,6 +69,9 @@ const createCartStep = createStep( return new StepResponse({ cart }, cart.id) }, async (cartId, { container }) => { + if (!cartId) { + return + } const cartModuleService = container.resolve(Modules.CART) await cartModuleService.deleteCarts([cartId]) @@ -92,70 +95,70 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import type { - MedusaRequest, - MedusaResponse, - } from "@medusajs/framework/http" - import { createCartWorkflow } from "../../workflows/create-cart" - - export async function GET( - req: MedusaRequest, - res: MedusaResponse - ) { - const { result } = await createCartWorkflow(req.scope) - .run() - - res.send(result) - } - ``` +```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import type { + MedusaRequest, + MedusaResponse, +} from "@medusajs/framework/http" +import { createCartWorkflow } from "../../workflows/create-cart" + +export async function GET( + req: MedusaRequest, + res: MedusaResponse +) { + const { result } = await createCartWorkflow(req.scope) + .run() + + res.send(result) +} +``` - ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import { - type SubscriberConfig, - type SubscriberArgs, - } from "@medusajs/framework" - import { createCartWorkflow } from "../workflows/create-cart" - - export default async function handleUserCreated({ - event: { data }, - container, - }: SubscriberArgs<{ id: string }>) { - const { result } = await createCartWorkflow(container) - .run() - - console.log(result) - } +```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import { + type SubscriberConfig, + type SubscriberArgs, +} from "@medusajs/framework" +import { createCartWorkflow } from "../workflows/create-cart" + +export default async function handleUserCreated({ + event: { data }, + container, +}: SubscriberArgs<{ id: string }>) { + const { result } = await createCartWorkflow(container) + .run() + + console.log(result) +} - export const config: SubscriberConfig = { - event: "user.created", - } - ``` +export const config: SubscriberConfig = { + event: "user.created", +} +``` - ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} - import { MedusaContainer } from "@medusajs/framework/types" - import { createCartWorkflow } from "../workflows/create-cart" +```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} +import { MedusaContainer } from "@medusajs/framework/types" +import { createCartWorkflow } from "../workflows/create-cart" - export default async function myCustomJob( - container: MedusaContainer - ) { - const { result } = await createCartWorkflow(container) - .run() +export default async function myCustomJob( + container: MedusaContainer +) { + const { result } = await createCartWorkflow(container) + .run() - console.log(result) - } + console.log(result) +} - export const config = { - name: "run-once-a-day", - schedule: `0 0 * * *`, - }; - ``` +export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, +} +``` diff --git a/www/apps/resources/app/commerce-modules/currency/links-to-other-modules/page.mdx b/www/apps/resources/app/commerce-modules/currency/links-to-other-modules/page.mdx index 2ea00ee4de647..0cc6da0aecb28 100644 --- a/www/apps/resources/app/commerce-modules/currency/links-to-other-modules/page.mdx +++ b/www/apps/resources/app/commerce-modules/currency/links-to-other-modules/page.mdx @@ -39,8 +39,8 @@ To retrieve the details of a store's currencies with [Query](!docs!/learn/fundam const { data: stores } = await query.graph({ entity: "store", fields: [ - "supported_currencies.currency.*" - ] + "supported_currencies.currency.*", + ], }) // stores.supported_currencies @@ -57,8 +57,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: stores } = useQueryGraphStep({ entity: "store", fields: [ - "supported_currencies.currency.*" - ] + "supported_currencies.currency.*", + ], }) // stores.supported_currencies diff --git a/www/apps/resources/app/commerce-modules/currency/page.mdx b/www/apps/resources/app/commerce-modules/currency/page.mdx index 05bc4845d69fa..511b8aa87e941 100644 --- a/www/apps/resources/app/commerce-modules/currency/page.mdx +++ b/www/apps/resources/app/commerce-modules/currency/page.mdx @@ -41,7 +41,7 @@ import { WorkflowResponse, createStep, StepResponse, - transform + transform, } from "@medusajs/framework/workflows-sdk" import { Modules } from "@medusajs/framework/utils" @@ -53,7 +53,7 @@ const retrieveCurrencyStep = createStep( const currency = await currencyModuleService .retrieveCurrency("usd") - return new StepResponse({ currency }, currency.id) + return new StepResponse({ currency }) } ) @@ -64,11 +64,11 @@ type Input = { export const retrievePriceWithCurrency = createWorkflow( "create-currency", (input: Input) => { - const { currency } = await retrieveCurrencyStep() + const { currency } = retrieveCurrencyStep() const formattedPrice = transform({ input, - currency + currency, }, (data) => { return `${data.currency.symbol}${data.input.price}` }) @@ -85,76 +85,76 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"], ["13"], ["14"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import type { - MedusaRequest, - MedusaResponse, - } from "@medusajs/framework/http" - import {retrievePriceWithCurrency} from "../../workflows/retrieve-price-with-currency" - - export async function GET( - req: MedusaRequest, - res: MedusaResponse - ) { - const { result } = await retrievePriceWithCurrency(req.scope) - .run({ - price: 10 - }) - - res.send(result) - } - ``` +```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"], ["13"], ["14"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import type { + MedusaRequest, + MedusaResponse, +} from "@medusajs/framework/http" +import { retrievePriceWithCurrency } from "../../workflows/retrieve-price-with-currency" + +export async function GET( + req: MedusaRequest, + res: MedusaResponse +) { + const { result } = await retrievePriceWithCurrency(req.scope) + .run({ + price: 10, + }) + + res.send(result) +} +``` - ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"], ["13"], ["14"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import { - type SubscriberConfig, - type SubscriberArgs, - } from "@medusajs/framework" - import {retrievePriceWithCurrency} from "../workflows/retrieve-price-with-currency" - - export default async function handleUserCreated({ - event: { data }, - container, - }: SubscriberArgs<{ id: string }>) { - const { result } = await retrievePriceWithCurrency(container) - .run({ - price: 10 - }) - - console.log(result) - } - - export const config: SubscriberConfig = { - event: "user.created", - } - ``` +```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"], ["13"], ["14"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import { + type SubscriberConfig, + type SubscriberArgs, +} from "@medusajs/framework" +import { retrievePriceWithCurrency } from "../workflows/retrieve-price-with-currency" + +export default async function handleUserCreated({ + event: { data }, + container, +}: SubscriberArgs<{ id: string }>) { + const { result } = await retrievePriceWithCurrency(container) + .run({ + price: 10, + }) + + console.log(result) +} + +export const config: SubscriberConfig = { + event: "user.created", +} +``` - ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"], ["9"], ["10"]]} - import { MedusaContainer } from "@medusajs/framework/types" - import {retrievePriceWithCurrency} from "../workflows/retrieve-price-with-currency" - - export default async function myCustomJob( - container: MedusaContainer - ) { - const { result } = await retrievePriceWithCurrency(container) - .run({ - price: 10 - }) - - console.log(result) - } - - export const config = { - name: "run-once-a-day", - schedule: `0 0 * * *`, - }; - ``` +```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"], ["9"], ["10"]]} +import { MedusaContainer } from "@medusajs/framework/types" +import { retrievePriceWithCurrency } from "../workflows/retrieve-price-with-currency" + +export default async function myCustomJob( + container: MedusaContainer +) { + const { result } = await retrievePriceWithCurrency(container) + .run({ + price: 10, + }) + + console.log(result) +} + +export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, +} +``` diff --git a/www/apps/resources/app/commerce-modules/customer/links-to-other-modules/page.mdx b/www/apps/resources/app/commerce-modules/customer/links-to-other-modules/page.mdx index 7dac5330fe47d..bf91bf2576655 100644 --- a/www/apps/resources/app/commerce-modules/customer/links-to-other-modules/page.mdx +++ b/www/apps/resources/app/commerce-modules/customer/links-to-other-modules/page.mdx @@ -38,8 +38,8 @@ To retrieve a customer's carts with [Query](!docs!/learn/fundamentals/module-lin const { data: customers } = await query.graph({ entity: "customer", fields: [ - "carts.*" - ] + "carts.*", + ], }) // customers.carts @@ -56,8 +56,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: customers } = useQueryGraphStep({ entity: "customer", fields: [ - "carts.*" - ] + "carts.*", + ], }) // customers.carts @@ -83,8 +83,8 @@ To retrieve a customer's orders with [Query](!docs!/learn/fundamentals/module-li const { data: customers } = await query.graph({ entity: "customer", fields: [ - "orders.*" - ] + "orders.*", + ], }) // customers.orders @@ -101,8 +101,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: customers } = useQueryGraphStep({ entity: "customer", fields: [ - "orders.*" - ] + "orders.*", + ], }) // customers.orders diff --git a/www/apps/resources/app/commerce-modules/customer/page.mdx b/www/apps/resources/app/commerce-modules/customer/page.mdx index 7bebcd43b1c7b..a33942b8561a9 100644 --- a/www/apps/resources/app/commerce-modules/customer/page.mdx +++ b/www/apps/resources/app/commerce-modules/customer/page.mdx @@ -58,6 +58,9 @@ const createCustomerStep = createStep( return new StepResponse({ customer }, customer.id) }, async (customerId, { container }) => { + if (!customerId) { + return + } const customerModuleService = container.resolve(Modules.CUSTOMER) await customerModuleService.deleteCustomers([customerId]) @@ -70,7 +73,7 @@ export const createCustomerWorkflow = createWorkflow( const { customer } = createCustomerStep() return new WorkflowResponse({ - customer + customer, }) } ) @@ -81,70 +84,70 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import type { - MedusaRequest, - MedusaResponse, - } from "@medusajs/framework/http" - import {createCustomerWorkflow} from "../../workflows/create-customer" - - export async function GET( - req: MedusaRequest, - res: MedusaResponse - ) { - const { result } = await createCustomerWorkflow(req.scope) - .run() - - res.send(result) - } - ``` +```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import type { + MedusaRequest, + MedusaResponse, +} from "@medusajs/framework/http" +import { createCustomerWorkflow } from "../../workflows/create-customer" + +export async function GET( + req: MedusaRequest, + res: MedusaResponse +) { + const { result } = await createCustomerWorkflow(req.scope) + .run() + + res.send(result) +} +``` - ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import { - type SubscriberConfig, - type SubscriberArgs, - } from "@medusajs/framework" - import {createCustomerWorkflow} from "../workflows/create-customer" - - export default async function handleUserCreated({ - event: { data }, - container, - }: SubscriberArgs<{ id: string }>) { - const { result } = await createCustomerWorkflow(container) - .run() - - console.log(result) - } +```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import { + type SubscriberConfig, + type SubscriberArgs, +} from "@medusajs/framework" +import { createCustomerWorkflow } from "../workflows/create-customer" + +export default async function handleUserCreated({ + event: { data }, + container, +}: SubscriberArgs<{ id: string }>) { + const { result } = await createCustomerWorkflow(container) + .run() + + console.log(result) +} - export const config: SubscriberConfig = { - event: "user.created", - } - ``` +export const config: SubscriberConfig = { + event: "user.created", +} +``` - ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} - import { MedusaContainer } from "@medusajs/framework/types" - import {createCustomerWorkflow} from "../workflows/create-customer" +```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} +import { MedusaContainer } from "@medusajs/framework/types" +import { createCustomerWorkflow } from "../workflows/create-customer" - export default async function myCustomJob( - container: MedusaContainer - ) { - const { result } = await createCustomerWorkflow(container) - .run() +export default async function myCustomJob( + container: MedusaContainer +) { + const { result } = await createCustomerWorkflow(container) + .run() - console.log(result) - } + console.log(result) +} - export const config = { - name: "run-once-a-day", - schedule: `0 0 * * *`, - }; - ``` +export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, +} +``` diff --git a/www/apps/resources/app/commerce-modules/fulfillment/links-to-other-modules/page.mdx b/www/apps/resources/app/commerce-modules/fulfillment/links-to-other-modules/page.mdx index 234ac7d107c3e..0f665358fd597 100644 --- a/www/apps/resources/app/commerce-modules/fulfillment/links-to-other-modules/page.mdx +++ b/www/apps/resources/app/commerce-modules/fulfillment/links-to-other-modules/page.mdx @@ -49,8 +49,8 @@ To retrieve the return, pass `return.*` in `fields`. const { data: fulfillments } = await query.graph({ entity: "fulfillment", fields: [ - "order.*" - ] + "order.*", + ], }) // fulfillments.order @@ -67,8 +67,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: fulfillments } = useQueryGraphStep({ entity: "fulfillment", fields: [ - "order.*" - ] + "order.*", + ], }) // fulfillments.order @@ -142,8 +142,8 @@ To retrieve the price set of a shipping option with [Query](!docs!/learn/fundame const { data: shippingOptions } = await query.graph({ entity: "shipping_option", fields: [ - "price_set.*" - ] + "price_set.*", + ], }) // shippingOptions.price_set @@ -160,8 +160,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: shippingOptions } = useQueryGraphStep({ entity: "shipping_option", fields: [ - "price_set.*" - ] + "price_set.*", + ], }) // shippingOptions.price_set @@ -245,8 +245,8 @@ To retrieve the stock location of a fulfillment provider, pass `locations.*` in const { data: fulfillmentSets } = await query.graph({ entity: "fulfillment_set", fields: [ - "location.*" - ] + "location.*", + ], }) // fulfillmentSets.location @@ -263,8 +263,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: fulfillmentSets } = useQueryGraphStep({ entity: "fulfillment_set", fields: [ - "location.*" - ] + "location.*", + ], }) // fulfillmentSets.location diff --git a/www/apps/resources/app/commerce-modules/fulfillment/page.mdx b/www/apps/resources/app/commerce-modules/fulfillment/page.mdx index 4fd2282e24e00..cfd8c3695ab20 100644 --- a/www/apps/resources/app/commerce-modules/fulfillment/page.mdx +++ b/www/apps/resources/app/commerce-modules/fulfillment/page.mdx @@ -74,6 +74,9 @@ const createFulfillmentStep = createStep( return new StepResponse({ fulfillment }, fulfillment.id) }, async (fulfillmentId, { container }) => { + if (!fulfillmentId) { + return + } const fulfillmentModuleService = container.resolve(Modules.FULFILLMENT) await fulfillmentModuleService.deleteFulfillment(fulfillmentId) @@ -97,70 +100,70 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import type { - MedusaRequest, - MedusaResponse, - } from "@medusajs/framework/http" - import {createFulfillmentWorkflow} from "../../workflows/create-fuilfillment" - - export async function GET( - req: MedusaRequest, - res: MedusaResponse - ) { - const { result } = await createFulfillmentWorkflow(req.scope) - .run() - - res.send(result) - } - ``` +```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import type { + MedusaRequest, + MedusaResponse, +} from "@medusajs/framework/http" +import { createFulfillmentWorkflow } from "../../workflows/create-fuilfillment" + +export async function GET( + req: MedusaRequest, + res: MedusaResponse +) { + const { result } = await createFulfillmentWorkflow(req.scope) + .run() + + res.send(result) +} +``` - ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import { - type SubscriberConfig, - type SubscriberArgs, - } from "@medusajs/framework" - import {createFulfillmentWorkflow} from "../workflows/create-fuilfillment" - - export default async function handleUserCreated({ - event: { data }, - container, - }: SubscriberArgs<{ id: string }>) { - const { result } = await createFulfillmentWorkflow(container) - .run() - - console.log(result) - } +```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import { + type SubscriberConfig, + type SubscriberArgs, +} from "@medusajs/framework" +import { createFulfillmentWorkflow } from "../workflows/create-fuilfillment" + +export default async function handleUserCreated({ + event: { data }, + container, +}: SubscriberArgs<{ id: string }>) { + const { result } = await createFulfillmentWorkflow(container) + .run() + + console.log(result) +} - export const config: SubscriberConfig = { - event: "user.created", - } - ``` +export const config: SubscriberConfig = { + event: "user.created", +} +``` - ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} - import { MedusaContainer } from "@medusajs/framework/types" - import {createFulfillmentWorkflow} from "../workflows/create-fuilfillment" +```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} +import { MedusaContainer } from "@medusajs/framework/types" +import { createFulfillmentWorkflow } from "../workflows/create-fuilfillment" - export default async function myCustomJob( - container: MedusaContainer - ) { - const { result } = await createFulfillmentWorkflow(container) - .run() +export default async function myCustomJob( + container: MedusaContainer +) { + const { result } = await createFulfillmentWorkflow(container) + .run() - console.log(result) - } + console.log(result) +} - export const config = { - name: "run-once-a-day", - schedule: `0 0 * * *`, - }; - ``` +export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, +} +``` diff --git a/www/apps/resources/app/commerce-modules/inventory/links-to-other-modules/page.mdx b/www/apps/resources/app/commerce-modules/inventory/links-to-other-modules/page.mdx index 2b8f3134c9173..35bfc0bdc3746 100644 --- a/www/apps/resources/app/commerce-modules/inventory/links-to-other-modules/page.mdx +++ b/www/apps/resources/app/commerce-modules/inventory/links-to-other-modules/page.mdx @@ -42,8 +42,8 @@ To retrieve the product variants of an inventory item with [Query](!docs!/learn/ const { data: inventoryItems } = await query.graph({ entity: "inventory_item", fields: [ - "variants.*" - ] + "variants.*", + ], }) // inventoryItems.variants @@ -60,8 +60,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: inventoryItems } = useQueryGraphStep({ entity: "inventory_item", fields: [ - "variants.*" - ] + "variants.*", + ], }) // inventoryItems.variants @@ -131,8 +131,8 @@ To retrieve the stock locations of an inventory level with [Query](!docs!/learn/ const { data: inventoryLevels } = await query.graph({ entity: "inventory_level", fields: [ - "stock_locations.*" - ] + "stock_locations.*", + ], }) // inventoryLevels.stock_locations @@ -149,8 +149,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: inventoryLevels } = useQueryGraphStep({ entity: "inventory_level", fields: [ - "stock_locations.*" - ] + "stock_locations.*", + ], }) // inventoryLevels.stock_locations diff --git a/www/apps/resources/app/commerce-modules/inventory/page.mdx b/www/apps/resources/app/commerce-modules/inventory/page.mdx index 56838a830d604..9abb351be9454 100644 --- a/www/apps/resources/app/commerce-modules/inventory/page.mdx +++ b/www/apps/resources/app/commerce-modules/inventory/page.mdx @@ -60,6 +60,9 @@ const createInventoryItemStep = createStep( return new StepResponse({ inventoryItem }, inventoryItem.id) }, async (inventoryItemId, { container }) => { + if (!inventoryItemId) { + return + } const inventoryModuleService = container.resolve(Modules.INVENTORY) await inventoryModuleService.deleteInventoryItems([inventoryItemId]) @@ -83,70 +86,70 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import type { - MedusaRequest, - MedusaResponse, - } from "@medusajs/framework/http" - import {createInventoryItemWorkflow} from "../../workflows/create-inventory-item" - - export async function GET( - req: MedusaRequest, - res: MedusaResponse - ) { - const { result } = await createInventoryItemWorkflow(req.scope) - .run() - - res.send(result) - } - ``` +```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import type { + MedusaRequest, + MedusaResponse, +} from "@medusajs/framework/http" +import { createInventoryItemWorkflow } from "../../workflows/create-inventory-item" + +export async function GET( + req: MedusaRequest, + res: MedusaResponse +) { + const { result } = await createInventoryItemWorkflow(req.scope) + .run() + + res.send(result) +} +``` - ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import { - type SubscriberConfig, - type SubscriberArgs, - } from "@medusajs/framework" - import {createInventoryItemWorkflow} from "../workflows/create-inventory-item" - - export default async function handleUserCreated({ - event: { data }, - container, - }: SubscriberArgs<{ id: string }>) { - const { result } = await createInventoryItemWorkflow(container) - .run() - - console.log(result) - } +```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import { + type SubscriberConfig, + type SubscriberArgs, +} from "@medusajs/framework" +import { createInventoryItemWorkflow } from "../workflows/create-inventory-item" + +export default async function handleUserCreated({ + event: { data }, + container, +}: SubscriberArgs<{ id: string }>) { + const { result } = await createInventoryItemWorkflow(container) + .run() + + console.log(result) +} - export const config: SubscriberConfig = { - event: "user.created", - } - ``` +export const config: SubscriberConfig = { + event: "user.created", +} +``` - ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} - import { MedusaContainer } from "@medusajs/framework/types" - import {createInventoryItemWorkflow} from "../workflows/create-inventory-item" +```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} +import { MedusaContainer } from "@medusajs/framework/types" +import { createInventoryItemWorkflow } from "../workflows/create-inventory-item" - export default async function myCustomJob( - container: MedusaContainer - ) { - const { result } = await createInventoryItemWorkflow(container) - .run() +export default async function myCustomJob( + container: MedusaContainer +) { + const { result } = await createInventoryItemWorkflow(container) + .run() - console.log(result) - } + console.log(result) +} - export const config = { - name: "run-once-a-day", - schedule: `0 0 * * *`, - }; - ``` +export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, +} +``` diff --git a/www/apps/resources/app/commerce-modules/order/links-to-other-modules/page.mdx b/www/apps/resources/app/commerce-modules/order/links-to-other-modules/page.mdx index 07c028281bada..2964f1b91f64a 100644 --- a/www/apps/resources/app/commerce-modules/order/links-to-other-modules/page.mdx +++ b/www/apps/resources/app/commerce-modules/order/links-to-other-modules/page.mdx @@ -47,8 +47,8 @@ To retrieve the customer of an order with [Query](!docs!/learn/fundamentals/modu const { data: orders } = await query.graph({ entity: "order", fields: [ - "customer.*" - ] + "customer.*", + ], }) // orders.customer @@ -65,8 +65,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: orders } = useQueryGraphStep({ entity: "order", fields: [ - "customer.*" - ] + "customer.*", + ], }) // orders.customer @@ -96,8 +96,8 @@ To retrieve the cart of an order with [Query](!docs!/learn/fundamentals/module-l const { data: orders } = await query.graph({ entity: "order", fields: [ - "cart.*" - ] + "cart.*", + ], }) // orders.cart @@ -114,8 +114,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: orders } = useQueryGraphStep({ entity: "order", fields: [ - "cart.*" - ] + "cart.*", + ], }) // orders.cart @@ -197,8 +197,8 @@ To retrieve the fulfillments of a return, pass `fulfillments.*` in `fields`. const { data: orders } = await query.graph({ entity: "order", fields: [ - "fulfillments.*" - ] + "fulfillments.*", + ], }) // orders.fulfillments @@ -215,8 +215,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: orders } = useQueryGraphStep({ entity: "order", fields: [ - "fulfillments.*" - ] + "fulfillments.*", + ], }) // orders.fulfillments @@ -290,8 +290,8 @@ To retrieve the payment collections of an order, order exchange, or order claim const { data: orders } = await query.graph({ entity: "order", fields: [ - "payment_collections.*" - ] + "payment_collections.*", + ], }) // orders.payment_collections @@ -308,8 +308,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: orders } = useQueryGraphStep({ entity: "order", fields: [ - "payment_collections.*" - ] + "payment_collections.*", + ], }) // orders.payment_collections @@ -388,8 +388,8 @@ To retrieve the product, pass `product.*` in `fields`. const { data: lineItems } = await query.graph({ entity: "order_line_item", fields: [ - "variant.*" - ] + "variant.*", + ], }) // lineItems.variant @@ -406,8 +406,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: lineItems } = useQueryGraphStep({ entity: "order_line_item", fields: [ - "variant.*" - ] + "variant.*", + ], }) // lineItems.variant @@ -435,8 +435,8 @@ To retrieve the promotion applied on an order with [Query](!docs!/learn/fundamen const { data: orders } = await query.graph({ entity: "order", fields: [ - "promotion.*" - ] + "promotion.*", + ], }) // orders.promotion @@ -453,8 +453,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: orders } = useQueryGraphStep({ entity: "order", fields: [ - "promotion.*" - ] + "promotion.*", + ], }) // orders.promotion @@ -524,8 +524,8 @@ To retrieve the region of an order with [Query](!docs!/learn/fundamentals/module const { data: orders } = await query.graph({ entity: "order", fields: [ - "region.*" - ] + "region.*", + ], }) // orders.region @@ -542,8 +542,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: orders } = useQueryGraphStep({ entity: "order", fields: [ - "region.*" - ] + "region.*", + ], }) // orders.region @@ -569,8 +569,8 @@ To retrieve the sales channel of an order with [Query](!docs!/learn/fundamentals const { data: orders } = await query.graph({ entity: "order", fields: [ - "sales_channel.*" - ] + "sales_channel.*", + ], }) // orders.sales_channel @@ -587,8 +587,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: orders } = useQueryGraphStep({ entity: "order", fields: [ - "sales_channel.*" - ] + "sales_channel.*", + ], }) // orders.sales_channel diff --git a/www/apps/resources/app/commerce-modules/order/page.mdx b/www/apps/resources/app/commerce-modules/order/page.mdx index 2b5b8b1ef0bd4..6f62b3cd607f1 100644 --- a/www/apps/resources/app/commerce-modules/order/page.mdx +++ b/www/apps/resources/app/commerce-modules/order/page.mdx @@ -68,12 +68,14 @@ const createDraftOrderStep = createStep( }, ], status: "draft", - is_draft_order: true, }) return new StepResponse({ draftOrder }, draftOrder.id) }, async (draftOrderId, { container }) => { + if (!draftOrderId) { + return + } const orderModuleService = container.resolve(Modules.ORDER) await orderModuleService.deleteOrders([draftOrderId]) @@ -88,6 +90,7 @@ export const createDraftOrderWorkflow = createWorkflow( return new WorkflowResponse({ draftOrder, }) + } ) ``` @@ -96,70 +99,70 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import type { - MedusaRequest, - MedusaResponse, - } from "@medusajs/framework/http" - import {createDraftOrderWorkflow} from "../../workflows/create-draft-order" - - export async function GET( - req: MedusaRequest, - res: MedusaResponse - ) { - const { result } = await createDraftOrderWorkflow(req.scope) - .run() - - res.send(result) - } - ``` +```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import type { + MedusaRequest, + MedusaResponse, +} from "@medusajs/framework/http" +import { createDraftOrderWorkflow } from "../../workflows/create-draft-order" + +export async function GET( + req: MedusaRequest, + res: MedusaResponse +) { + const { result } = await createDraftOrderWorkflow(req.scope) + .run() + + res.send(result) +} +``` - ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import { - type SubscriberConfig, - type SubscriberArgs, - } from "@medusajs/framework" - import {createDraftOrderWorkflow} from "../workflows/create-draft-order" - - export default async function handleUserCreated({ - event: { data }, - container, - }: SubscriberArgs<{ id: string }>) { - const { result } = await createDraftOrderWorkflow(container) - .run() - - console.log(result) - } +```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import { + type SubscriberConfig, + type SubscriberArgs, +} from "@medusajs/framework" +import { createDraftOrderWorkflow } from "../workflows/create-draft-order" + +export default async function handleUserCreated({ + event: { data }, + container, +}: SubscriberArgs<{ id: string }>) { + const { result } = await createDraftOrderWorkflow(container) + .run() + + console.log(result) +} - export const config: SubscriberConfig = { - event: "user.created", - } - ``` +export const config: SubscriberConfig = { + event: "user.created", +} +``` - ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} - import { MedusaContainer } from "@medusajs/framework/types" - import {createDraftOrderWorkflow} from "../workflows/create-draft-order" +```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} +import { MedusaContainer } from "@medusajs/framework/types" +import { createDraftOrderWorkflow } from "../workflows/create-draft-order" - export default async function myCustomJob( - container: MedusaContainer - ) { - const { result } = await createDraftOrderWorkflow(container) - .run() +export default async function myCustomJob( + container: MedusaContainer +) { + const { result } = await createDraftOrderWorkflow(container) + .run() - console.log(result) - } + console.log(result) +} - export const config = { - name: "run-once-a-day", - schedule: `0 0 * * *`, - }; - ``` +export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, +} +``` diff --git a/www/apps/resources/app/commerce-modules/payment/links-to-other-modules/page.mdx b/www/apps/resources/app/commerce-modules/payment/links-to-other-modules/page.mdx index 14af06d51b994..9c43ff095df12 100644 --- a/www/apps/resources/app/commerce-modules/payment/links-to-other-modules/page.mdx +++ b/www/apps/resources/app/commerce-modules/payment/links-to-other-modules/page.mdx @@ -39,8 +39,8 @@ To retrieve the cart associated with the payment collection with [Query](!docs!/ const { data: paymentCollections } = await query.graph({ entity: "payment_collection", fields: [ - "cart.*" - ] + "cart.*", + ], }) // paymentCollections.cart @@ -57,8 +57,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: paymentCollections } = useQueryGraphStep({ entity: "payment_collection", fields: [ - "cart.*" - ] + "cart.*", + ], }) // paymentCollections.cart @@ -131,8 +131,8 @@ To retrieve the order of a payment collection with [Query](!docs!/learn/fundamen const { data: paymentCollections } = await query.graph({ entity: "payment_collection", fields: [ - "order.*" - ] + "order.*", + ], }) // paymentCollections.order @@ -149,8 +149,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: paymentCollections } = useQueryGraphStep({ entity: "payment_collection", fields: [ - "order.*" - ] + "order.*", + ], }) // paymentCollections.order @@ -224,8 +224,8 @@ To retrieve the regions of a payment provider with [Query](!docs!/learn/fundamen const { data: paymentProviders } = await query.graph({ entity: "payment_provider", fields: [ - "regions.*" - ] + "regions.*", + ], }) // paymentProviders.regions @@ -242,8 +242,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: paymentProviders } = useQueryGraphStep({ entity: "payment_provider", fields: [ - "regions.*" - ] + "regions.*", + ], }) // paymentProviders.regions diff --git a/www/apps/resources/app/commerce-modules/payment/page.mdx b/www/apps/resources/app/commerce-modules/payment/page.mdx index 9e530f964c06f..5ae0b744fe0dd 100644 --- a/www/apps/resources/app/commerce-modules/payment/page.mdx +++ b/www/apps/resources/app/commerce-modules/payment/page.mdx @@ -60,6 +60,9 @@ const createPaymentCollectionStep = createStep( return new StepResponse({ paymentCollection }, paymentCollection.id) }, async (paymentCollectionId, { container }) => { + if (!paymentCollectionId) { + return + } const paymentModuleService = container.resolve(Modules.PAYMENT) await paymentModuleService.deletePaymentCollections([paymentCollectionId]) @@ -83,70 +86,70 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import type { - MedusaRequest, - MedusaResponse, - } from "@medusajs/framework/http" - import {createPaymentCollectionWorkflow} from "../../workflows/create-payment-collection" - - export async function GET( - req: MedusaRequest, - res: MedusaResponse - ) { - const { result } = await createPaymentCollectionWorkflow(req.scope) - .run() - - res.send(result) - } - ``` +```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import type { + MedusaRequest, + MedusaResponse, +} from "@medusajs/framework/http" +import { createPaymentCollectionWorkflow } from "../../workflows/create-payment-collection" + +export async function GET( + req: MedusaRequest, + res: MedusaResponse +) { + const { result } = await createPaymentCollectionWorkflow(req.scope) + .run() + + res.send(result) +} +``` - ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import { - type SubscriberConfig, - type SubscriberArgs, - } from "@medusajs/framework" - import {createPaymentCollectionWorkflow} from "../workflows/create-payment-collection" - - export default async function handleUserCreated({ - event: { data }, - container, - }: SubscriberArgs<{ id: string }>) { - const { result } = await createPaymentCollectionWorkflow(container) - .run() - - console.log(result) - } +```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import { + type SubscriberConfig, + type SubscriberArgs, +} from "@medusajs/framework" +import { createPaymentCollectionWorkflow } from "../workflows/create-payment-collection" + +export default async function handleUserCreated({ + event: { data }, + container, +}: SubscriberArgs<{ id: string }>) { + const { result } = await createPaymentCollectionWorkflow(container) + .run() + + console.log(result) +} - export const config: SubscriberConfig = { - event: "user.created", - } - ``` +export const config: SubscriberConfig = { + event: "user.created", +} +``` - ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} - import { MedusaContainer } from "@medusajs/framework/types" - import {createPaymentCollectionWorkflow} from "../workflows/create-payment-collection" +```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} +import { MedusaContainer } from "@medusajs/framework/types" +import { createPaymentCollectionWorkflow } from "../workflows/create-payment-collection" - export default async function myCustomJob( - container: MedusaContainer - ) { - const { result } = await createPaymentCollectionWorkflow(container) - .run() +export default async function myCustomJob( + container: MedusaContainer +) { + const { result } = await createPaymentCollectionWorkflow(container) + .run() - console.log(result) - } + console.log(result) +} - export const config = { - name: "run-once-a-day", - schedule: `0 0 * * *`, - }; - ``` +export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, +} +``` diff --git a/www/apps/resources/app/commerce-modules/pricing/links-to-other-modules/page.mdx b/www/apps/resources/app/commerce-modules/pricing/links-to-other-modules/page.mdx index 5fb0e16c403b6..5348688ed4f63 100644 --- a/www/apps/resources/app/commerce-modules/pricing/links-to-other-modules/page.mdx +++ b/www/apps/resources/app/commerce-modules/pricing/links-to-other-modules/page.mdx @@ -36,8 +36,8 @@ To retrieve the shipping option of a price set with [Query](!docs!/learn/fundame const { data: priceSets } = await query.graph({ entity: "price_set", fields: [ - "shipping_option.*" - ] + "shipping_option.*", + ], }) // priceSets.shipping_option @@ -54,8 +54,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: priceSets } = useQueryGraphStep({ entity: "price_set", fields: [ - "shipping_option.*" - ] + "shipping_option.*", + ], }) // priceSets.shipping_option @@ -133,8 +133,8 @@ To retrieve the variant of a price set with [Query](!docs!/learn/fundamentals/mo const { data: priceSets } = await query.graph({ entity: "price_set", fields: [ - "variant.*" - ] + "variant.*", + ], }) // priceSets.variant @@ -151,8 +151,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: priceSets } = useQueryGraphStep({ entity: "price_set", fields: [ - "variant.*" - ] + "variant.*", + ], }) // priceSets.variant diff --git a/www/apps/resources/app/commerce-modules/pricing/page.mdx b/www/apps/resources/app/commerce-modules/pricing/page.mdx index cb65399da1a1f..bf10090096d0b 100644 --- a/www/apps/resources/app/commerce-modules/pricing/page.mdx +++ b/www/apps/resources/app/commerce-modules/pricing/page.mdx @@ -71,6 +71,9 @@ const createPriceSetStep = createStep( return new StepResponse({ priceSet }, priceSet.id) }, async (priceSetId, { container }) => { + if (!priceSetId) { + return + } const pricingModuleService = container.resolve(Modules.PRICING) await pricingModuleService.deletePriceSets([priceSetId]) @@ -94,70 +97,70 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import type { - MedusaRequest, - MedusaResponse, - } from "@medusajs/framework/http" - import {createPriceSetWorkflow} from "../../workflows/create-price-set" - - export async function GET( - req: MedusaRequest, - res: MedusaResponse - ) { - const { result } = await createPriceSetWorkflow(req.scope) - .run() - - res.send(result) - } - ``` +```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import type { + MedusaRequest, + MedusaResponse, +} from "@medusajs/framework/http" +import { createPriceSetWorkflow } from "../../workflows/create-price-set" + +export async function GET( + req: MedusaRequest, + res: MedusaResponse +) { + const { result } = await createPriceSetWorkflow(req.scope) + .run() + + res.send(result) +} +``` - ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import { - type SubscriberConfig, - type SubscriberArgs, - } from "@medusajs/framework" - import {createPriceSetWorkflow} from "../workflows/create-price-set" - - export default async function handleUserCreated({ - event: { data }, - container, - }: SubscriberArgs<{ id: string }>) { - const { result } = await createPriceSetWorkflow(container) - .run() - - console.log(result) - } +```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import { + type SubscriberConfig, + type SubscriberArgs, +} from "@medusajs/framework" +import { createPriceSetWorkflow } from "../workflows/create-price-set" + +export default async function handleUserCreated({ + event: { data }, + container, +}: SubscriberArgs<{ id: string }>) { + const { result } = await createPriceSetWorkflow(container) + .run() + + console.log(result) +} - export const config: SubscriberConfig = { - event: "user.created", - } - ``` +export const config: SubscriberConfig = { + event: "user.created", +} +``` - ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} - import { MedusaContainer } from "@medusajs/framework/types" - import {createPriceSetWorkflow} from "../workflows/create-price-set" +```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} +import { MedusaContainer } from "@medusajs/framework/types" +import { createPriceSetWorkflow } from "../workflows/create-price-set" - export default async function myCustomJob( - container: MedusaContainer - ) { - const { result } = await createPriceSetWorkflow(container) - .run() +export default async function myCustomJob( + container: MedusaContainer +) { + const { result } = await createPriceSetWorkflow(container) + .run() - console.log(result) - } + console.log(result) +} - export const config = { - name: "run-once-a-day", - schedule: `0 0 * * *`, - }; - ``` +export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, +} +``` diff --git a/www/apps/resources/app/commerce-modules/product/links-to-other-modules/page.mdx b/www/apps/resources/app/commerce-modules/product/links-to-other-modules/page.mdx index 04fd9fedbf21d..1e92032bd8aec 100644 --- a/www/apps/resources/app/commerce-modules/product/links-to-other-modules/page.mdx +++ b/www/apps/resources/app/commerce-modules/product/links-to-other-modules/page.mdx @@ -50,8 +50,8 @@ To retrieve the line items of a product, pass `line_items.*` in `fields`. const { data: variants } = await query.graph({ entity: "variant", fields: [ - "line_items.*" - ] + "line_items.*", + ], }) // variants.line_items @@ -68,8 +68,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: variants } = useQueryGraphStep({ entity: "variant", fields: [ - "line_items.*" - ] + "line_items.*", + ], }) // variants.line_items @@ -101,8 +101,8 @@ To retrieve the inventory items of a product variant with [Query](!docs!/learn/f const { data: variants } = await query.graph({ entity: "variant", fields: [ - "inventory_items.*" - ] + "inventory_items.*", + ], }) // variants.inventory_items @@ -119,8 +119,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: variants } = useQueryGraphStep({ entity: "variant", fields: [ - "inventory_items.*" - ] + "inventory_items.*", + ], }) // variants.inventory_items @@ -199,8 +199,8 @@ To retrieve a product's order line items, pass `order_items.*` in `fields`. const { data: variants } = await query.graph({ entity: "variant", fields: [ - "order_items.*" - ] + "order_items.*", + ], }) // variants.order_items @@ -217,8 +217,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: variants } = useQueryGraphStep({ entity: "variant", fields: [ - "order_items.*" - ] + "order_items.*", + ], }) // variants.order_items @@ -250,8 +250,8 @@ To retrieve the price set of a variant with [Query](!docs!/learn/fundamentals/mo const { data: variants } = await query.graph({ entity: "variant", fields: [ - "price_set.*" - ] + "price_set.*", + ], }) // variants.price_set @@ -268,8 +268,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: variants } = useQueryGraphStep({ entity: "variant", fields: [ - "price_set.*" - ] + "price_set.*", + ], }) // variants.price_set @@ -343,8 +343,8 @@ To retrieve the sales channels of a product with [Query](!docs!/learn/fundamenta const { data: products } = await query.graph({ entity: "product", fields: [ - "sales_channels.*" - ] + "sales_channels.*", + ], }) // products.sales_channels @@ -361,8 +361,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: products } = useQueryGraphStep({ entity: "product", fields: [ - "sales_channels.*" - ] + "sales_channels.*", + ], }) // products.sales_channels diff --git a/www/apps/resources/app/commerce-modules/product/page.mdx b/www/apps/resources/app/commerce-modules/product/page.mdx index 64d5cf7aee2c8..45777f4580cd0 100644 --- a/www/apps/resources/app/commerce-modules/product/page.mdx +++ b/www/apps/resources/app/commerce-modules/product/page.mdx @@ -70,6 +70,9 @@ const createProductStep = createStep( return new StepResponse({ product }, product.id) }, async (productId, { container }) => { + if (!productId) { + return + } const productService = container.resolve(Modules.PRODUCT) await productService.deleteProducts([productId]) @@ -93,70 +96,70 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import type { - MedusaRequest, - MedusaResponse, - } from "@medusajs/framework/http" - import {createProductWorkflow} from "../../workflows/create-product" - - export async function GET( - req: MedusaRequest, - res: MedusaResponse - ) { - const { result } = await createProductWorkflow(req.scope) - .run() - - res.send(result) - } - ``` +```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import type { + MedusaRequest, + MedusaResponse, +} from "@medusajs/framework/http" +import { createProductWorkflow } from "../../workflows/create-product" + +export async function GET( + req: MedusaRequest, + res: MedusaResponse +) { + const { result } = await createProductWorkflow(req.scope) + .run() + + res.send(result) +} +``` - ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import { - type SubscriberConfig, - type SubscriberArgs, - } from "@medusajs/framework" - import {createProductWorkflow} from "../workflows/create-product" - - export default async function handleUserCreated({ - event: { data }, - container, - }: SubscriberArgs<{ id: string }>) { - const { result } = await createProductWorkflow(container) - .run() - - console.log(result) - } +```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import { + type SubscriberConfig, + type SubscriberArgs, +} from "@medusajs/framework" +import { createProductWorkflow } from "../workflows/create-product" + +export default async function handleUserCreated({ + event: { data }, + container, +}: SubscriberArgs<{ id: string }>) { + const { result } = await createProductWorkflow(container) + .run() + + console.log(result) +} - export const config: SubscriberConfig = { - event: "user.created", - } - ``` +export const config: SubscriberConfig = { + event: "user.created", +} +``` - ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} - import { MedusaContainer } from "@medusajs/framework/types" - import {createProductWorkflow} from "../workflows/create-product" +```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} +import { MedusaContainer } from "@medusajs/framework/types" +import { createProductWorkflow } from "../workflows/create-product" - export default async function myCustomJob( - container: MedusaContainer - ) { - const { result } = await createProductWorkflow(container) - .run() +export default async function myCustomJob( + container: MedusaContainer +) { + const { result } = await createProductWorkflow(container) + .run() - console.log(result) - } + console.log(result) +} - export const config = { - name: "run-once-a-day", - schedule: `0 0 * * *`, - }; - ``` +export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, +} +``` diff --git a/www/apps/resources/app/commerce-modules/promotion/links-to-other-modules/page.mdx b/www/apps/resources/app/commerce-modules/promotion/links-to-other-modules/page.mdx index 356a3f9134f67..6b73eec158760 100644 --- a/www/apps/resources/app/commerce-modules/promotion/links-to-other-modules/page.mdx +++ b/www/apps/resources/app/commerce-modules/promotion/links-to-other-modules/page.mdx @@ -49,8 +49,8 @@ To retrieve the line item adjustments of a promotion, pass `line_item_adjustment const { data: promotions } = await query.graph({ entity: "promotion", fields: [ - "carts.*" - ] + "carts.*", + ], }) // promotions.carts @@ -67,8 +67,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: promotions } = useQueryGraphStep({ entity: "promotion", fields: [ - "carts.*" - ] + "carts.*", + ], }) // promotions.carts @@ -140,8 +140,8 @@ To retrieve the orders a promotion is applied on with [Query](!docs!/learn/funda const { data: promotions } = await query.graph({ entity: "promotion", fields: [ - "orders.*" - ] + "orders.*", + ], }) // promotions.orders @@ -158,8 +158,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: promotions } = useQueryGraphStep({ entity: "promotion", fields: [ - "orders.*" - ] + "orders.*", + ], }) // promotions.orders diff --git a/www/apps/resources/app/commerce-modules/promotion/page.mdx b/www/apps/resources/app/commerce-modules/promotion/page.mdx index 4d3cadc6e95f1..947659e9581f2 100644 --- a/www/apps/resources/app/commerce-modules/promotion/page.mdx +++ b/www/apps/resources/app/commerce-modules/promotion/page.mdx @@ -57,7 +57,7 @@ const createPromotionStep = createStep( application_method: { type: "percentage", target_type: "order", - value: "10", + value: 10, currency_code: "usd", }, }) @@ -65,6 +65,9 @@ const createPromotionStep = createStep( return new StepResponse({ promotion }, promotion.id) }, async (promotionId, { container }) => { + if (!promotionId) { + return + } const promotionModuleService = container.resolve(Modules.PROMOTION) await promotionModuleService.deletePromotions(promotionId) @@ -88,70 +91,70 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import type { - MedusaRequest, - MedusaResponse, - } from "@medusajs/framework/http" - import { createPromotionWorkflow } from "../../workflows/create-cart" - - export async function GET( - req: MedusaRequest, - res: MedusaResponse - ) { - const { result } = await createPromotionWorkflow(req.scope) - .run() - - res.send(result) - } - ``` +```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import type { + MedusaRequest, + MedusaResponse, +} from "@medusajs/framework/http" +import { createPromotionWorkflow } from "../../workflows/create-cart" + +export async function GET( + req: MedusaRequest, + res: MedusaResponse +) { + const { result } = await createPromotionWorkflow(req.scope) + .run() + + res.send(result) +} +``` - ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import { - type SubscriberConfig, - type SubscriberArgs, - } from "@medusajs/framework" - import { createPromotionWorkflow } from "../workflows/create-cart" - - export default async function handleUserCreated({ - event: { data }, - container, - }: SubscriberArgs<{ id: string }>) { - const { result } = await createPromotionWorkflow(container) - .run() - - console.log(result) - } +```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import { + type SubscriberConfig, + type SubscriberArgs, +} from "@medusajs/framework" +import { createPromotionWorkflow } from "../workflows/create-cart" + +export default async function handleUserCreated({ + event: { data }, + container, +}: SubscriberArgs<{ id: string }>) { + const { result } = await createPromotionWorkflow(container) + .run() + + console.log(result) +} - export const config: SubscriberConfig = { - event: "user.created", - } - ``` +export const config: SubscriberConfig = { + event: "user.created", +} +``` - ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} - import { MedusaContainer } from "@medusajs/framework/types" - import { createPromotionWorkflow } from "../workflows/create-cart" +```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} +import { MedusaContainer } from "@medusajs/framework/types" +import { createPromotionWorkflow } from "../workflows/create-cart" - export default async function myCustomJob( - container: MedusaContainer - ) { - const { result } = await createPromotionWorkflow(container) - .run() +export default async function myCustomJob( + container: MedusaContainer +) { + const { result } = await createPromotionWorkflow(container) + .run() - console.log(result) - } + console.log(result) +} - export const config = { - name: "run-once-a-day", - schedule: `0 0 * * *`, - }; - ``` +export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, +} +``` diff --git a/www/apps/resources/app/commerce-modules/region/links-to-other-modules/page.mdx b/www/apps/resources/app/commerce-modules/region/links-to-other-modules/page.mdx index 08881435999fd..1d7183799bb00 100644 --- a/www/apps/resources/app/commerce-modules/region/links-to-other-modules/page.mdx +++ b/www/apps/resources/app/commerce-modules/region/links-to-other-modules/page.mdx @@ -39,8 +39,8 @@ To retrieve the carts of a region with [Query](!docs!/learn/fundamentals/module- const { data: regions } = await query.graph({ entity: "region", fields: [ - "carts.*" - ] + "carts.*", + ], }) // regions.carts @@ -57,8 +57,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: regions } = useQueryGraphStep({ entity: "region", fields: [ - "carts.*" - ] + "carts.*", + ], }) // regions.carts @@ -84,8 +84,8 @@ To retrieve the orders of a region with [Query](!docs!/learn/fundamentals/module const { data: regions } = await query.graph({ entity: "region", fields: [ - "orders.*" - ] + "orders.*", + ], }) // regions.orders @@ -102,8 +102,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: regions } = useQueryGraphStep({ entity: "region", fields: [ - "orders.*" - ] + "orders.*", + ], }) // regions.orders @@ -133,8 +133,8 @@ To retrieve the payment providers of a region with [Query](!docs!/learn/fundamen const { data: regions } = await query.graph({ entity: "region", fields: [ - "payment_providers.*" - ] + "payment_providers.*", + ], }) // regions.payment_providers @@ -151,8 +151,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: regions } = useQueryGraphStep({ entity: "region", fields: [ - "payment_providers.*" - ] + "payment_providers.*", + ], }) // regions.payment_providers diff --git a/www/apps/resources/app/commerce-modules/region/page.mdx b/www/apps/resources/app/commerce-modules/region/page.mdx index d2708c902bac5..8d7ccc275021a 100644 --- a/www/apps/resources/app/commerce-modules/region/page.mdx +++ b/www/apps/resources/app/commerce-modules/region/page.mdx @@ -60,6 +60,9 @@ const createRegionStep = createStep( return new StepResponse({ region }, region.id) }, async (regionId, { container }) => { + if (!regionId) { + return + } const regionModuleService = container.resolve(Modules.REGION) await regionModuleService.deleteRegions([regionId]) @@ -83,70 +86,70 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import type { - MedusaRequest, - MedusaResponse, - } from "@medusajs/framework/http" - import { createRegionWorkflow } from "../../workflows/create-region" - - export async function GET( - req: MedusaRequest, - res: MedusaResponse - ) { - const { result } = await createRegionWorkflow(req.scope) - .run() - - res.send(result) - } - ``` +```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import type { + MedusaRequest, + MedusaResponse, +} from "@medusajs/framework/http" +import { createRegionWorkflow } from "../../workflows/create-region" + +export async function GET( + req: MedusaRequest, + res: MedusaResponse +) { + const { result } = await createRegionWorkflow(req.scope) + .run() + + res.send(result) +} +``` - ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import { - type SubscriberConfig, - type SubscriberArgs, - } from "@medusajs/framework" - import { createRegionWorkflow } from "../workflows/create-region" - - export default async function handleUserCreated({ - event: { data }, - container, - }: SubscriberArgs<{ id: string }>) { - const { result } = await createRegionWorkflow(container) - .run() - - console.log(result) - } +```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import { + type SubscriberConfig, + type SubscriberArgs, +} from "@medusajs/framework" +import { createRegionWorkflow } from "../workflows/create-region" + +export default async function handleUserCreated({ + event: { data }, + container, +}: SubscriberArgs<{ id: string }>) { + const { result } = await createRegionWorkflow(container) + .run() + + console.log(result) +} - export const config: SubscriberConfig = { - event: "user.created", - } - ``` +export const config: SubscriberConfig = { + event: "user.created", +} +``` - ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} - import { MedusaContainer } from "@medusajs/framework/types" - import { createRegionWorkflow } from "../workflows/create-region" +```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} +import { MedusaContainer } from "@medusajs/framework/types" +import { createRegionWorkflow } from "../workflows/create-region" - export default async function myCustomJob( - container: MedusaContainer - ) { - const { result } = await createRegionWorkflow(container) - .run() +export default async function myCustomJob( + container: MedusaContainer +) { + const { result } = await createRegionWorkflow(container) + .run() - console.log(result) - } + console.log(result) +} - export const config = { - name: "run-once-a-day", - schedule: `0 0 * * *`, - }; - ``` +export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, +} +``` diff --git a/www/apps/resources/app/commerce-modules/sales-channel/links-to-other-modules/page.mdx b/www/apps/resources/app/commerce-modules/sales-channel/links-to-other-modules/page.mdx index fb68fb6608c40..23e46d578b8c2 100644 --- a/www/apps/resources/app/commerce-modules/sales-channel/links-to-other-modules/page.mdx +++ b/www/apps/resources/app/commerce-modules/sales-channel/links-to-other-modules/page.mdx @@ -45,8 +45,8 @@ To retrieve the API keys associated with a sales channel with [Query](!docs!/lea const { data: salesChannels } = await query.graph({ entity: "sales_channel", fields: [ - "publishable_api_keys.*" - ] + "publishable_api_keys.*", + ], }) // salesChannels.publishable_api_keys @@ -63,8 +63,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: salesChannels } = useQueryGraphStep({ entity: "sales_channel", fields: [ - "publishable_api_keys.*" - ] + "publishable_api_keys.*", + ], }) // salesChannels.publishable_api_keys @@ -134,8 +134,8 @@ To retrieve the carts of a sales channel with [Query](!docs!/learn/fundamentals/ const { data: salesChannels } = await query.graph({ entity: "sales_channel", fields: [ - "carts.*" - ] + "carts.*", + ], }) // salesChannels.carts @@ -152,8 +152,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: salesChannels } = useQueryGraphStep({ entity: "sales_channel", fields: [ - "carts.*" - ] + "carts.*", + ], }) // salesChannels.carts @@ -179,8 +179,8 @@ To retrieve the orders of a sales channel with [Query](!docs!/learn/fundamentals const { data: salesChannels } = await query.graph({ entity: "sales_channel", fields: [ - "orders.*" - ] + "orders.*", + ], }) // salesChannels.orders @@ -197,8 +197,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: salesChannels } = useQueryGraphStep({ entity: "sales_channel", fields: [ - "orders.*" - ] + "orders.*", + ], }) // salesChannels.orders @@ -228,8 +228,8 @@ To retrieve the products of a sales channel with [Query](!docs!/learn/fundamenta const { data: salesChannels } = await query.graph({ entity: "sales_channel", fields: [ - "products.*" - ] + "products.*", + ], }) // salesChannels.products @@ -246,8 +246,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: salesChannels } = useQueryGraphStep({ entity: "sales_channel", fields: [ - "products.*" - ] + "products.*", + ], }) // salesChannels.products @@ -321,8 +321,8 @@ To retrieve the stock locations of a sales channel with [Query](!docs!/learn/fun const { data: salesChannels } = await query.graph({ entity: "sales_channel", fields: [ - "stock_locations.*" - ] + "stock_locations.*", + ], }) // salesChannels.stock_locations @@ -339,8 +339,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: salesChannels } = useQueryGraphStep({ entity: "sales_channel", fields: [ - "stock_locations.*" - ] + "stock_locations.*", + ], }) // salesChannels.stock_locations diff --git a/www/apps/resources/app/commerce-modules/sales-channel/page.mdx b/www/apps/resources/app/commerce-modules/sales-channel/page.mdx index 25deebfa1185e..f144d01b4325b 100644 --- a/www/apps/resources/app/commerce-modules/sales-channel/page.mdx +++ b/www/apps/resources/app/commerce-modules/sales-channel/page.mdx @@ -72,12 +72,15 @@ const createSalesChannelStep = createStep( }, ]) - return new StepResponse({ salesChannels }, salesChannels.map(sc => sc.id)) + return new StepResponse({ salesChannels }, salesChannels.map((sc) => sc.id)) }, async (salesChannelIds, { container }) => { + if (!salesChannelIds) { + return + } const salesChannelModuleService = container.resolve(Modules.SALES_CHANNEL) - const salesChannels = await salesChannelModuleService.deleteSalesChannels( + await salesChannelModuleService.deleteSalesChannels( salesChannelIds ) } @@ -100,70 +103,70 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import type { - MedusaRequest, - MedusaResponse, - } from "@medusajs/framework/http" - import { createSalesChannelWorkflow } from "../../workflows/create-sales-channel" - - export async function GET( - req: MedusaRequest, - res: MedusaResponse - ) { - const { result } = await createSalesChannelWorkflow(req.scope) - .run() - - res.send(result) - } - ``` +```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import type { + MedusaRequest, + MedusaResponse, +} from "@medusajs/framework/http" +import { createSalesChannelWorkflow } from "../../workflows/create-sales-channel" + +export async function GET( + req: MedusaRequest, + res: MedusaResponse +) { + const { result } = await createSalesChannelWorkflow(req.scope) + .run() + + res.send(result) +} +``` - ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import { - type SubscriberConfig, - type SubscriberArgs, - } from "@medusajs/framework" - import { createSalesChannelWorkflow } from "../workflows/create-sales-channel" - - export default async function handleUserCreated({ - event: { data }, - container, - }: SubscriberArgs<{ id: string }>) { - const { result } = await createSalesChannelWorkflow(container) - .run() - - console.log(result) - } +```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import { + type SubscriberConfig, + type SubscriberArgs, +} from "@medusajs/framework" +import { createSalesChannelWorkflow } from "../workflows/create-sales-channel" + +export default async function handleUserCreated({ + event: { data }, + container, +}: SubscriberArgs<{ id: string }>) { + const { result } = await createSalesChannelWorkflow(container) + .run() + + console.log(result) +} - export const config: SubscriberConfig = { - event: "user.created", - } - ``` +export const config: SubscriberConfig = { + event: "user.created", +} +``` - ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} - import { MedusaContainer } from "@medusajs/framework/types" - import { createSalesChannelWorkflow } from "../workflows/create-sales-channel" +```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} +import { MedusaContainer } from "@medusajs/framework/types" +import { createSalesChannelWorkflow } from "../workflows/create-sales-channel" - export default async function myCustomJob( - container: MedusaContainer - ) { - const { result } = await createSalesChannelWorkflow(container) - .run() +export default async function myCustomJob( + container: MedusaContainer +) { + const { result } = await createSalesChannelWorkflow(container) + .run() - console.log(result) - } + console.log(result) +} - export const config = { - name: "run-once-a-day", - schedule: `0 0 * * *`, - }; - ``` +export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, +} +``` diff --git a/www/apps/resources/app/commerce-modules/stock-location/links-to-other-modules/page.mdx b/www/apps/resources/app/commerce-modules/stock-location/links-to-other-modules/page.mdx index 1845c552476b5..2c617a959fab9 100644 --- a/www/apps/resources/app/commerce-modules/stock-location/links-to-other-modules/page.mdx +++ b/www/apps/resources/app/commerce-modules/stock-location/links-to-other-modules/page.mdx @@ -54,8 +54,8 @@ To retrieve the fulfillment providers, pass `fulfillment_providers.*` in `fields const { data: stockLocations } = await query.graph({ entity: "stock_location", fields: [ - "fulfillment_sets.*" - ] + "fulfillment_sets.*", + ], }) // stockLocations.fulfillment_sets @@ -72,8 +72,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: stockLocations } = useQueryGraphStep({ entity: "stock_location", fields: [ - "fulfillment_sets.*" - ] + "fulfillment_sets.*", + ], }) // stockLocations.fulfillment_sets @@ -143,8 +143,8 @@ To retrieve the inventory levels of a stock location with [Query](!docs!/learn/f const { data: stockLocations } = await query.graph({ entity: "stock_location", fields: [ - "inventory_levels.*" - ] + "inventory_levels.*", + ], }) // stockLocations.inventory_levels @@ -161,8 +161,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: stockLocations } = useQueryGraphStep({ entity: "stock_location", fields: [ - "inventory_levels.*" - ] + "inventory_levels.*", + ], }) // stockLocations.inventory_levels @@ -192,8 +192,8 @@ To retrieve the sales channels of a stock location with [Query](!docs!/learn/fun const { data: stockLocations } = await query.graph({ entity: "stock_location", fields: [ - "sales_channels.*" - ] + "sales_channels.*", + ], }) // stockLocations.sales_channels @@ -210,8 +210,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: stockLocations } = useQueryGraphStep({ entity: "stock_location", fields: [ - "sales_channels.*" - ] + "sales_channels.*", + ], }) // stockLocations.sales_channels diff --git a/www/apps/resources/app/commerce-modules/stock-location/page.mdx b/www/apps/resources/app/commerce-modules/stock-location/page.mdx index 278cc85579199..ca17c0c0e58e4 100644 --- a/www/apps/resources/app/commerce-modules/stock-location/page.mdx +++ b/www/apps/resources/app/commerce-modules/stock-location/page.mdx @@ -56,6 +56,9 @@ const createStockLocationStep = createStep( return new StepResponse({ stockLocation }, stockLocation.id) }, async (stockLocationId, { container }) => { + if (!stockLocationId) { + return + } const stockLocationModuleService = container.resolve(Modules.STOCK_LOCATION) await stockLocationModuleService.deleteStockLocations([stockLocationId]) @@ -77,70 +80,70 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import type { - MedusaRequest, - MedusaResponse, - } from "@medusajs/framework/http" - import { createStockLocationWorkflow } from "../../workflows/create-stock-location" - - export async function GET( - req: MedusaRequest, - res: MedusaResponse - ) { - const { result } = await createStockLocationWorkflow(req.scope) - .run() - - res.send(result) - } - ``` +```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import type { + MedusaRequest, + MedusaResponse, +} from "@medusajs/framework/http" +import { createStockLocationWorkflow } from "../../workflows/create-stock-location" + +export async function GET( + req: MedusaRequest, + res: MedusaResponse +) { + const { result } = await createStockLocationWorkflow(req.scope) + .run() + + res.send(result) +} +``` - ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import { - type SubscriberConfig, - type SubscriberArgs, - } from "@medusajs/framework" - import { createStockLocationWorkflow } from "../workflows/create-stock-location" - - export default async function handleUserCreated({ - event: { data }, - container, - }: SubscriberArgs<{ id: string }>) { - const { result } = await createStockLocationWorkflow(container) - .run() - - console.log(result) - } +```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import { + type SubscriberConfig, + type SubscriberArgs, +} from "@medusajs/framework" +import { createStockLocationWorkflow } from "../workflows/create-stock-location" + +export default async function handleUserCreated({ + event: { data }, + container, +}: SubscriberArgs<{ id: string }>) { + const { result } = await createStockLocationWorkflow(container) + .run() + + console.log(result) +} - export const config: SubscriberConfig = { - event: "user.created", - } - ``` +export const config: SubscriberConfig = { + event: "user.created", +} +``` - ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} - import { MedusaContainer } from "@medusajs/framework/types" - import { createStockLocationWorkflow } from "../workflows/create-stock-location" +```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} +import { MedusaContainer } from "@medusajs/framework/types" +import { createStockLocationWorkflow } from "../workflows/create-stock-location" - export default async function myCustomJob( - container: MedusaContainer - ) { - const { result } = await createStockLocationWorkflow(container) - .run() +export default async function myCustomJob( + container: MedusaContainer +) { + const { result } = await createStockLocationWorkflow(container) + .run() - console.log(result) - } + console.log(result) +} - export const config = { - name: "run-once-a-day", - schedule: `0 0 * * *`, - }; - ``` +export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, +} +``` diff --git a/www/apps/resources/app/commerce-modules/store/links-to-other-modules/page.mdx b/www/apps/resources/app/commerce-modules/store/links-to-other-modules/page.mdx index a9710b966b2d5..10132231b342b 100644 --- a/www/apps/resources/app/commerce-modules/store/links-to-other-modules/page.mdx +++ b/www/apps/resources/app/commerce-modules/store/links-to-other-modules/page.mdx @@ -39,8 +39,8 @@ To retrieve the details of a store's currencies with [Query](!docs!/learn/fundam const { data: stores } = await query.graph({ entity: "store", fields: [ - "supported_currencies.currency.*" - ] + "supported_currencies.currency.*", + ], }) // stores.supported_currencies @@ -57,8 +57,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows" const { data: stores } = useQueryGraphStep({ entity: "store", fields: [ - "supported_currencies.currency.*" - ] + "supported_currencies.currency.*", + ], }) // stores.supported_currencies diff --git a/www/apps/resources/app/commerce-modules/store/page.mdx b/www/apps/resources/app/commerce-modules/store/page.mdx index 7287b367c6746..94edf8071c18c 100644 --- a/www/apps/resources/app/commerce-modules/store/page.mdx +++ b/www/apps/resources/app/commerce-modules/store/page.mdx @@ -51,12 +51,18 @@ const createStoreStep = createStep( const store = await storeModuleService.createStores({ name: "My Store", - supported_currency_codes: ["usd"], + supported_currencies: [{ + currency_code: "usd", + is_default: true, + }], }) return new StepResponse({ store }, store.id) }, async (storeId, { container }) => { + if(!storeId) { + return + } const storeModuleService = container.resolve(Modules.STORE) await storeModuleService.deleteStores([storeId]) @@ -78,70 +84,70 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import type { - MedusaRequest, - MedusaResponse, - } from "@medusajs/framework/http" - import { createStoreWorkflow } from "../../workflows/create-store" - - export async function GET( - req: MedusaRequest, - res: MedusaResponse - ) { - const { result } = await createStoreWorkflow(req.scope) - .run() - - res.send(result) - } - ``` +```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import type { + MedusaRequest, + MedusaResponse, +} from "@medusajs/framework/http" +import { createStoreWorkflow } from "../../workflows/create-store" + +export async function GET( + req: MedusaRequest, + res: MedusaResponse +) { + const { result } = await createStoreWorkflow(req.scope) + .run() + + res.send(result) +} +``` - ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import { - type SubscriberConfig, - type SubscriberArgs, - } from "@medusajs/framework" - import { createStoreWorkflow } from "../workflows/create-store" - - export default async function handleUserCreated({ - event: { data }, - container, - }: SubscriberArgs<{ id: string }>) { - const { result } = await createStoreWorkflow(container) - .run() - - console.log(result) - } +```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import { + type SubscriberConfig, + type SubscriberArgs, +} from "@medusajs/framework" +import { createStoreWorkflow } from "../workflows/create-store" + +export default async function handleUserCreated({ + event: { data }, + container, +}: SubscriberArgs<{ id: string }>) { + const { result } = await createStoreWorkflow(container) + .run() + + console.log(result) +} - export const config: SubscriberConfig = { - event: "user.created", - } - ``` +export const config: SubscriberConfig = { + event: "user.created", +} +``` - ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} - import { MedusaContainer } from "@medusajs/framework/types" - import { createStoreWorkflow } from "../workflows/create-store" +```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} +import { MedusaContainer } from "@medusajs/framework/types" +import { createStoreWorkflow } from "../workflows/create-store" - export default async function myCustomJob( - container: MedusaContainer - ) { - const { result } = await createStoreWorkflow(container) - .run() +export default async function myCustomJob( + container: MedusaContainer +) { + const { result } = await createStoreWorkflow(container) + .run() - console.log(result) - } + console.log(result) +} - export const config = { - name: "run-once-a-day", - schedule: `0 0 * * *`, - }; - ``` +export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, +} +``` diff --git a/www/apps/resources/app/commerce-modules/tax/page.mdx b/www/apps/resources/app/commerce-modules/tax/page.mdx index 76d079d453336..3e8f85dc0a906 100644 --- a/www/apps/resources/app/commerce-modules/tax/page.mdx +++ b/www/apps/resources/app/commerce-modules/tax/page.mdx @@ -57,6 +57,9 @@ const createTaxRegionStep = createStep( return new StepResponse({ taxRegion }, taxRegion.id) }, async (taxRegionId, { container }) => { + if (!taxRegionId) { + return + } const taxModuleService = container.resolve(Modules.TAX) await taxModuleService.deleteTaxRegions([taxRegionId]) @@ -78,70 +81,70 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import type { - MedusaRequest, - MedusaResponse, - } from "@medusajs/framework/http" - import { createTaxRegionWorkflow } from "../../workflows/create-tax-region" - - export async function GET( - req: MedusaRequest, - res: MedusaResponse - ) { - const { result } = await createTaxRegionWorkflow(req.scope) - .run() - - res.send(result) - } - ``` +```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import type { + MedusaRequest, + MedusaResponse, +} from "@medusajs/framework/http" +import { createTaxRegionWorkflow } from "../../workflows/create-tax-region" + +export async function GET( + req: MedusaRequest, + res: MedusaResponse +) { + const { result } = await createTaxRegionWorkflow(req.scope) + .run() + + res.send(result) +} +``` - ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import { - type SubscriberConfig, - type SubscriberArgs, - } from "@medusajs/framework" - import { createTaxRegionWorkflow } from "../workflows/create-tax-region" - - export default async function handleUserCreated({ - event: { data }, - container, - }: SubscriberArgs<{ id: string }>) { - const { result } = await createTaxRegionWorkflow(container) - .run() - - console.log(result) - } +```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import { + type SubscriberConfig, + type SubscriberArgs, +} from "@medusajs/framework" +import { createTaxRegionWorkflow } from "../workflows/create-tax-region" + +export default async function handleUserCreated({ + event: { data }, + container, +}: SubscriberArgs<{ id: string }>) { + const { result } = await createTaxRegionWorkflow(container) + .run() + + console.log(result) +} - export const config: SubscriberConfig = { - event: "user.created", - } - ``` +export const config: SubscriberConfig = { + event: "user.created", +} +``` - ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} - import { MedusaContainer } from "@medusajs/framework/types" - import { createTaxRegionWorkflow } from "../workflows/create-tax-region" +```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} +import { MedusaContainer } from "@medusajs/framework/types" +import { createTaxRegionWorkflow } from "../workflows/create-tax-region" - export default async function myCustomJob( - container: MedusaContainer - ) { - const { result } = await createTaxRegionWorkflow(container) - .run() +export default async function myCustomJob( + container: MedusaContainer +) { + const { result } = await createTaxRegionWorkflow(container) + .run() - console.log(result) - } + console.log(result) +} - export const config = { - name: "run-once-a-day", - schedule: `0 0 * * *`, - }; - ``` +export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, +} +``` diff --git a/www/apps/resources/app/commerce-modules/user/page.mdx b/www/apps/resources/app/commerce-modules/user/page.mdx index 69f661d640cca..d563e51fd56e7 100644 --- a/www/apps/resources/app/commerce-modules/user/page.mdx +++ b/www/apps/resources/app/commerce-modules/user/page.mdx @@ -58,6 +58,9 @@ const createUserStep = createStep( return new StepResponse({ user }, user.id) }, async (userId, { container }) => { + if (!userId) { + return + } const userModuleService = container.resolve(Modules.USER) await userModuleService.deleteUsers([userId]) @@ -81,70 +84,70 @@ You can then execute the workflow in your custom API routes, scheduled jobs, or - ```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import type { - MedusaRequest, - MedusaResponse, - } from "@medusajs/framework/http" - import { createUserWorkflow } from "../../workflows/create-user" - - export async function GET( - req: MedusaRequest, - res: MedusaResponse - ) { - const { result } = await createUserWorkflow(req.scope) - .run() - - res.send(result) - } - ``` +```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import type { + MedusaRequest, + MedusaResponse, +} from "@medusajs/framework/http" +import { createUserWorkflow } from "../../workflows/create-user" + +export async function GET( + req: MedusaRequest, + res: MedusaResponse +) { + const { result } = await createUserWorkflow(req.scope) + .run() + + res.send(result) +} +``` - ```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" - import { - type SubscriberConfig, - type SubscriberArgs, - } from "@medusajs/framework" - import { createUserWorkflow } from "../workflows/create-user" - - export default async function handleUserCreated({ - event: { data }, - container, - }: SubscriberArgs<{ id: string }>) { - const { result } = await createUserWorkflow(container) - .run() - - console.log(result) - } +```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports" +import { + type SubscriberConfig, + type SubscriberArgs, +} from "@medusajs/framework" +import { createUserWorkflow } from "../workflows/create-user" + +export default async function handleUserCreated({ + event: { data }, + container, +}: SubscriberArgs<{ id: string }>) { + const { result } = await createUserWorkflow(container) + .run() + + console.log(result) +} - export const config: SubscriberConfig = { - event: "user.created", - } - ``` +export const config: SubscriberConfig = { + event: "user.created", +} +``` - ```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} - import { MedusaContainer } from "@medusajs/framework/types" - import { createUserWorkflow } from "../workflows/create-user" +```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]} +import { MedusaContainer } from "@medusajs/framework/types" +import { createUserWorkflow } from "../workflows/create-user" - export default async function myCustomJob( - container: MedusaContainer - ) { - const { result } = await createUserWorkflow(container) - .run() +export default async function myCustomJob( + container: MedusaContainer +) { + const { result } = await createUserWorkflow(container) + .run() - console.log(result) - } + console.log(result) +} - export const config = { - name: "run-once-a-day", - schedule: `0 0 * * *`, - }; - ``` +export const config = { + name: "run-once-a-day", + schedule: `0 0 * * *`, +} +```