From c6dff873de72e5367c083a595b94a94d517b3f3e Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Mon, 13 Nov 2023 20:11:50 +0200 Subject: [PATCH] docs: update docusaurus to v3 (#5625) * update dependencies * update onboarding mdx * fixes for mdx issues * fixes for mdx compatibility * resolve mdx errors * fixes in reference * fix check errors * revert change in vale action * fix node version in action * fix summary in markdown --- .github/workflows/docs-test.yml | 2 +- docs-util/packages/typedoc-config/entities.js | 6 + .../packages/typedoc-config/js-client.js | 4 + .../src/resources/helpers/comment.ts | 3 + .../resources/helpers/declaration-title.ts | 9 +- .../src/resources/helpers/reflection-title.ts | 2 +- .../src/resources/helpers/signature-title.ts | 46 +- .../src/resources/partials/comment.hbs | 2 +- .../resources/partials/member.declaration.hbs | 20 +- .../src/types.ts | 4 +- .../src/utils.ts | 16 +- .../src/utils/reflection-formatter.ts | 19 +- .../src/utils/return-reflection-formatter.ts | 2 +- .../src/utils/type-utils.ts | 226 +- .../src/feature-flags/utils/flag-router.ts | 4 +- www/apps/docs/content/admin/onboarding.md | 2012 ------- www/apps/docs/content/admin/onboarding.mdx | 1981 +++++++ www/apps/docs/content/contribution/docs.md | 32 +- www/apps/docs/content/create-medusa-app.mdx | 89 +- .../server/deploying-on-railway.md | 4 +- .../storefront/deploying-next-on-vercel.mdx | 4 +- .../api-routes/create-express-route.mdx | 754 +-- .../content/development/api-routes/create.mdx | 266 +- .../backend/prepare-environment.mdx | 166 +- .../content/development/batch-jobs/create.mdx | 192 +- .../content/development/entities/create.mdx | 106 +- .../content/development/plugins/create.mdx | 45 +- .../content/development/plugins/publish.mdx | 48 +- .../admin/manage-publishable-api-keys.mdx | 962 ++-- .../development/services/create-service.mdx | 418 +- www/apps/docs/content/js-client/overview.mdx | 202 +- .../docs/content/medusa-react/overview.mdx | 192 +- .../storefront/implement-cart.mdx | 770 +-- .../storefront/implement-checkout-flow.mdx | 758 +-- .../admin/manage-customer-groups.mdx | 992 ++-- .../customers/admin/manage-customers.mdx | 380 +- .../implement-customer-profiles.mdx | 754 +-- .../discounts/admin/manage-discounts.mdx | 940 ++-- .../storefront/use-discounts-in-checkout.mdx | 164 +- .../gift-cards/admin/manage-gift-cards.mdx | 1014 ++-- .../gift-cards/storefront/use-gift-cards.mdx | 316 +- .../admin/manage-inventory-items.mdx | 968 ++-- .../manage-item-allocations-in-orders.mdx | 828 +-- .../admin/manage-reservations.mdx | 422 +- .../admin/manage-stock-locations.mdx | 742 +-- .../modules/orders/admin/edit-order.mdx | 911 ++-- .../modules/orders/admin/manage-claims.mdx | 770 +-- .../orders/admin/manage-draft-orders.mdx | 1022 ++-- .../modules/orders/admin/manage-orders.mdx | 1481 +++--- .../modules/orders/admin/manage-returns.mdx | 764 +-- .../modules/orders/admin/manage-swaps.mdx | 594 +-- .../orders/storefront/create-return.mdx | 228 +- .../modules/orders/storefront/create-swap.mdx | 220 +- .../orders/storefront/handle-order-edits.mdx | 426 +- .../storefront/implement-claim-order.mdx | 178 +- .../storefront/retrieve-order-details.mdx | 246 +- .../price-lists/admin/_import-prices.mdx | 557 +- .../price-lists/admin/manage-price-lists.mdx | 870 +-- .../products/admin/import-products.mdx | 2022 ++++--- .../products/admin/manage-categories.mdx | 849 ++- .../products/admin/manage-products.mdx | 1452 ++--- .../products/{products.md => products.mdx} | 6 +- ...erless-module.md => serverless-module.mdx} | 6 +- .../products/storefront/show-products.mdx | 1058 ++-- .../products/storefront/use-categories.mdx | 440 +- .../admin/manage-currencies.mdx | 484 +- .../admin/manage-regions.mdx | 634 +-- .../storefront/use-regions.mdx | 262 +- .../modules/sales-channels/admin/manage.mdx | 1046 ++-- .../storefront/use-sales-channels.mdx | 283 +- .../modules/taxes/admin/manage-tax-rates.mdx | 1400 ++--- .../taxes/admin/manage-tax-settings.mdx | 352 +- .../modules/users/admin/manage-invites.mdx | 512 +- .../modules/users/admin/manage-profile.mdx | 620 +-- .../modules/users/admin/manage-users.mdx | 404 +- .../content/modules/users/backend/rbac.mdx | 1128 ++-- .../cms/{contentful.md => contentful.mdx} | 514 +- .../plugins/notifications/sendgrid.mdx | 98 +- www/apps/docs/content/recipes/b2b.mdx | 96 +- .../content/recipes/commerce-automation.mdx | 562 +- .../docs/content/recipes/digital-products.mdx | 3510 ++++++------ www/apps/docs/content/recipes/marketplace.mdx | 306 +- www/apps/docs/content/recipes/pos.mdx | 74 +- .../references/entities/classes/Address.mdx | 6 +- .../references/entities/classes/BatchJob.mdx | 16 +- .../references/entities/classes/Cart.mdx | 30 +- .../entities/classes/ClaimImage.mdx | 18 +- .../references/entities/classes/ClaimItem.mdx | 74 +- .../entities/classes/ClaimOrder.mdx | 22 +- .../references/entities/classes/ClaimTag.mdx | 2 +- .../references/entities/classes/Country.mdx | 16 +- .../entities/classes/CustomShippingOption.mdx | 54 +- .../references/entities/classes/Customer.mdx | 78 +- .../entities/classes/CustomerGroup.mdx | 24 +- .../references/entities/classes/Discount.mdx | 40 +- .../entities/classes/DiscountCondition.mdx | 76 +- .../DiscountConditionCustomerGroup.mdx | 44 +- .../classes/DiscountConditionProduct.mdx | 58 +- .../DiscountConditionProductCollection.mdx | 38 +- .../classes/DiscountConditionProductTag.mdx | 36 +- .../classes/DiscountConditionProductType.mdx | 36 +- .../entities/classes/DiscountRule.mdx | 38 +- .../entities/classes/DraftOrder.mdx | 8 +- .../entities/classes/Fulfillment.mdx | 122 +- .../entities/classes/FulfillmentItem.mdx | 40 +- .../entities/classes/FulfillmentProvider.mdx | 2 +- .../references/entities/classes/GiftCard.mdx | 70 +- .../entities/classes/GiftCardTransaction.mdx | 60 +- .../entities/classes/IdempotencyKey.mdx | 4 +- .../references/entities/classes/Image.mdx | 2 +- .../references/entities/classes/Invite.mdx | 4 +- .../references/entities/classes/LineItem.mdx | 20 +- .../entities/classes/LineItemAdjustment.mdx | 6 +- .../entities/classes/LineItemTaxLine.mdx | 4 +- .../entities/classes/MoneyAmount.mdx | 48 +- .../references/entities/classes/Note.mdx | 8 +- .../entities/classes/Notification.mdx | 42 +- .../entities/classes/NotificationProvider.mdx | 2 +- .../references/entities/classes/Oauth.mdx | 2 +- .../references/entities/classes/Order.mdx | 50 +- .../references/entities/classes/OrderEdit.mdx | 10 +- .../entities/classes/OrderItemChange.mdx | 8 +- .../references/entities/classes/Payment.mdx | 116 +- .../entities/classes/PaymentCollection.mdx | 46 +- .../entities/classes/PaymentProvider.mdx | 2 +- .../entities/classes/PaymentSession.mdx | 36 +- .../references/entities/classes/PriceList.mdx | 24 +- .../references/entities/classes/Product.mdx | 86 +- .../entities/classes/ProductCategory.mdx | 44 +- .../entities/classes/ProductCollection.mdx | 28 +- .../entities/classes/ProductOption.mdx | 36 +- .../entities/classes/ProductOptionValue.mdx | 24 +- .../entities/classes/ProductTag.mdx | 2 +- .../entities/classes/ProductTaxRate.mdx | 40 +- .../entities/classes/ProductType.mdx | 2 +- .../entities/classes/ProductTypeTaxRate.mdx | 18 +- .../entities/classes/ProductVariant.mdx | 54 +- .../classes/ProductVariantInventoryItem.mdx | 14 +- .../references/entities/classes/Refund.mdx | 68 +- .../references/entities/classes/Region.mdx | 22 +- .../references/entities/classes/Return.mdx | 136 +- .../entities/classes/ReturnItem.mdx | 50 +- .../entities/classes/ReturnReason.mdx | 12 +- .../entities/classes/SalesChannel.mdx | 6 +- .../entities/classes/SalesChannelLocation.mdx | 6 +- .../entities/classes/ShippingMethod.mdx | 180 +- .../classes/ShippingMethodTaxLine.mdx | 20 +- .../entities/classes/ShippingOption.mdx | 50 +- .../classes/ShippingOptionRequirement.mdx | 24 +- .../entities/classes/ShippingProfile.mdx | 54 +- .../entities/classes/ShippingTaxRate.mdx | 34 +- .../references/entities/classes/StagedJob.mdx | 4 +- .../references/entities/classes/Store.mdx | 16 +- .../references/entities/classes/Swap.mdx | 24 +- .../references/entities/classes/TaxLine.mdx | 2 +- .../entities/classes/TaxProvider.mdx | 2 +- .../references/entities/classes/TaxRate.mdx | 68 +- .../entities/classes/TrackingLink.mdx | 20 +- .../references/entities/classes/User.mdx | 4 +- .../entities/enums/AllocationType.mdx | 4 +- .../entities/enums/BatchJobStatus.mdx | 14 +- .../references/entities/enums/CartType.mdx | 10 +- .../entities/enums/ClaimFulfillmentStatus.mdx | 18 +- .../entities/enums/ClaimPaymentStatus.mdx | 6 +- .../references/entities/enums/ClaimReason.mdx | 8 +- .../references/entities/enums/ClaimType.mdx | 4 +- .../enums/DiscountConditionOperator.mdx | 4 +- .../entities/enums/DiscountConditionType.mdx | 10 +- .../entities/enums/DiscountRuleType.mdx | 6 +- .../entities/enums/DraftOrderStatus.mdx | 4 +- .../entities/enums/FulfillmentStatus.mdx | 18 +- .../enums/OrderEditItemChangeType.mdx | 6 +- .../entities/enums/OrderEditStatus.mdx | 10 +- .../references/entities/enums/OrderStatus.mdx | 10 +- .../enums/PaymentCollectionStatus.mdx | 10 +- .../entities/enums/PaymentCollectionType.mdx | 2 +- .../entities/enums/PaymentSessionStatus.mdx | 10 +- .../entities/enums/PaymentStatus.mdx | 14 +- .../entities/enums/PriceListStatus.mdx | 4 +- .../entities/enums/PriceListType.mdx | 4 +- .../entities/enums/ProductStatus.mdx | 8 +- .../entities/enums/RefundReason.mdx | 10 +- .../entities/enums/RequirementType.mdx | 4 +- .../entities/enums/ReturnStatus.mdx | 8 +- .../enums/ShippingOptionPriceType.mdx | 4 +- .../entities/enums/ShippingProfileType.mdx | 6 +- .../entities/enums/SwapFulfillmentStatus.mdx | 12 +- .../entities/enums/SwapPaymentStatus.mdx | 18 +- .../references/entities/enums/UserRoles.mdx | 6 +- .../content/references/entities/index.mdx | 2 +- .../entities/types/BatchJobResultError.mdx | 4 +- .../types/BatchJobResultStatDescriptor.mdx | 2 +- .../references/entities/types/Record.mdx | 4 +- ...artWorkflow.CreateCartWorkflowInputDTO.mdx | 6 +- ....internal-1.CommonTypes.AddressPayload.mdx | 2 +- ...ternal-1.CommonTypes.CustomFindOptions.mdx | 4 +- ...ernal-1.CommonTypes.ExtendedFindConfig.mdx | 4 +- ...l-1.CommonTypes.HttpCompressionOptions.mdx | 4 +- ...nal.internal-1.CommonTypes.PartialPick.mdx | 4 +- ...nal-1.CommonTypes.ProjectConfigOptions.mdx | 10 +- ...nal.internal-1.CommonTypes.QueryConfig.mdx | 8 +- ...l.internal-1.CommonTypes.QuerySelector.mdx | 4 +- ...ernal-1.CommonTypes.RequestQueryFields.mdx | 4 +- ...ternal.internal-1.CommonTypes.Selector.mdx | 4 +- ...rnal.internal-1.CommonTypes.TotalField.mdx | 2 - ...ternal-1.CommonTypes.TreeQuerySelector.mdx | 4 +- ...nal-1.CommonTypes.WithRequiredProperty.mdx | 4 +- ...ternal.internal-1.CommonTypes.Writable.mdx | 4 +- ...internal.internal-1.DAL.BaseFilterable.mdx | 4 +- .../internal.internal-1.DAL.OptionsQuery.mdx | 4 +- ...ernal.internal-1.DAL.RepositoryService.mdx | 40 +- ...l.internal-1.DAL.TreeRepositoryService.mdx | 30 +- ...ernal.internal-1.DAL.EntityDateColumns.mdx | 2 - .../internal.internal-1.DAL.FilterQuery.mdx | 4 +- .../internal.internal-1.DAL.FindOptions.mdx | 10 +- ...l-1.DAL.SoftDeletableEntityDateColumns.mdx | 2 - ....internal-1.EventBusTypes.EventHandler.mdx | 8 +- ...l-1.EventBusTypes.SubscriberDescriptor.mdx | 6 +- ...EventEmitter.EventEmitterAsyncResource.mdx | 72 +- .../internal.EventEmitter.Abortable.mdx | 2 +- ...r.EventEmitterReferencingAsyncResource.mdx | 4 +- ...nternal-1.FeatureFlagTypes.IFlagRouter.mdx | 6 +- ....FeatureFlagTypes.FeatureFlagsResponse.mdx | 2 - ...ternal-1.FeatureFlagTypes.FlagSettings.mdx | 4 +- ...oryTypes.BulkUpdateInventoryLevelInput.mdx | 2 - ...nventoryTypes.CreateInventoryItemInput.mdx | 6 +- ...ventoryTypes.CreateInventoryLevelInput.mdx | 4 +- ...entoryTypes.CreateReservationItemInput.mdx | 6 +- ...toryTypes.FilterableInventoryItemProps.mdx | 8 +- ...oryTypes.FilterableInventoryLevelProps.mdx | 10 +- ...ryTypes.FilterableReservationItemProps.mdx | 8 +- ...ventoryTypes.UpdateInventoryLevelInput.mdx | 4 +- ...entoryTypes.UpdateReservationItemInput.mdx | 6 +- ...ryWorkflow.CreateInventoryItemInputDTO.mdx | 2 +- ...w.CreateInventoryItemsWorkflowInputDTO.mdx | 2 +- ...1.ModulesSdkTypes.MODULE_RESOURCE_TYPE.mdx | 4 - ...nternal-1.ModulesSdkTypes.MODULE_SCOPE.mdx | 4 - ...dkTypes.ModuleServiceInitializeOptions.mdx | 4 +- ...ulesSdkTypes.ExternalModuleDeclaration.mdx | 10 +- ...ulesSdkTypes.InternalModuleDeclaration.mdx | 12 +- ...1.ModulesSdkTypes.LinkModuleDefinition.mdx | 6 +- ...nternal-1.ModulesSdkTypes.LoadedModule.mdx | 2 - ...ternal-1.ModulesSdkTypes.LoaderOptions.mdx | 10 +- ...al.internal-1.ModulesSdkTypes.LogLevel.mdx | 2 - ...ternal-1.ModulesSdkTypes.LoggerOptions.mdx | 2 - ...nternal-1.ModulesSdkTypes.ModuleConfig.mdx | 2 - ...nal-1.ModulesSdkTypes.ModuleDefinition.mdx | 6 +- ...ternal-1.ModulesSdkTypes.ModuleExports.mdx | 14 +- ...l-1.ModulesSdkTypes.ModuleJoinerConfig.mdx | 2 - ...dulesSdkTypes.ModuleJoinerRelationship.mdx | 2 - ...1.ModulesSdkTypes.ModuleLoaderFunction.mdx | 10 +- ...nal-1.ModulesSdkTypes.ModuleResolution.mdx | 12 +- ...erviceInitializeCustomDataLayerOptions.mdx | 4 +- ...rnal-1.ModulesSdkTypes.ModulesResponse.mdx | 2 - ...l.internal-1.PricingTypes.AddPricesDTO.mdx | 2 +- ...al.internal-1.PricingTypes.AddRulesDTO.mdx | 2 +- ...al-1.PricingTypes.CreateMoneyAmountDTO.mdx | 2 +- ...ernal-1.PricingTypes.CreatePriceSetDTO.mdx | 4 +- ...cingTypes.CreatePriceSetMoneyAmountDTO.mdx | 4 +- ...PricingTypes.CreatePriceSetRuleTypeDTO.mdx | 4 +- ...nternal-1.PricingTypes.CreatePricesDTO.mdx | 4 +- ...ernal-1.PricingTypes.CreateRuleTypeDTO.mdx | 2 +- ...1.PricingTypes.FilterableCurrencyProps.mdx | 4 +- ...ricingTypes.FilterableMoneyAmountProps.mdx | 4 +- ....PricingTypes.FilterablePriceRuleProps.mdx | 4 +- ...pes.FilterablePriceSetMoneyAmountProps.mdx | 4 +- ...ilterablePriceSetMoneyAmountRulesProps.mdx | 4 +- ...1.PricingTypes.FilterablePriceSetProps.mdx | 6 +- ...gTypes.FilterablePriceSetRuleTypeProps.mdx | 4 +- ...1.PricingTypes.FilterableRuleTypeProps.mdx | 4 +- ...internal-1.PricingTypes.MoneyAmountDTO.mdx | 2 +- ...l.internal-1.PricingTypes.PriceRuleDTO.mdx | 4 +- ...al.internal-1.PricingTypes.PriceSetDTO.mdx | 4 +- ...-1.PricingTypes.PriceSetMoneyAmountDTO.mdx | 6 +- ...icingTypes.PriceSetMoneyAmountRulesDTO.mdx | 4 +- ...nal-1.PricingTypes.PriceSetRuleTypeDTO.mdx | 4 +- ...internal-1.PricingTypes.PricingContext.mdx | 2 +- ...al.internal-1.PricingTypes.RuleTypeDTO.mdx | 2 +- ...cingTypes.UpdatePriceSetMoneyAmountDTO.mdx | 4 +- ...ernal-1.PricingTypes.UpdateRuleTypeDTO.mdx | 2 +- ....internal-1.ProductTypes.ProductStatus.mdx | 8 - ....ProductTypes.CreateProductCategoryDTO.mdx | 2 +- ...roductTypes.CreateProductCollectionDTO.mdx | 2 +- ...ternal-1.ProductTypes.CreateProductDTO.mdx | 16 +- ...al-1.ProductTypes.CreateProductOnlyDTO.mdx | 10 +- ...roductTypes.CreateProductOptionOnlyDTO.mdx | 2 +- ...al-1.ProductTypes.CreateProductTypeDTO.mdx | 2 +- ...1.ProductTypes.CreateProductVariantDTO.mdx | 4 +- ...oductTypes.CreateProductVariantOnlyDTO.mdx | 4 +- ...ctTypes.FilterableProductCategoryProps.mdx | 4 +- ...Types.FilterableProductCollectionProps.mdx | 4 +- ...ductTypes.FilterableProductOptionProps.mdx | 4 +- ...-1.ProductTypes.FilterableProductProps.mdx | 10 +- ...ProductTypes.FilterableProductTagProps.mdx | 4 +- ...roductTypes.FilterableProductTypeProps.mdx | 4 +- ...uctTypes.FilterableProductVariantProps.mdx | 4 +- ...l-1.ProductTypes.IProductModuleService.mdx | 268 +- ...rnal-1.ProductTypes.ProductCategoryDTO.mdx | 4 +- ...al-1.ProductTypes.ProductCollectionDTO.mdx | 4 +- ...nal.internal-1.ProductTypes.ProductDTO.mdx | 18 +- ...nternal-1.ProductTypes.ProductImageDTO.mdx | 2 +- ...ternal-1.ProductTypes.ProductOptionDTO.mdx | 6 +- ...l-1.ProductTypes.ProductOptionValueDTO.mdx | 6 +- ....internal-1.ProductTypes.ProductTagDTO.mdx | 4 +- ...internal-1.ProductTypes.ProductTypeDTO.mdx | 2 +- ...ernal-1.ProductTypes.ProductVariantDTO.mdx | 6 +- ....ProductTypes.UpdateProductCategoryDTO.mdx | 2 +- ...roductTypes.UpdateProductCollectionDTO.mdx | 2 +- ...ternal-1.ProductTypes.UpdateProductDTO.mdx | 16 +- ...al-1.ProductTypes.UpdateProductTypeDTO.mdx | 2 +- ...1.ProductTypes.UpdateProductVariantDTO.mdx | 4 +- ...oductTypes.UpdateProductVariantOnlyDTO.mdx | 4 +- ....ProductWorkflow.CreateProductInputDTO.mdx | 16 +- ...tWorkflow.CreateProductVariantInputDTO.mdx | 6 +- ...orkflow.CreateProductsWorkflowInputDTO.mdx | 2 +- ....ProductWorkflow.UpdateProductInputDTO.mdx | 14 +- ...tWorkflow.UpdateProductVariantInputDTO.mdx | 6 +- ...Workflow.UpdateProductVariantsInputDTO.mdx | 6 +- ....UpdateProductVariantsWorkflowInputDTO.mdx | 2 +- ...orkflow.UpdateProductsWorkflowInputDTO.mdx | 2 +- ...al-1.SalesChannelTypes.SalesChannelDTO.mdx | 4 +- ...esChannelTypes.SalesChannelLocationDTO.mdx | 2 +- ....internal-1.SearchTypes.ISearchService.mdx | 6 +- ...l.internal-1.SearchTypes.IndexSettings.mdx | 8 +- ...LocationTypes.CreateStockLocationInput.mdx | 8 +- ...tionTypes.FilterableStockLocationProps.mdx | 6 +- ...kLocationTypes.StockLocationAddressDTO.mdx | 6 +- ...ocationTypes.StockLocationAddressInput.mdx | 6 +- ...LocationTypes.UpdateStockLocationInput.mdx | 8 +- .../js-client/classes/AddressesResource.mdx | 58 +- .../references/js-client/classes/Admin.mdx | 78 +- .../js-client/classes/AdminAuthResource.mdx | 34 +- .../classes/AdminBatchJobsResource.mdx | 94 +- .../classes/AdminCollectionsResource.mdx | 80 +- .../classes/AdminCurrenciesResource.mdx | 18 +- .../js-client/classes/AdminCustomResource.mdx | 18 +- .../classes/AdminCustomerGroupsResource.mdx | 124 +- .../classes/AdminCustomersResource.mdx | 78 +- .../classes/AdminDiscountsResource.mdx | 288 +- .../classes/AdminDraftOrdersResource.mdx | 212 +- .../classes/AdminGiftCardsResource.mdx | 64 +- .../classes/AdminInventoryItemsResource.mdx | 118 +- .../classes/AdminInvitesResource.mdx | 34 +- .../js-client/classes/AdminNotesResource.mdx | 52 +- .../classes/AdminNotificationsResource.mdx | 38 +- .../classes/AdminOrderEditsResource.mdx | 184 +- .../js-client/classes/AdminOrdersResource.mdx | 192 +- .../AdminPaymentCollectionsResource.mdx | 70 +- .../classes/AdminPaymentsResource.mdx | 54 +- .../classes/AdminPriceListResource.mdx | 186 +- .../AdminProductCategoriesResource.mdx | 118 +- .../classes/AdminProductTagsResource.mdx | 18 +- .../classes/AdminProductTypesResource.mdx | 20 +- .../classes/AdminProductsResource.mdx | 414 +- .../AdminPublishableApiKeyResource.mdx | 76 +- .../classes/AdminRegionsResource.mdx | 234 +- .../classes/AdminReservationsResource.mdx | 54 +- .../classes/AdminReturnReasonsResource.mdx | 60 +- .../classes/AdminReturnsResource.mdx | 108 +- .../classes/AdminSalesChannelsResource.mdx | 110 +- .../classes/AdminShippingOptionsResource.mdx | 122 +- .../classes/AdminShippingProfilesResource.mdx | 80 +- .../classes/AdminStockLocationsResource.mdx | 62 +- .../js-client/classes/AdminStoresResource.mdx | 106 +- .../js-client/classes/AdminSwapsResource.mdx | 64 +- .../classes/AdminTaxRatesResource.mdx | 204 +- .../classes/AdminUploadsResource.mdx | 28 +- .../js-client/classes/AdminUsersResource.mdx | 70 +- .../classes/AdminVariantsResource.mdx | 62 +- .../js-client/classes/AuthResource.mdx | 48 +- .../js-client/classes/CartsResource.mdx | 396 +- .../js-client/classes/CollectionsResource.mdx | 28 +- .../js-client/classes/CustomersResource.mdx | 162 +- .../js-client/classes/GiftCardsResource.mdx | 12 +- .../js-client/classes/LineItemsResource.mdx | 116 +- .../js-client/classes/OrderEditsResource.mdx | 50 +- .../js-client/classes/OrdersResource.mdx | 184 +- .../classes/PaymentCollectionsResource.mdx | 122 +- .../classes/PaymentMethodsResource.mdx | 8 +- .../classes/ProductCategoriesResource.mdx | 40 +- .../js-client/classes/ProductTagsResource.mdx | 20 +- .../classes/ProductTypesResource.mdx | 20 +- .../classes/ProductVariantsResource.mdx | 48 +- .../js-client/classes/ProductsResource.mdx | 80 +- .../js-client/classes/RegionsResource.mdx | 44 +- .../classes/ReturnReasonsResource.mdx | 24 +- .../js-client/classes/ReturnsResource.mdx | 28 +- .../classes/ShippingOptionsResource.mdx | 54 +- .../js-client/classes/SwapsResource.mdx | 66 +- .../internal.internal-1.ILinkModule.mdx | 44 +- ...nternal.internal-1.JoinerServiceConfig.mdx | 12 +- ...al.internal-1.JoinerServiceConfigAlias.mdx | 2 +- ...ternal.internal-1.RemoteExpandProperty.mdx | 8 +- .../internal.internal-1.RemoteJoinerQuery.mdx | 4 +- ...nternal.internal-1.RemoteNestedExpands.mdx | 4 - .../types/internal.internal-1.AddressDTO.mdx | 6 +- .../types/internal.internal-1.CartDTO.mdx | 8 +- ...internal.internal-1.JoinerRelationship.mdx | 6 +- .../internal.internal-1.SharedContext.mdx | 4 +- .../classes/internal.internal-3.Writable.mdx | 346 +- .../internal.internal-3.FinishedOptions.mdx | 2 +- .../internal.internal-3.PipelineOptions.mdx | 2 +- .../internal.internal-3.StreamOptions.mdx | 10 +- .../internal.internal-3.WritableOptions.mdx | 30 +- .../modules/internal.internal-3.finished.mdx | 6 +- .../modules/internal.internal-3.pipeline.mdx | 48 +- .../internal.internal-3.PipelineCallback.mdx | 6 +- ...nternal.internal-3.PipelineDestination.mdx | 6 +- ...-3.PipelineDestinationIterableFunction.mdx | 10 +- ...l-3.PipelineDestinationPromiseFunction.mdx | 10 +- .../internal.internal-3.PipelinePromise.mdx | 6 +- .../internal.internal-3.PipelineSource.mdx | 4 +- ...rnal.internal-3.PipelineSourceFunction.mdx | 10 +- .../internal.internal-3.PipelineTransform.mdx | 6 +- ...nal.internal-3.PipelineTransformSource.mdx | 4 +- ...internal.AbstractEventBusModuleService.mdx | 32 +- .../internal.AbstractSearchService.mdx | 6 +- .../internal/classes/internal.Address.mdx | 6 +- .../classes/internal.AddressPayload.mdx | 2 +- .../internal.AdminCreateUserRequest.mdx | 2 +- ...eteCustomerGroupsGroupCustomerBatchReq.mdx | 2 +- ...ntsDiscountConditionsConditionBatchReq.mdx | 2 +- ...ductCategoriesCategoryProductsBatchReq.mdx | 2 +- ...PublishableApiKeySalesChannelsBatchReq.mdx | 2 +- ...teSalesChannelsChannelProductsBatchReq.mdx | 2 +- .../classes/internal.AdminGetBatchParams.mdx | 14 +- .../internal.AdminGetCollectionsParams.mdx | 6 +- .../internal.AdminGetCustomerGroupsParams.mdx | 6 +- ...al.AdminGetDiscountsDiscountRuleParams.mdx | 4 +- .../internal.AdminGetDiscountsParams.mdx | 2 +- .../internal.AdminGetInventoryItemsParams.mdx | 10 +- .../classes/internal.AdminGetOrdersParams.mdx | 6 +- ...rnal.AdminGetPriceListPaginationParams.mdx | 10 +- ...inGetPriceListsPriceListProductsParams.mdx | 8 +- .../internal.AdminGetProductTagsParams.mdx | 8 +- .../internal.AdminGetProductTypesParams.mdx | 8 +- .../internal.AdminGetProductsParams.mdx | 8 +- .../internal.AdminGetRegionsParams.mdx | 6 +- ...nGetRegionsRegionFulfillmentOptionsRes.mdx | 2 +- .../internal.AdminGetReservationsParams.mdx | 6 +- .../internal.AdminGetSalesChannelsParams.mdx | 6 +- .../internal.AdminGetTaxRatesParams.mdx | 2 +- .../internal.AdminGetVariantsParams.mdx | 2 +- .../internal.AdminListOrdersSelector.mdx | 6 +- .../classes/internal.AdminPostBatchesReq.mdx | 4 +- ...rnal.AdminPostCollectionsCollectionReq.mdx | 2 +- .../internal.AdminPostCollectionsReq.mdx | 2 +- ...stCustomerGroupsGroupCustomersBatchReq.mdx | 2 +- ...ternal.AdminPostCustomerGroupsGroupReq.mdx | 2 +- .../internal.AdminPostCustomerGroupsReq.mdx | 2 +- ...internal.AdminPostCustomersCustomerReq.mdx | 4 +- .../internal.AdminPostCustomersReq.mdx | 2 +- ...l.AdminPostDiscountsDiscountConditions.mdx | 4 +- ...ntsDiscountConditionsConditionBatchReq.mdx | 2 +- ...inPostDiscountsDiscountDynamicCodesReq.mdx | 2 +- ...internal.AdminPostDiscountsDiscountReq.mdx | 4 +- ...nternal.AdminPostDiscountsDiscountRule.mdx | 6 +- .../internal.AdminPostDiscountsReq.mdx | 4 +- ...tDraftOrdersDraftOrderLineItemsItemReq.mdx | 6 +- ...nPostDraftOrdersDraftOrderLineItemsReq.mdx | 8 +- ...rnal.AdminPostDraftOrdersDraftOrderReq.mdx | 6 +- .../internal.AdminPostDraftOrdersReq.mdx | 12 +- ...internal.AdminPostGiftCardsGiftCardReq.mdx | 2 +- .../internal.AdminPostGiftCardsReq.mdx | 2 +- .../internal.AdminPostInventoryItemsReq.mdx | 2 +- ...ternal.AdminPostInvitesInviteAcceptReq.mdx | 2 +- .../classes/internal.AdminPostInvitesReq.mdx | 2 +- ...al.AdminPostOrderEditsEditLineItemsReq.mdx | 2 +- ...tOrdersOrderClaimsClaimFulfillmentsReq.mdx | 2 +- ...nal.AdminPostOrdersOrderClaimsClaimReq.mdx | 6 +- ...internal.AdminPostOrdersOrderClaimsReq.mdx | 12 +- ...al.AdminPostOrdersOrderFulfillmentsReq.mdx | 4 +- ...nternal.AdminPostOrdersOrderRefundsReq.mdx | 2 +- .../internal.AdminPostOrdersOrderReq.mdx | 12 +- ...nternal.AdminPostOrdersOrderReturnsReq.mdx | 4 +- ...AdminPostOrdersOrderShippingMethodsReq.mdx | 2 +- .../internal.AdminPostOrdersOrderSwapsReq.mdx | 8 +- ...ostOrdersOrderSwapsSwapFulfillmentsReq.mdx | 2 +- .../internal.AdminPostPaymentRefundsReq.mdx | 2 +- ...rnal.AdminPostPriceListPricesPricesReq.mdx | 2 +- ...minPostPriceListsPriceListPriceListReq.mdx | 8 +- ...ternal.AdminPostPriceListsPriceListReq.mdx | 8 +- ...ductCategoriesCategoryProductsBatchReq.mdx | 2 +- .../internal.AdminPostProductsProductReq.mdx | 14 +- ...al.AdminPostProductsProductVariantsReq.mdx | 6 +- ...nPostProductsProductVariantsVariantReq.mdx | 6 +- .../classes/internal.AdminPostProductsReq.mdx | 16 +- ...PublishableApiKeySalesChannelsBatchReq.mdx | 2 +- .../internal.AdminPostRegionsRegionReq.mdx | 2 +- .../classes/internal.AdminPostRegionsReq.mdx | 2 +- .../internal.AdminPostReservationsReq.mdx | 2 +- ...al.AdminPostReservationsReservationReq.mdx | 2 +- ...ternal.AdminPostReturnReasonsReasonReq.mdx | 2 +- .../internal.AdminPostReturnReasonsReq.mdx | 2 +- ...ernal.AdminPostReturnsReturnReceiveReq.mdx | 2 +- ...stSalesChannelsChannelProductsBatchReq.mdx | 2 +- ...rnal.AdminPostShippingOptionsOptionReq.mdx | 6 +- .../internal.AdminPostShippingOptionsReq.mdx | 8 +- ...al.AdminPostShippingProfilesProfileReq.mdx | 4 +- .../internal.AdminPostShippingProfilesReq.mdx | 4 +- ...nal.AdminPostStockLocationsLocationReq.mdx | 4 +- .../internal.AdminPostStockLocationsReq.mdx | 6 +- .../classes/internal.AdminPostStoreReq.mdx | 8 +- ...internal.AdminPriceListPricesCreateReq.mdx | 4 +- ...internal.AdminPriceListPricesUpdateReq.mdx | 4 +- .../internal.AdminUpdateDiscountRule.mdx | 4 +- ...ernal.AdminUpdatePaymentCollectionsReq.mdx | 2 +- .../internal.AdminUpdateUserRequest.mdx | 4 +- .../classes/internal.AsyncResource.mdx | 2 +- .../internal/classes/internal.Axios.mdx | 40 +- .../internal/classes/internal.BatchJob.mdx | 12 +- .../internal/classes/internal.Blob.mdx | 10 +- .../internal/classes/internal.Cart.mdx | 30 +- .../internal/classes/internal.ClaimOrder.mdx | 22 +- .../internal/classes/internal.Client.mdx | 30 +- .../internal/classes/internal.Customer.mdx | 10 +- .../classes/internal.CustomerGroup.mdx | 6 +- .../classes/internal.CustomerGroupUpdate.mdx | 2 +- .../internal/classes/internal.Discount-1.mdx | 8 +- .../classes/internal.DiscountCondition.mdx | 28 +- .../internal/classes/internal.DraftOrder.mdx | 8 +- .../internal/classes/internal.Duplex.mdx | 606 +-- .../classes/internal.EventEmitter-1.mdx | 70 +- .../classes/internal.FilterableCartProps.mdx | 6 +- .../internal.FilterableCustomerGroupProps.mdx | 6 +- .../internal.FilterableDiscountProps.mdx | 2 +- ...rnal.FilterableLineItemAdjustmentProps.mdx | 6 +- .../internal.FilterablePriceListProps.mdx | 10 +- .../internal.FilterableProductProps.mdx | 8 +- ...internal.FilterableProductVariantProps.mdx | 16 +- .../internal/classes/internal.FlagRouter.mdx | 12 +- .../internal/classes/internal.Fulfillment.mdx | 16 +- .../classes/internal.FulfillmentService.mdx | 84 +- .../internal/classes/internal.GiftCard-1.mdx | 6 +- .../classes/internal.GiftCardTransaction.mdx | 4 +- .../internal/classes/internal.Invite.mdx | 4 +- .../internal/classes/internal.Item-3.mdx | 8 +- .../internal/classes/internal.Item-5.mdx | 2 +- .../internal/classes/internal.Item-6.mdx | 6 +- .../internal/classes/internal.LineItem.mdx | 24 +- .../internal/classes/internal.MedusaError.mdx | 2 +- .../internal/classes/internal.Note.mdx | 4 +- .../classes/internal.Notification.mdx | 10 +- .../classes/internal.NotificationProvider.mdx | 2 +- .../internal/classes/internal.Order.mdx | 50 +- .../internal/classes/internal.OrderEdit.mdx | 12 +- .../classes/internal.OrderItemChange.mdx | 8 +- .../internal/classes/internal.PassThrough.mdx | 610 +-- .../internal/classes/internal.Payment.mdx | 12 +- .../classes/internal.PaymentCollection.mdx | 14 +- .../classes/internal.PaymentMethod.mdx | 2 +- .../classes/internal.PaymentProvider.mdx | 2 +- .../classes/internal.PaymentService.mdx | 50 +- .../classes/internal.PaymentSession.mdx | 6 +- .../internal/classes/internal.PriceList.mdx | 8 +- .../internal/classes/internal.Product.mdx | 24 +- .../classes/internal.ProductCategory.mdx | 10 +- .../classes/internal.ProductCollection.mdx | 4 +- .../internal/classes/internal.ProductTag.mdx | 2 +- .../internal/classes/internal.ProductType.mdx | 2 +- ...internal.ProductVariantPricesCreateReq.mdx | 4 +- ...internal.ProductVariantPricesUpdateReq.mdx | 4 +- .../classes/internal.ProductVariantReq-1.mdx | 6 +- .../classes/internal.ProductVariantReq.mdx | 6 +- .../internal/classes/internal.Readable.mdx | 430 +- .../classes/internal.ReadableBase.mdx | 422 +- .../internal/classes/internal.Refund.mdx | 6 +- .../internal/classes/internal.Region.mdx | 14 +- .../internal/classes/internal.Return.mdx | 16 +- .../classes/internal.ReturnReason.mdx | 6 +- .../classes/internal.SalesChannel.mdx | 4 +- .../classes/internal.ShippingMethod-1.mdx | 4 +- .../classes/internal.ShippingMethod-2.mdx | 2 +- .../classes/internal.ShippingMethod-3.mdx | 2 +- .../classes/internal.ShippingMethod-4.mdx | 16 +- .../classes/internal.ShippingMethod.mdx | 2 +- .../classes/internal.ShippingOption.mdx | 18 +- .../classes/internal.ShippingProfile.mdx | 12 +- .../internal/classes/internal.Socket.mdx | 606 +-- .../internal/classes/internal.Store.mdx | 12 +- .../internal.StoreGetCollectionsParams.mdx | 4 +- ....StoreGetCustomersCustomerOrdersParams.mdx | 12 +- .../classes/internal.StoreGetOrdersParams.mdx | 2 +- .../internal.StoreGetProductTagsParams.mdx | 8 +- .../internal.StoreGetProductTypesParams.mdx | 8 +- .../internal.StoreGetProductsParams.mdx | 4 +- .../internal.StoreGetVariantsParams.mdx | 2 +- .../classes/internal.StorePostCartReq.mdx | 4 +- ...nal.StorePostCartsCartLineItemsItemReq.mdx | 2 +- ...nternal.StorePostCartsCartLineItemsReq.mdx | 2 +- ...rePostCartsCartPaymentSessionUpdateReq.mdx | 2 +- .../internal.StorePostCartsCartReq.mdx | 10 +- ...al.StorePostCartsCartShippingMethodReq.mdx | 2 +- ...stCustomersCustomerAddressesAddressReq.mdx | 2 +- ...StorePostCustomersCustomerAddressesReq.mdx | 2 +- ...internal.StorePostCustomersCustomerReq.mdx | 4 +- ...PostPaymentCollectionsBatchSessionsReq.mdx | 2 +- .../classes/internal.StorePostReturnsReq.mdx | 4 +- .../classes/internal.StorePostSwapsReq.mdx | 4 +- .../internal/classes/internal.Stream.mdx | 74 +- .../internal/classes/internal.Swap.mdx | 24 +- .../internal/classes/internal.TaxLine.mdx | 2 +- .../internal/classes/internal.TaxProvider.mdx | 2 +- .../internal/classes/internal.TaxRate.mdx | 10 +- .../internal/classes/internal.Transform.mdx | 610 +-- .../internal/classes/internal.User.mdx | 4 +- .../classes/internal.WritableBase.mdx | 342 +- .../internal/classes/internal.internal-6.mdx | 74 +- ...rnal.internal.AbstractBatchJobStrategy.mdx | 44 +- ...nternal.AbstractCartCompletionStrategy.mdx | 32 +- .../internal.internal.AbstractFileService.mdx | 46 +- ...al.internal.AbstractFulfillmentService.mdx | 66 +- ...l.internal.AbstractNotificationService.mdx | 30 +- ...rnal.internal.AbstractPaymentProcessor.mdx | 48 +- ...ternal.internal.AbstractPaymentService.mdx | 100 +- ...nternal.AbstractPriceSelectionStrategy.mdx | 34 +- .../internal.internal.AbstractTaxService.mdx | 10 +- ...internal.internal.AdminCreateCondition.mdx | 2 +- ...internal.internal.AdminUpsertCondition.mdx | 2 +- ...ternal.internal.AnalyticsConfigService.mdx | 40 +- .../classes/internal.internal.AuthService.mdx | 38 +- .../internal.internal.BatchJobService.mdx | 90 +- .../classes/internal.internal.CartService.mdx | 250 +- .../classes/internal.internal.ClaimImage.mdx | 4 +- .../classes/internal.internal.ClaimItem.mdx | 14 +- .../internal.internal.ClaimItemService.mdx | 50 +- .../internal.internal.ClaimService.mdx | 96 +- .../classes/internal.internal.ClaimTag.mdx | 2 +- .../classes/internal.internal.Country.mdx | 2 +- .../internal.internal.CurrencyService.mdx | 42 +- ...internal.internal.CustomShippingOption.mdx | 6 +- ...l.internal.CustomShippingOptionService.mdx | 38 +- ...internal.internal.CustomerGroupService.mdx | 56 +- .../internal.internal.CustomerService.mdx | 98 +- ...nternal.DiscountConditionCustomerGroup.mdx | 6 +- ...rnal.internal.DiscountConditionProduct.mdx | 6 +- ...nal.DiscountConditionProductCollection.mdx | 6 +- ...l.internal.DiscountConditionProductTag.mdx | 6 +- ....internal.DiscountConditionProductType.mdx | 6 +- ...rnal.internal.DiscountConditionService.mdx | 48 +- .../internal.internal.DiscountRule.mdx | 10 +- .../internal.internal.DiscountService.mdx | 122 +- .../internal.internal.DraftOrderService.mdx | 68 +- .../internal.internal.EventBusService.mdx | 68 +- ...ernal.internal.FilterableBatchJobProps.mdx | 6 +- .../internal.internal.FulfillmentItem.mdx | 4 +- .../internal.internal.FulfillmentProvider.mdx | 2 +- ...al.internal.FulfillmentProviderService.mdx | 80 +- .../internal.internal.GiftCardService.mdx | 80 +- .../internal.internal.IdempotencyKey.mdx | 4 +- ...nternal.internal.IdempotencyKeyService.mdx | 48 +- .../classes/internal.internal.Image.mdx | 2 +- .../internal.internal.LineItemAdjustment.mdx | 6 +- ...nal.internal.LineItemAdjustmentService.mdx | 66 +- .../internal.internal.LineItemService.mdx | 86 +- .../internal.internal.LineItemTaxLine.mdx | 4 +- .../internal.internal.MiddlewareService.mdx | 30 +- .../classes/internal.internal.MoneyAmount.mdx | 10 +- .../internal.internal.NewTotalsService.mdx | 102 +- .../classes/internal.internal.NoteService.mdx | 54 +- .../internal.internal.NotificationService.mdx | 66 +- .../classes/internal.internal.Oauth.mdx | 2 +- .../internal.internal.OauthService.mdx | 54 +- ...al.internal.OrderEditItemChangeService.mdx | 48 +- .../internal.internal.OrderEditService.mdx | 100 +- .../internal.internal.OrderService.mdx | 212 +- ...rnal.internal.PaymentCollectionService.mdx | 64 +- ...ternal.internal.PaymentProviderService.mdx | 148 +- .../internal.internal.PriceListService.mdx | 98 +- .../internal.internal.PricingService.mdx | 186 +- ...ternal.internal.ProductCategoryService.mdx | 98 +- ...rnal.internal.ProductCollectionService.mdx | 62 +- .../internal.internal.ProductOption.mdx | 6 +- .../internal.internal.ProductOptionValue.mdx | 6 +- .../internal.internal.ProductService.mdx | 128 +- .../internal.internal.ProductTaxRate.mdx | 6 +- .../internal.internal.ProductTypeService.mdx | 42 +- .../internal.internal.ProductTypeTaxRate.mdx | 6 +- .../internal.internal.ProductVariant.mdx | 12 +- ...l.internal.ProductVariantInventoryItem.mdx | 2 +- ...nternal.ProductVariantInventoryService.mdx | 156 +- ...nternal.internal.ProductVariantService.mdx | 148 +- .../internal.internal.RegionService.mdx | 100 +- .../classes/internal.internal.ReturnItem.mdx | 8 +- .../internal.internal.ReturnReasonService.mdx | 46 +- .../internal.internal.ReturnService.mdx | 102 +- ....internal.SalesChannelInventoryService.mdx | 88 +- ...internal.internal.SalesChannelLocation.mdx | 2 +- ...l.internal.SalesChannelLocationService.mdx | 50 +- .../internal.internal.SalesChannelService.mdx | 70 +- .../internal.internal.SearchService.mdx | 22 +- ...nternal.internal.ShippingMethodTaxLine.mdx | 4 +- ...nal.internal.ShippingOptionRequirement.mdx | 6 +- ...nternal.internal.ShippingOptionService.mdx | 110 +- ...ternal.internal.ShippingProfileService.mdx | 82 +- .../internal.internal.ShippingTaxRate.mdx | 6 +- .../classes/internal.internal.StagedJob.mdx | 4 +- .../internal.internal.StagedJobService.mdx | 36 +- ...nternal.internal.StoreGetRegionsParams.mdx | 4 +- .../internal.internal.StoreService.mdx | 46 +- ...ernal.internal.StrategyResolverService.mdx | 28 +- .../classes/internal.internal.SwapService.mdx | 122 +- ....internal.SystemPaymentProviderService.mdx | 44 +- .../internal.internal.TaxProviderService.mdx | 88 +- .../internal.internal.TaxRateService.mdx | 76 +- .../internal.internal.TokenService.mdx | 4 +- .../internal.internal.TotalsService.mdx | 150 +- .../internal.internal.TrackingLink.mdx | 4 +- ...ternal.internal.TransactionBaseService.mdx | 24 +- .../classes/internal.internal.UserService.mdx | 62 +- .../internal/enums/internal.CartType.mdx | 10 - ...l.DiscountConditionJoinTableForeignKey.mdx | 10 - .../internal.DiscountConditionOperator.mdx | 4 - .../enums/internal.FulfillmentStatus-1.mdx | 18 - .../enums/internal.FulfillmentStatus.mdx | 18 - .../enums/internal.OrderEditStatus.mdx | 10 - .../internal/enums/internal.OrderStatus-1.mdx | 10 - .../internal/enums/internal.OrderStatus.mdx | 10 - .../internal.PaymentCollectionStatus.mdx | 10 - .../enums/internal.PaymentStatus-1.mdx | 14 - .../internal/enums/internal.PaymentStatus.mdx | 14 - .../enums/internal.PriceListStatus.mdx | 4 - .../internal/enums/internal.PriceListType.mdx | 4 - .../internal/enums/internal.ProductStatus.mdx | 8 - .../internal/enums/internal.RefundReason.mdx | 10 - .../enums/internal.ShippingProfileType.mdx | 6 - .../enums/internal.SwapFulfillmentStatus.mdx | 12 - .../enums/internal.SwapPaymentStatus.mdx | 18 - .../internal.internal.AllocationType.mdx | 4 - .../internal.internal.BatchJobStatus.mdx | 14 - ...ternal.internal.ClaimFulfillmentStatus.mdx | 18 - .../internal.internal.ClaimPaymentStatus.mdx | 6 - .../enums/internal.internal.ClaimReason.mdx | 8 - .../enums/internal.internal.ClaimType.mdx | 4 - ...nternal.internal.DiscountConditionType.mdx | 10 - .../internal.internal.DiscountRuleType.mdx | 6 - .../internal.internal.DraftOrderStatus.mdx | 4 - ...ernal.internal.OrderEditItemChangeType.mdx | 6 - ...internal.internal.PaymentSessionStatus.mdx | 10 - .../enums/internal.internal.PostgresError.mdx | 8 - .../internal.internal.RequirementType.mdx | 4 - .../enums/internal.internal.ReturnStatus.mdx | 8 - ...ernal.internal.ShippingOptionPriceType.mdx | 4 - .../enums/internal.internal.UserRoles.mdx | 6 - .../interfaces/internal.ArrayBufferView.mdx | 2 +- .../interfaces/internal.ArrayLike.mdx | 4 - .../interfaces/internal.ArrayOptions.mdx | 2 +- .../interfaces/internal.AsyncGenerator.mdx | 10 +- .../internal.AsyncGeneratorFunction.mdx | 36 +- .../interfaces/internal.AsyncIterable.mdx | 2 +- .../internal.AsyncIterableIterator.mdx | 8 +- .../interfaces/internal.AsyncIterator.mdx | 8 +- .../interfaces/internal.AxiosAdapter.mdx | 32 - .../interfaces/internal.AxiosDefaults.mdx | 24 +- .../interfaces/internal.AxiosError.mdx | 4 +- .../interfaces/internal.AxiosInstance.mdx | 115 +- .../internal.AxiosInterceptorManager.mdx | 2 +- .../interfaces/internal.AxiosPromise.mdx | 12 +- .../internal.AxiosRequestTransformer.mdx | 41 - .../interfaces/internal.AxiosResponse.mdx | 4 +- .../internal.AxiosResponseTransformer.mdx | 41 - .../internal.BaseRepositoryService.mdx | 6 +- .../interfaces/internal.BlobOptions.mdx | 2 +- .../interfaces/internal.BlobPropertyBag.mdx | 2 +- .../internal/interfaces/internal.Buffer.mdx | 142 +- .../interfaces/internal.BufferConstructor.mdx | 88 +- .../internal/interfaces/internal.CallSite.mdx | 10 +- .../interfaces/internal.CancelToken.mdx | 4 +- .../internal/interfaces/internal.Config.mdx | 2 +- .../interfaces/internal.ConnectOpts.mdx | 2 +- .../interfaces/internal.CreateNoteInput.mdx | 4 +- .../interfaces/internal.CreateUserInput.mdx | 4 +- .../internal/interfaces/internal.Dict.mdx | 4 - .../interfaces/internal.DuplexOptions.mdx | 34 +- .../interfaces/internal.EventEmitter-2.mdx | 28 +- .../internal/interfaces/internal.File.mdx | 8 +- .../interfaces/internal.FilePropertyBag.mdx | 2 +- .../interfaces/internal.HTTPResponse.mdx | 2 +- .../interfaces/internal.HeadersDefaults.mdx | 22 +- .../interfaces/internal.ICacheService.mdx | 6 +- .../internal.IEventBusModuleService.mdx | 28 +- .../interfaces/internal.IEventBusService.mdx | 22 +- .../interfaces/internal.IInventoryService.mdx | 148 +- .../internal.IPricingModuleService.mdx | 294 +- .../internal.IStockLocationService.mdx | 40 +- .../internal.ITransactionBaseService.mdx | 4 +- .../internal.IpcSocketConnectOpts.mdx | 2 +- .../internal/interfaces/internal.Iterable.mdx | 2 +- .../interfaces/internal.IterableIterator.mdx | 8 +- .../internal/interfaces/internal.Iterator.mdx | 6 +- .../interfaces/internal.OnReadOpts.mdx | 4 +- .../interfaces/internal.PromiseLike.mdx | 6 +- .../interfaces/internal.QueuingStrategy-1.mdx | 2 +- .../interfaces/internal.QueuingStrategy.mdx | 2 +- .../internal.QueuingStrategySize-1.mdx | 32 - .../internal.QueuingStrategySize.mdx | 32 - .../interfaces/internal.ReadWriteStream.mdx | 80 +- ...nternal.ReadableByteStreamController-1.mdx | 2 +- .../internal.ReadableByteStreamController.mdx | 4 +- ...l.ReadableByteStreamControllerCallback.mdx | 32 - .../interfaces/internal.ReadableOptions.mdx | 16 +- .../interfaces/internal.ReadableStream-1.mdx | 56 +- .../interfaces/internal.ReadableStream-2.mdx | 28 +- .../interfaces/internal.ReadableStream.mdx | 32 +- .../internal.ReadableStreamBYOBReader-1.mdx | 6 +- .../internal.ReadableStreamBYOBReader.mdx | 6 +- .../internal.ReadableStreamBYOBRequest.mdx | 4 +- ...internal.ReadableStreamDefaultReader-1.mdx | 6 +- .../internal.ReadableStreamDefaultReader.mdx | 6 +- .../internal.ReadableStreamErrorCallback.mdx | 32 - ...internal.ReadableStreamGenericReader-1.mdx | 4 +- .../internal.ReadableStreamGenericReader.mdx | 4 +- .../internal.ReadableWritablePair-1.mdx | 6 +- .../internal.ReadableWritablePair.mdx | 6 +- .../interfaces/internal.RetryConfig.mdx | 6 +- .../interfaces/internal.SharedArrayBuffer.mdx | 4 +- .../internal.SharedArrayBufferConstructor.mdx | 2 +- .../internal.SocketConstructorOpts.mdx | 2 +- .../internal.StaticEventEmitterOptions.mdx | 2 +- .../internal.StreamPipeOptions-1.mdx | 2 +- .../interfaces/internal.StreamPipeOptions.mdx | 2 +- .../internal.TcpSocketConnectOpts.mdx | 4 +- .../interfaces/internal.TransformOptions.mdx | 44 +- .../internal.UnderlyingByteSource-1.mdx | 6 +- .../internal.UnderlyingByteSource.mdx | 6 +- .../internal.UnderlyingDefaultSource.mdx | 6 +- .../interfaces/internal.UnderlyingSink-1.mdx | 8 +- .../interfaces/internal.UnderlyingSink.mdx | 8 +- ...internal.UnderlyingSinkAbortCallback-1.mdx | 32 - .../internal.UnderlyingSinkAbortCallback.mdx | 32 - ...internal.UnderlyingSinkCloseCallback-1.mdx | 18 - .../internal.UnderlyingSinkCloseCallback.mdx | 18 - ...internal.UnderlyingSinkStartCallback-1.mdx | 32 - .../internal.UnderlyingSinkStartCallback.mdx | 32 - ...internal.UnderlyingSinkWriteCallback-1.mdx | 41 - .../internal.UnderlyingSinkWriteCallback.mdx | 41 - .../internal.UnderlyingSource-1.mdx | 6 +- .../interfaces/internal.UnderlyingSource.mdx | 6 +- ...ernal.UnderlyingSourceCancelCallback-1.mdx | 32 - ...nternal.UnderlyingSourceCancelCallback.mdx | 32 - ...nternal.UnderlyingSourcePullCallback-1.mdx | 32 - .../internal.UnderlyingSourcePullCallback.mdx | 32 - ...ternal.UnderlyingSourceStartCallback-1.mdx | 32 - ...internal.UnderlyingSourceStartCallback.mdx | 32 - .../interfaces/internal.UpdateUserInput.mdx | 4 +- .../interfaces/internal.WritableStream-1.mdx | 6 +- .../interfaces/internal.WritableStream-2.mdx | 6 +- .../interfaces/internal.WritableStream.mdx | 60 +- ...ternal.WritableStreamDefaultController.mdx | 2 +- ...internal.WritableStreamDefaultWriter-1.mdx | 12 +- .../internal.WritableStreamDefaultWriter.mdx | 12 +- .../interfaces/internal._NodeEventTarget.mdx | 2 +- .../internal.internal.CustomFindOptions.mdx | 4 +- .../internal.internal.FulfillmentService.mdx | 64 +- .../internal.internal.IBatchJobStrategy.mdx | 38 +- ...ernal.internal.ICartCompletionStrategy.mdx | 10 +- .../internal.internal.IFileService.mdx | 48 +- ...internal.internal.INotificationService.mdx | 32 +- ...ernal.internal.IPriceSelectionStrategy.mdx | 16 +- ...ernal.internal.ITaxCalculationStrategy.mdx | 8 +- .../internal.internal.ITaxService.mdx | 12 +- .../internal.internal.MedusaRequest.mdx | 390 +- .../internal.internal.PaymentProcessor.mdx | 46 +- .../internal.internal.PaymentService.mdx | 100 +- .../internal/modules/internal.internal-3.mdx | 4 - .../internal/modules/internal.internal.mdx | 222 +- .../internal.AddOrderEditLineItemInput.mdx | 6 +- .../types/internal.AdjustmentContext.mdx | 4 +- .../internal/types/internal.AdminAuthRes.mdx | 6 +- .../types/internal.AdminBatchJobListRes.mdx | 2 - .../types/internal.AdminBatchJobRes.mdx | 6 +- .../types/internal.AdminBearerAuthRes.mdx | 4 +- .../internal.AdminCollectionsListRes.mdx | 2 - .../types/internal.AdminCollectionsRes.mdx | 6 +- .../internal.AdminCreateUploadPayload.mdx | 2 - .../types/internal.AdminCreateUserPayload.mdx | 2 - .../types/internal.AdminCurrenciesListRes.mdx | 2 - .../types/internal.AdminCurrenciesRes.mdx | 6 +- .../internal.AdminCustomerGroupsListRes.mdx | 2 - .../types/internal.AdminCustomerGroupsRes.mdx | 6 +- .../types/internal.AdminCustomersListRes.mdx | 2 - .../types/internal.AdminCustomersRes.mdx | 6 +- ...l.AdminDeleteProductsFromCollectionRes.mdx | 4 +- .../internal.AdminDiscountConditionsRes.mdx | 6 +- .../types/internal.AdminDiscountsListRes.mdx | 2 - .../types/internal.AdminDiscountsRes.mdx | 6 +- .../internal.AdminDraftOrdersListRes.mdx | 2 - .../types/internal.AdminDraftOrdersRes.mdx | 6 +- .../types/internal.AdminExtendedStoresRes.mdx | 6 +- ...al.AdminGetVariantsVariantInventoryRes.mdx | 6 +- .../types/internal.AdminGiftCardsListRes.mdx | 2 - .../types/internal.AdminGiftCardsRes.mdx | 6 +- ...msListWithVariantsAndLocationLevelsRes.mdx | 2 - ...l.AdminInventoryItemsLocationLevelsRes.mdx | 6 +- .../types/internal.AdminInventoryItemsRes.mdx | 6 +- .../types/internal.AdminListInvitesRes.mdx | 6 +- .../types/internal.AdminNotesListRes.mdx | 2 - .../internal/types/internal.AdminNotesRes.mdx | 6 +- .../internal.AdminNotificationsListRes.mdx | 2 - .../types/internal.AdminNotificationsRes.mdx | 6 +- ...rnal.AdminOrderEditItemChangeDeleteRes.mdx | 4 +- .../types/internal.AdminOrderEditsListRes.mdx | 2 - .../types/internal.AdminOrderEditsRes.mdx | 6 +- .../types/internal.AdminOrdersListRes.mdx | 2 - .../types/internal.AdminOrdersRes.mdx | 6 +- ...ternal.AdminPaymentCollectionDeleteRes.mdx | 4 +- .../internal.AdminPaymentCollectionsRes.mdx | 6 +- .../internal.AdminPaymentProvidersList.mdx | 6 +- .../types/internal.AdminPaymentRes.mdx | 6 +- ...raftOrdersDraftOrderRegisterPaymentRes.mdx | 6 +- .../internal.AdminPostInvitesPayload.mdx | 2 - .../internal.AdminPriceListDeleteBatchRes.mdx | 4 +- .../types/internal.AdminPriceListRes.mdx | 6 +- .../types/internal.AdminPriceListsListRes.mdx | 2 - ...nternal.AdminPriceListsProductsListRes.mdx | 2 - ...rnal.AdminProductCategoriesCategoryRes.mdx | 6 +- ...internal.AdminProductCategoriesListRes.mdx | 2 - .../internal.AdminProductTagsListRes.mdx | 2 - .../internal.AdminProductTypesListRes.mdx | 2 - .../internal.AdminProductsDeleteOptionRes.mdx | 6 +- .../types/internal.AdminProductsDeleteRes.mdx | 4 +- ...internal.AdminProductsDeleteVariantRes.mdx | 6 +- .../types/internal.AdminProductsListRes.mdx | 2 - .../internal.AdminProductsListTagsRes.mdx | 6 +- .../internal.AdminProductsListTypesRes.mdx | 6 +- .../types/internal.AdminProductsRes.mdx | 6 +- ...nternal.AdminPublishableApiKeysListRes.mdx | 2 - ...PublishableApiKeysListSalesChannelsRes.mdx | 6 +- .../internal.AdminPublishableApiKeysRes.mdx | 6 +- .../types/internal.AdminRefundRes.mdx | 6 +- .../types/internal.AdminRegionsListRes.mdx | 2 - .../types/internal.AdminRegionsRes.mdx | 6 +- .../internal.AdminReservationsListRes.mdx | 2 - .../types/internal.AdminReservationsRes.mdx | 6 +- .../internal.AdminReturnReasonsListRes.mdx | 6 +- .../types/internal.AdminReturnReasonsRes.mdx | 6 +- .../types/internal.AdminReturnsCancelRes.mdx | 6 +- .../types/internal.AdminReturnsListRes.mdx | 2 - .../types/internal.AdminReturnsRes.mdx | 6 +- .../internal.AdminSalesChannelsListRes.mdx | 2 - .../types/internal.AdminSalesChannelsRes.mdx | 6 +- .../internal.AdminShippingOptionsListRes.mdx | 2 - .../internal.AdminShippingOptionsRes.mdx | 6 +- .../internal.AdminShippingProfilesListRes.mdx | 6 +- .../internal.AdminShippingProfilesRes.mdx | 6 +- .../internal.AdminStockLocationsListRes.mdx | 2 - .../types/internal.AdminStockLocationsRes.mdx | 6 +- .../types/internal.AdminStoresRes.mdx | 6 +- .../types/internal.AdminSwapsListRes.mdx | 2 - .../internal/types/internal.AdminSwapsRes.mdx | 6 +- .../types/internal.AdminTaxProvidersList.mdx | 6 +- .../types/internal.AdminTaxRatesListRes.mdx | 2 - .../types/internal.AdminTaxRatesRes.mdx | 6 +- .../types/internal.AdminUpdateUserPayload.mdx | 2 - .../internal.AdminUploadsDownloadUrlRes.mdx | 4 +- .../types/internal.AdminUploadsRes.mdx | 6 +- .../internal/types/internal.AdminUserRes.mdx | 6 +- .../types/internal.AdminUsersListRes.mdx | 6 +- .../types/internal.AdminVariantsListRes.mdx | 2 - .../types/internal.AdminVariantsRes.mdx | 6 +- .../types/internal.AllocationMapOptions.mdx | 4 +- .../types/internal.ArrayBufferLike.mdx | 2 - .../types/internal.ArrayBufferView-1.mdx | 2 - .../types/internal.AuthenticateResult.mdx | 8 +- .../types/internal.AvailabilityContext.mdx | 8 +- .../types/internal.AxiosRequestHeaders.mdx | 2 - .../types/internal.AxiosResponseHeaders.mdx | 2 - .../internal/types/internal.BinaryLike.mdx | 2 - .../internal/types/internal.BlobPart.mdx | 2 - .../types/internal.BufferEncoding.mdx | 2 - .../internal/types/internal.BufferSource.mdx | 2 - .../internal.CalculateOptionPriceInput.mdx | 6 +- .../types/internal.CalculationContextData.mdx | 20 +- .../internal.CalculationContextOptions.mdx | 4 +- .../types/internal.CartCreateProps.mdx | 18 +- .../types/internal.CartUpdateProps.mdx | 14 +- .../types/internal.CategoryQueryParams.mdx | 4 +- .../types/internal.ClaimTypeValue.mdx | 2 - .../types/internal.ComposeFnParam.mdx | 4 +- .../internal/types/internal.ConfigModule.mdx | 12 +- .../internal/types/internal.Constructor.mdx | 6 +- .../types/internal.CreateAnalyticsConfig.mdx | 4 +- .../types/internal.CreateClaimInput.mdx | 20 +- ...nal.CreateClaimItemAdditionalItemInput.mdx | 4 +- .../types/internal.CreateClaimItemInput.mdx | 6 +- ...nternal.CreateClaimReturnShippingInput.mdx | 4 +- ...nternal.CreateClaimShippingMethodInput.mdx | 6 +- ...ternal.CreateCustomShippingOptionInput.mdx | 6 +- .../types/internal.CreateCustomerInput.mdx | 6 +- .../types/internal.CreateDiscountInput.mdx | 10 +- .../internal.CreateDiscountRuleInput.mdx | 10 +- .../internal.CreateDynamicDiscountInput.mdx | 6 +- .../types/internal.CreateFulfillmentOrder.mdx | 2 - .../types/internal.CreateGiftCardInput.mdx | 6 +- ...nternal.CreateGiftCardTransactionInput.mdx | 4 +- .../internal.CreateIdempotencyKeyInput.mdx | 6 +- .../types/internal.CreateOauthInput.mdx | 4 +- .../types/internal.CreateOrderEditInput.mdx | 4 +- ...nternal.CreateOrderEditItemChangeInput.mdx | 6 +- .../internal.CreatePaymentCollectionInput.mdx | 6 +- .../types/internal.CreatePaymentInput.mdx | 6 +- .../internal.CreateProductCategoryInput.mdx | 2 - .../internal.CreateProductCollection.mdx | 6 +- .../types/internal.CreateProductInput.mdx | 20 +- ...rnal.CreateProductProductCategoryInput.mdx | 4 +- .../internal.CreateProductProductOption.mdx | 4 +- ....CreateProductProductSalesChannelInput.mdx | 4 +- .../internal.CreateProductProductTagInput.mdx | 4 +- ...internal.CreateProductProductTypeInput.mdx | 4 +- ...ernal.CreateProductProductVariantInput.mdx | 10 +- ....CreateProductProductVariantPriceInput.mdx | 4 +- .../internal.CreateProductVariantInput.mdx | 10 +- .../types/internal.CreateRegionInput.mdx | 6 +- .../types/internal.CreateReturnInput.mdx | 8 +- .../types/internal.CreateReturnReason.mdx | 6 +- .../types/internal.CreateReturnType.mdx | 2 - .../internal.CreateSalesChannelInput.mdx | 4 +- .../types/internal.CreateShipmentConfig.mdx | 6 +- .../types/internal.CreateShippingMethod.mdx | 4 +- .../internal.CreateShippingMethodDto.mdx | 2 - .../internal.CreateShippingOptionInput.mdx | 12 +- .../types/internal.CreateShippingProfile.mdx | 8 +- .../types/internal.CreateTaxRateInput.mdx | 4 +- .../types/internal.CreateUserRoles.mdx | 2 - .../types/internal.CreateUserRolesEnum.mdx | 2 - ...internal.CustomerGroupConstructorProps.mdx | 8 +- .../internal.DecoratedInventoryItemDTO.mdx | 2 - .../internal.DefaultWithoutRelations-1.mdx | 2 - .../internal.DefaultWithoutRelations.mdx | 2 - .../types/internal.DeleteFileType.mdx | 6 +- .../types/internal.DeleteResponse-1.mdx | 4 +- .../internal/types/internal.Dictionary.mdx | 6 +- .../internal/types/internal.Discount-5.mdx | 4 +- .../types/internal.DiscountAllocation.mdx | 4 +- .../types/internal.DiscountConditionInput.mdx | 16 +- ...internal.DiscountConditionResourceType.mdx | 2 - .../types/internal.DraftOrderCreateProps.mdx | 16 +- .../internal/types/internal.EmitData.mdx | 8 +- .../internal/types/internal.EndingType.mdx | 2 - .../internal/types/internal.Exclude.mdx | 4 +- .../internal/types/internal.ExpandScalar.mdx | 4 +- .../types/internal.ExtendedStoreDTO.mdx | 2 - .../types/internal.FeatureFlagsResponse.mdx | 2 - ...ernal.FileServiceGetUploadStreamResult.mdx | 10 +- .../internal.FileServiceUploadResult.mdx | 4 +- .../internal/types/internal.FilterValue.mdx | 4 +- .../internal/types/internal.FilterValue2.mdx | 4 +- .../types/internal.FilterableTaxRateProps.mdx | 14 +- .../types/internal.FilterableUserProps.mdx | 2 - .../types/internal.FindProductConfig.mdx | 2 - .../internal.FindWithRelationsOptions.mdx | 2 - ...internal.FindWithoutRelationsOptions-1.mdx | 2 - .../internal.FindWithoutRelationsOptions.mdx | 2 - .../types/internal.FulFillmentItemType.mdx | 4 +- .../internal.FulfillmentItemPartition.mdx | 8 +- .../types/internal.FulfillmentOptions.mdx | 6 +- .../internal.FulfillmentProviderContainer.mdx | 2 - .../internal.FulfillmentProviderData.mdx | 2 - .../types/internal.FulfillmentProviderKey.mdx | 2 - .../types/internal.GenerateInputData.mdx | 6 +- .../internal.GenerateLineItemContext.mdx | 8 +- .../types/internal.GeneratedAdjustment.mdx | 4 +- .../internal.GetLineItemTotalOptions.mdx | 4 +- .../types/internal.GetRegionPriceContext.mdx | 4 +- ...nternal.GetShippingMethodTotalsOptions.mdx | 6 +- .../types/internal.GetTotalsOptions.mdx | 4 +- .../types/internal.GetUploadedFileType.mdx | 6 +- .../types/internal.GiftCardAllocation.mdx | 4 +- .../types/internal.GiftCardTransaction-1.mdx | 6 +- .../internal.IdempotencyCallbackResult.mdx | 6 +- .../types/internal.InjectedDependencies-1.mdx | 8 +- .../internal.InjectedDependencies-10.mdx | 10 +- .../internal.InjectedDependencies-11.mdx | 12 +- .../internal.InjectedDependencies-12.mdx | 6 +- .../internal.InjectedDependencies-13.mdx | 24 +- .../internal.InjectedDependencies-14.mdx | 10 +- .../internal.InjectedDependencies-15.mdx | 8 +- .../internal.InjectedDependencies-16.mdx | 10 +- .../internal.InjectedDependencies-17.mdx | 2 - .../internal.InjectedDependencies-18.mdx | 46 +- .../internal.InjectedDependencies-19.mdx | 24 +- .../types/internal.InjectedDependencies-2.mdx | 10 +- .../internal.InjectedDependencies-20.mdx | 12 +- .../internal.InjectedDependencies-21.mdx | 12 +- .../internal.InjectedDependencies-22.mdx | 2 - .../internal.InjectedDependencies-23.mdx | 18 +- .../internal.InjectedDependencies-24.mdx | 26 +- .../internal.InjectedDependencies-25.mdx | 8 +- .../internal.InjectedDependencies-26.mdx | 10 +- .../internal.InjectedDependencies-27.mdx | 16 +- .../internal.InjectedDependencies-28.mdx | 26 +- .../internal.InjectedDependencies-29.mdx | 26 +- .../types/internal.InjectedDependencies-3.mdx | 58 +- .../internal.InjectedDependencies-30.mdx | 6 +- .../internal.InjectedDependencies-31.mdx | 10 +- .../internal.InjectedDependencies-32.mdx | 10 +- .../internal.InjectedDependencies-33.mdx | 10 +- .../internal.InjectedDependencies-34.mdx | 6 +- .../internal.InjectedDependencies-35.mdx | 16 +- .../internal.InjectedDependencies-36.mdx | 16 +- .../internal.InjectedDependencies-37.mdx | 10 +- .../internal.InjectedDependencies-38.mdx | 6 +- .../internal.InjectedDependencies-39.mdx | 6 +- .../types/internal.InjectedDependencies-4.mdx | 36 +- .../internal.InjectedDependencies-40.mdx | 20 +- .../internal.InjectedDependencies-41.mdx | 10 +- .../types/internal.InjectedDependencies-5.mdx | 10 +- .../types/internal.InjectedDependencies-6.mdx | 6 +- .../types/internal.InjectedDependencies-7.mdx | 10 +- .../types/internal.InjectedDependencies-8.mdx | 8 +- .../types/internal.InjectedDependencies-9.mdx | 22 +- .../types/internal.InjectedDependencies.mdx | 6 +- .../internal/types/internal.InjectedProps.mdx | 30 +- .../types/internal.InventoryItemDTO.mdx | 6 +- .../types/internal.InventoryLevelDTO.mdx | 6 +- .../types/internal.InviteUserRolesEnum.mdx | 2 - .../internal/types/internal.Item-8.mdx | 6 +- .../types/internal.IteratorResult.mdx | 4 +- .../types/internal.LineAllocationsMap.mdx | 6 +- .../internal/types/internal.LineDiscount.mdx | 6 +- .../types/internal.LineDiscountAmount.mdx | 6 +- ...nternal.LineItemAdjustmentServiceProps.mdx | 8 +- .../types/internal.LineItemTotals-1.mdx | 6 +- .../types/internal.LineItemTotals.mdx | 6 +- .../types/internal.LineItemTotalsOptions.mdx | 6 +- .../types/internal.LineItemUpdate.mdx | 6 +- .../types/internal.LineItemValidateData.mdx | 4 +- .../types/internal.ListAndCountSelector.mdx | 2 - .../types/internal.LookupFunction.mdx | 8 +- .../types/internal.MedusaContainer-1.mdx | 2 - .../types/internal.MedusaContainer.mdx | 2 - .../internal.MedusaErrorHandlerFunction.mdx | 14 +- .../internal/types/internal.Method.mdx | 2 - .../types/internal.MiddlewareVerb.mdx | 2 - .../types/internal.ModuleDeclaration.mdx | 2 - .../types/internal.ModulesResponse.mdx | 2 - .../internal/types/internal.NoUndefined.mdx | 4 +- .../internal/types/internal.Omit.mdx | 4 +- .../internal/types/internal.OperatorMap.mdx | 28 +- .../internal/types/internal.Order-1.mdx | 4 +- .../types/internal.OrdersReturnItem-1.mdx | 4 +- .../types/internal.PaginatedResponse-1.mdx | 4 +- .../internal/types/internal.ParserConfig.mdx | 2 - .../internal/types/internal.Partial.mdx | 4 +- ...l.PaymentCollectionsSessionsBatchInput.mdx | 4 +- ...ternal.PaymentCollectionsSessionsInput.mdx | 4 +- .../types/internal.PaymentDataInput.mdx | 6 +- .../types/internal.PaymentProviderKey.mdx | 2 - .../types/internal.PaymentSessionInput.mdx | 10 +- .../internal/types/internal.Pick.mdx | 4 +- .../internal/types/internal.PrevLimit.mdx | 2 - .../internal/types/internal.Price.mdx | 2 - .../internal.PriceListConstructorProps.mdx | 20 +- .../internal/types/internal.PricedProduct.mdx | 2 - .../types/internal.PricedShippingOption.mdx | 2 - .../internal/types/internal.PricedVariant.mdx | 2 - .../types/internal.PricingContext.mdx | 6 +- .../internal/types/internal.Primary.mdx | 4 +- .../types/internal.ProductCategoryInput.mdx | 6 +- .../types/internal.ProductOptionInput.mdx | 6 +- .../types/internal.ProductSelector.mdx | 2 - .../types/internal.ProductVariantOption.mdx | 4 +- .../types/internal.ProductVariantPrice.mdx | 4 +- .../types/internal.ProductVariantPricing.mdx | 2 - .../types/internal.PropertyDecorator.mdx | 4 +- .../internal.ProviderLineItemTaxLine.mdx | 6 +- ...internal.ProviderShippingMethodTaxLine.mdx | 6 +- .../types/internal.ProviderTaxLine.mdx | 2 - .../internal/types/internal.Query.mdx | 4 +- .../internal.ReadableStreamController-1.mdx | 4 +- .../internal.ReadableStreamController.mdx | 4 +- ...ternal.ReadableStreamDefaultReadResult.mdx | 4 +- .../internal.ReadableStreamReadResult-1.mdx | 4 +- .../internal.ReadableStreamReadResult.mdx | 4 +- .../types/internal.ReadableStreamReader.mdx | 4 +- .../internal/types/internal.Readonly.mdx | 4 +- .../types/internal.ReadonlyPrimary.mdx | 4 +- .../internal/types/internal.Record.mdx | 4 +- .../internal/types/internal.RegionDetails.mdx | 4 +- .../types/internal.RemoteQueryFunction.mdx | 12 +- .../types/internal.ReorderConditions.mdx | 4 +- .../types/internal.RequestContext.mdx | 4 +- .../internal/types/internal.RequestMethod.mdx | 2 - .../types/internal.ReservationItemDTO.mdx | 6 +- .../types/internal.ReserveQuantityContext.mdx | 4 +- .../internal/types/internal.Response.mdx | 4 +- .../types/internal.ResponsePromise.mdx | 4 +- .../internal/types/internal.ResponseType.mdx | 2 - .../internal/types/internal.ReturnedData.mdx | 6 +- .../internal/types/internal.RouteVerb.mdx | 2 - .../internal/types/internal.Scalar.mdx | 2 - .../types/internal.SessionOptions.mdx | 4 +- .../types/internal.ShippingMethod-5.mdx | 6 +- .../types/internal.ShippingMethodData.mdx | 2 - .../types/internal.ShippingMethodTotals-1.mdx | 6 +- .../types/internal.ShippingMethodTotals.mdx | 6 +- .../types/internal.ShippingMethodUpdate.mdx | 4 +- .../types/internal.ShippingOptionData.mdx | 2 - .../types/internal.ShippingOptionPricing.mdx | 6 +- .../types/internal.SocketConnectOpts.mdx | 2 - .../types/internal.SocketReadyState.mdx | 2 - .../types/internal.StagedJobServiceProps.mdx | 6 +- .../types/internal.StockLocationDTO.mdx | 8 +- .../internal.StockLocationExpandedDTO.mdx | 2 - .../internal/types/internal.StoreAuthRes.mdx | 6 +- .../types/internal.StoreBearerAuthRes.mdx | 4 +- .../internal/types/internal.StoreCartsRes.mdx | 6 +- .../internal.StoreCollectionsListRes.mdx | 2 - .../types/internal.StoreCollectionsRes.mdx | 6 +- .../types/internal.StoreCompleteCartRes.mdx | 2 - .../internal.StoreCustomersListOrdersRes.mdx | 2 - ...al.StoreCustomersListPaymentMethodsRes.mdx | 6 +- .../types/internal.StoreCustomersRes.mdx | 6 +- .../types/internal.StoreGetAuthEmailRes.mdx | 4 +- ...l.StoreGetProductCategoriesCategoryRes.mdx | 6 +- .../internal.StoreGetProductCategoriesRes.mdx | 2 - .../types/internal.StoreGiftCardsRes.mdx | 6 +- .../types/internal.StoreOrderEditsRes.mdx | 6 +- .../types/internal.StoreOrdersRes.mdx | 6 +- .../internal.StorePaymentCollectionsRes.mdx | 6 +- ...rnal.StorePaymentCollectionsSessionRes.mdx | 6 +- .../types/internal.StorePostSearchRes.mdx | 2 - .../internal.StoreProductTagsListRes.mdx | 2 - .../internal.StoreProductTypesListRes.mdx | 2 - .../types/internal.StoreProductsListRes.mdx | 2 - .../types/internal.StoreProductsRes.mdx | 6 +- .../types/internal.StoreRegionsListRes.mdx | 2 - .../types/internal.StoreRegionsRes.mdx | 6 +- .../internal.StoreReturnReasonsListRes.mdx | 6 +- .../types/internal.StoreReturnReasonsRes.mdx | 6 +- .../types/internal.StoreReturnsRes.mdx | 6 +- .../internal.StoreShippingOptionsListRes.mdx | 6 +- .../internal/types/internal.StoreSwapsRes.mdx | 6 +- .../types/internal.StoreVariantsListRes.mdx | 6 +- .../types/internal.StoreVariantsRes.mdx | 6 +- .../internal/types/internal.Subscriber.mdx | 8 +- .../types/internal.SubscriberContext.mdx | 4 +- .../types/internal.SubtotalOptions.mdx | 4 +- .../internal/types/internal.TaxLinesMaps.mdx | 4 +- .../types/internal.TaxRateListByConfig.mdx | 4 +- .../types/internal.TaxServiceRate.mdx | 4 +- .../internal/types/internal.TaxedPricing.mdx | 6 +- .../internal/types/internal.TotalsConfig.mdx | 4 +- .../internal/types/internal.TotalsContext.mdx | 4 +- .../types/internal.TotalsServiceProps.mdx | 12 +- .../types/internal.TransformCallback.mdx | 6 +- .../internal/types/internal.Transformer.mdx | 12 +- .../internal/types/internal.TypedArray.mdx | 2 - .../types/internal.UpdateAnalyticsConfig.mdx | 4 +- .../types/internal.UpdateClaimInput.mdx | 10 +- .../internal.UpdateClaimItemImageInput.mdx | 4 +- .../types/internal.UpdateClaimItemInput.mdx | 10 +- .../internal.UpdateClaimItemTagInput.mdx | 4 +- ...nternal.UpdateClaimShippingMethodInput.mdx | 6 +- .../types/internal.UpdateCurrencyInput.mdx | 4 +- .../types/internal.UpdateCustomerInput.mdx | 10 +- .../types/internal.UpdateDiscountInput.mdx | 8 +- .../internal.UpdateDiscountRuleInput.mdx | 8 +- .../types/internal.UpdateGiftCardInput.mdx | 6 +- .../types/internal.UpdateOauthInput.mdx | 6 +- .../types/internal.UpdateOrderInput.mdx | 22 +- .../internal.UpdateProductCategoryInput.mdx | 2 - .../internal.UpdateProductCollection.mdx | 6 +- .../types/internal.UpdateProductInput.mdx | 2 - ...nternal.UpdateProductProductVariantDTO.mdx | 10 +- .../internal.UpdateProductVariantData.mdx | 8 +- .../internal.UpdateProductVariantInput.mdx | 10 +- .../types/internal.UpdateRegionInput.mdx | 6 +- .../types/internal.UpdateReturnInput.mdx | 8 +- .../types/internal.UpdateReturnReason.mdx | 6 +- .../internal.UpdateShippingOptionInput.mdx | 10 +- .../types/internal.UpdateShippingProfile.mdx | 8 +- .../types/internal.UpdateStoreInput.mdx | 6 +- .../types/internal.UpdateTaxRateInput.mdx | 4 +- .../types/internal.UpdateUserRoles.mdx | 2 - .../types/internal.UpdateUserRolesEnum.mdx | 2 - .../internal.UpdateVariantPricesData.mdx | 6 +- .../internal.UpdateVariantRegionPriceData.mdx | 4 +- .../internal.UploadStreamDescriptorType.mdx | 6 +- .../types/internal.UpsertTagsInput.mdx | 2 - .../types/internal.UpsertTypeInput.mdx | 2 - .../types/internal.UserServiceProps.mdx | 12 +- .../types/internal.VariantInventory.mdx | 8 +- .../types/internal.WithImplicitCoercion.mdx | 4 +- .../internal/types/internal.handler.mdx | 6 +- ...internal.AdminAnalyticsConfigDeleteRes.mdx | 2 - ...ernal.internal.AdminAnalyticsConfigRes.mdx | 6 +- ...nal.internal.AdminCollectionsDeleteRes.mdx | 2 - ....internal.AdminCustomerGroupsDeleteRes.mdx | 2 - ...internal.AdminDeleteShippingProfileRes.mdx | 2 - ...nternal.internal.AdminDeleteUploadsRes.mdx | 2 - .../internal.internal.AdminDeleteUserRes.mdx | 2 - ...ernal.AdminDiscountConditionsDeleteRes.mdx | 2 - ...ernal.internal.AdminDiscountsDeleteRes.mdx | 2 - ...nal.internal.AdminDraftOrdersDeleteRes.mdx | 2 - ...ernal.internal.AdminGiftCardsDeleteRes.mdx | 2 - ....internal.AdminInventoryItemsDeleteRes.mdx | 2 - ...al.internal.AdminInventoryItemsListRes.mdx | 2 - ...internal.internal.AdminInviteDeleteRes.mdx | 2 - .../internal.internal.AdminNotesDeleteRes.mdx | 2 - ...ernal.internal.AdminOrderEditDeleteRes.mdx | 2 - ...l.AdminPriceListDeleteProductPricesRes.mdx | 2 - ...ernal.internal.AdminPriceListDeleteRes.mdx | 2 - ...l.AdminPriceListDeleteVariantPricesRes.mdx | 2 - ...dminProductCategoriesCategoryDeleteRes.mdx | 2 - ....internal.AdminProductsListVariantsRes.mdx | 2 - ...ternal.AdminPublishableApiKeyDeleteRes.mdx | 2 - ...nternal.internal.AdminRegionsDeleteRes.mdx | 2 - ...al.internal.AdminReservationsDeleteRes.mdx | 2 - ...l.internal.AdminReturnReasonsDeleteRes.mdx | 2 - ...al.AdminSalesChannelsDeleteLocationRes.mdx | 2 - ...l.internal.AdminSalesChannelsDeleteRes.mdx | 2 - ...internal.AdminShippingOptionsDeleteRes.mdx | 2 - ....internal.AdminStockLocationsDeleteRes.mdx | 2 - ...ternal.internal.AdminTaxRatesDeleteRes.mdx | 2 - .../internal.internal.BatchJobCreateProps.mdx | 2 - .../internal.internal.BatchJobResultError.mdx | 6 +- ....internal.BatchJobResultStatDescriptor.mdx | 4 +- .../internal.internal.BatchJobUpdateProps.mdx | 2 - ...ternal.internal.CartCompletionResponse.mdx | 6 +- .../internal.internal.ClassConstructor.mdx | 6 +- .../types/internal.internal.ConfigModule.mdx | 2 - .../types/internal.internal.Constructor.mdx | 6 +- .../internal.internal.CreateBatchJobInput.mdx | 6 +- ...internal.internal.CreatePriceListInput.mdx | 12 +- .../internal/types/internal.internal.Data.mdx | 2 - .../internal.internal.ExtendedFindConfig.mdx | 4 +- .../internal.internal.ExtendedRequest.mdx | 4 +- ...ernal.internal.ExtendedReservationItem.mdx | 2 - ...ternal.internal.ItemTaxCalculationLine.mdx | 8 +- ...nternal.internal.LevelWithAvailability.mdx | 2 - .../types/internal.internal.Logger.mdx | 4 +- .../internal.internal.MedusaContainer.mdx | 2 - .../internal.internal.MedusaNextFunction.mdx | 2 - ...internal.internal.MedusaRequestHandler.mdx | 14 +- .../internal.internal.MedusaResponse.mdx | 2 - .../internal.internal.MiddlewareFunction.mdx | 2 - .../internal.internal.MiddlewareRoute.mdx | 10 +- .../internal.internal.MiddlewaresConfig.mdx | 8 +- .../types/internal.internal.PartialPick.mdx | 4 +- .../internal.internal.PaymentContext.mdx | 16 +- .../types/internal.internal.PaymentData.mdx | 2 - ...ernal.internal.PaymentProcessorContext.mdx | 12 +- ...ternal.PaymentProcessorSessionResponse.mdx | 8 +- .../internal.internal.PaymentSessionData.mdx | 2 - ...ternal.internal.PaymentSessionResponse.mdx | 8 +- .../internal.internal.PriceListLoadConfig.mdx | 4 +- ...nal.internal.PriceListPriceCreateInput.mdx | 4 +- ...nal.internal.PriceListPriceUpdateInput.mdx | 4 +- ...nternal.internal.PriceSelectionContext.mdx | 6 +- ...internal.internal.PriceSelectionResult.mdx | 8 +- .../types/internal.internal.PriceType.mdx | 2 - .../types/internal.internal.QueryConfig.mdx | 8 +- .../types/internal.internal.QuerySelector.mdx | 4 +- ...nternal.internal.ResponseInventoryItem.mdx | 2 - .../types/internal.internal.Selector.mdx | 4 +- ...al.internal.ShippingTaxCalculationLine.mdx | 8 +- ...ternal.StoreCartShippingOptionsListRes.mdx | 6 +- ...nternal.StoreCustomersResetPasswordRes.mdx | 6 +- ...nternal.internal.TaxCalculationContext.mdx | 14 +- .../types/internal.internal.TotalField.mdx | 2 - .../internal.internal.TreeQuerySelector.mdx | 4 +- ...internal.internal.UpdatePriceListInput.mdx | 2 - ...internal.internal.WithRequiredProperty.mdx | 4 +- .../types/internal.internal.Writable.mdx | 4 +- .../types/internal.internal.payload.mdx | 4 +- .../types/internal.middlewareHandlerType.mdx | 6 +- .../types/internal.middlewareType.mdx | 8 +- .../references/js-client/modules/internal.mdx | 376 +- .../IPricingModuleService.addPrices.mdx | 42 +- .../IPricingModuleService.addRules.mdx | 34 +- .../IPricingModuleService.calculatePrices.mdx | 10 +- .../methods/IPricingModuleService.create.mdx | 46 +- ...IPricingModuleService.createCurrencies.mdx | 8 +- ...ricingModuleService.createMoneyAmounts.mdx | 12 +- ...IPricingModuleService.createPriceRules.mdx | 12 +- ...Service.createPriceSetMoneyAmountRules.mdx | 12 +- .../IPricingModuleService.createRuleTypes.mdx | 12 +- .../methods/IPricingModuleService.delete.mdx | 4 +- ...IPricingModuleService.deleteCurrencies.mdx | 4 +- ...ricingModuleService.deleteMoneyAmounts.mdx | 4 +- ...IPricingModuleService.deletePriceRules.mdx | 4 +- ...Service.deletePriceSetMoneyAmountRules.mdx | 4 +- .../IPricingModuleService.deleteRuleTypes.mdx | 4 +- .../methods/IPricingModuleService.list.mdx | 24 +- .../IPricingModuleService.listAndCount.mdx | 20 +- ...ngModuleService.listAndCountCurrencies.mdx | 14 +- ...ModuleService.listAndCountMoneyAmounts.mdx | 14 +- ...ngModuleService.listAndCountPriceRules.mdx | 14 +- ...e.listAndCountPriceSetMoneyAmountRules.mdx | 14 +- ...rvice.listAndCountPriceSetMoneyAmounts.mdx | 14 +- ...ingModuleService.listAndCountRuleTypes.mdx | 14 +- .../IPricingModuleService.listCurrencies.mdx | 14 +- ...IPricingModuleService.listMoneyAmounts.mdx | 16 +- .../IPricingModuleService.listPriceRules.mdx | 18 +- ...leService.listPriceSetMoneyAmountRules.mdx | 18 +- ...ModuleService.listPriceSetMoneyAmounts.mdx | 20 +- .../IPricingModuleService.listRuleTypes.mdx | 16 +- .../IPricingModuleService.removeRules.mdx | 6 +- .../IPricingModuleService.retrieve.mdx | 14 +- ...IPricingModuleService.retrieveCurrency.mdx | 6 +- ...icingModuleService.retrieveMoneyAmount.mdx | 8 +- ...PricingModuleService.retrievePriceRule.mdx | 16 +- ...rvice.retrievePriceSetMoneyAmountRules.mdx | 18 +- ...IPricingModuleService.retrieveRuleType.mdx | 8 +- ...IPricingModuleService.updateCurrencies.mdx | 8 +- ...ricingModuleService.updateMoneyAmounts.mdx | 10 +- ...IPricingModuleService.updatePriceRules.mdx | 12 +- ...Service.updatePriceSetMoneyAmountRules.mdx | 12 +- .../IPricingModuleService.updateRuleTypes.mdx | 12 +- .../pricing/interfaces/AddPricesDTO.mdx | 6 +- .../pricing/interfaces/AddRulesDTO.mdx | 2 +- .../pricing/interfaces/BaseFilterable.mdx | 4 +- .../interfaces/CreateMoneyAmountDTO.mdx | 2 +- .../pricing/interfaces/CreatePriceSetDTO.mdx | 8 +- .../pricing/interfaces/CreatePricesDTO.mdx | 4 +- .../pricing/interfaces/CreateRuleTypeDTO.mdx | 2 +- .../interfaces/FilterableCurrencyProps.mdx | 4 +- .../interfaces/FilterableMoneyAmountProps.mdx | 4 +- .../interfaces/FilterablePriceRuleProps.mdx | 4 +- .../FilterablePriceSetMoneyAmountProps.mdx | 4 +- ...ilterablePriceSetMoneyAmountRulesProps.mdx | 4 +- .../interfaces/FilterablePriceSetProps.mdx | 10 +- .../interfaces/FilterableRuleTypeProps.mdx | 4 +- .../interfaces/JoinerServiceConfig.mdx | 18 +- .../interfaces/JoinerServiceConfigAlias.mdx | 2 +- .../pricing/interfaces/MoneyAmountDTO.mdx | 2 +- .../pricing/interfaces/PriceRuleDTO.mdx | 14 +- .../pricing/interfaces/PriceSetDTO.mdx | 8 +- .../interfaces/PriceSetMoneyAmountDTO.mdx | 26 +- .../PriceSetMoneyAmountRulesDTO.mdx | 22 +- .../pricing/interfaces/PricingContext.mdx | 2 +- .../pricing/interfaces/RuleTypeDTO.mdx | 2 +- .../pricing/interfaces/UpdateRuleTypeDTO.mdx | 2 +- .../references/pricing/types/Exclude.mdx | 4 +- .../pricing/types/JoinerRelationship.mdx | 4 +- .../pricing/types/ModuleJoinerConfig.mdx | 2 +- .../types/ModuleJoinerRelationship.mdx | 2 +- .../content/references/pricing/types/Omit.mdx | 4 +- .../content/references/pricing/types/Pick.mdx | 4 +- .../references/pricing/types/Record.mdx | 4 +- .../Buffer/methods/Buffer._iterator_.mdx | 6 +- .../product/Buffer/methods/Buffer.at.mdx | 2 +- .../product/Buffer/methods/Buffer.compare.mdx | 10 +- .../product/Buffer/methods/Buffer.copy.mdx | 6 +- .../Buffer/methods/Buffer.copyWithin.mdx | 6 +- .../product/Buffer/methods/Buffer.entries.mdx | 8 +- .../product/Buffer/methods/Buffer.equals.mdx | 4 +- .../product/Buffer/methods/Buffer.every.mdx | 6 +- .../product/Buffer/methods/Buffer.fill.mdx | 10 +- .../product/Buffer/methods/Buffer.filter.mdx | 10 +- .../product/Buffer/methods/Buffer.find.mdx | 6 +- .../Buffer/methods/Buffer.findIndex.mdx | 6 +- .../product/Buffer/methods/Buffer.forEach.mdx | 6 +- .../Buffer/methods/Buffer.includes.mdx | 6 +- .../product/Buffer/methods/Buffer.indexOf.mdx | 10 +- .../product/Buffer/methods/Buffer.join.mdx | 2 +- .../product/Buffer/methods/Buffer.keys.mdx | 8 +- .../Buffer/methods/Buffer.lastIndexOf.mdx | 8 +- .../product/Buffer/methods/Buffer.map.mdx | 10 +- .../Buffer/methods/Buffer.readBigInt64BE.mdx | 2 +- .../Buffer/methods/Buffer.readBigInt64LE.mdx | 2 +- .../Buffer/methods/Buffer.readBigUInt64BE.mdx | 2 +- .../Buffer/methods/Buffer.readBigUInt64LE.mdx | 2 +- .../methods/Buffer.readBigUint64BE-1.mdx | 2 +- .../methods/Buffer.readBigUint64LE-1.mdx | 2 +- .../Buffer/methods/Buffer.readDoubleBE.mdx | 2 +- .../Buffer/methods/Buffer.readDoubleLE.mdx | 2 +- .../Buffer/methods/Buffer.readFloatBE.mdx | 2 +- .../Buffer/methods/Buffer.readFloatLE.mdx | 2 +- .../Buffer/methods/Buffer.readInt16BE.mdx | 2 +- .../Buffer/methods/Buffer.readInt16LE.mdx | 2 +- .../Buffer/methods/Buffer.readInt32BE.mdx | 2 +- .../Buffer/methods/Buffer.readInt32LE.mdx | 2 +- .../Buffer/methods/Buffer.readInt8.mdx | 2 +- .../Buffer/methods/Buffer.readIntBE.mdx | 2 +- .../Buffer/methods/Buffer.readIntLE.mdx | 2 +- .../Buffer/methods/Buffer.readUInt16BE.mdx | 2 +- .../Buffer/methods/Buffer.readUInt16LE.mdx | 2 +- .../Buffer/methods/Buffer.readUInt32BE.mdx | 2 +- .../Buffer/methods/Buffer.readUInt32LE.mdx | 2 +- .../Buffer/methods/Buffer.readUInt8.mdx | 2 +- .../Buffer/methods/Buffer.readUIntBE.mdx | 2 +- .../Buffer/methods/Buffer.readUIntLE.mdx | 2 +- .../Buffer/methods/Buffer.readUint16BE-1.mdx | 2 +- .../Buffer/methods/Buffer.readUint16LE-1.mdx | 2 +- .../Buffer/methods/Buffer.readUint32BE-1.mdx | 2 +- .../Buffer/methods/Buffer.readUint32LE-1.mdx | 2 +- .../Buffer/methods/Buffer.readUint8-1.mdx | 2 +- .../Buffer/methods/Buffer.readUintBE-1.mdx | 2 +- .../Buffer/methods/Buffer.readUintLE-1.mdx | 2 +- .../product/Buffer/methods/Buffer.reduce.mdx | 18 +- .../Buffer/methods/Buffer.reduceRight.mdx | 18 +- .../product/Buffer/methods/Buffer.reverse.mdx | 6 +- .../product/Buffer/methods/Buffer.set.mdx | 4 +- .../product/Buffer/methods/Buffer.slice.mdx | 6 +- .../product/Buffer/methods/Buffer.some.mdx | 6 +- .../product/Buffer/methods/Buffer.sort.mdx | 6 +- .../Buffer/methods/Buffer.subarray.mdx | 8 +- .../product/Buffer/methods/Buffer.swap16.mdx | 8 +- .../product/Buffer/methods/Buffer.swap32.mdx | 8 +- .../product/Buffer/methods/Buffer.swap64.mdx | 8 +- .../product/Buffer/methods/Buffer.toJSON.mdx | 6 +- .../Buffer/methods/Buffer.toLocaleString.mdx | 2 +- .../Buffer/methods/Buffer.toString.mdx | 4 +- .../product/Buffer/methods/Buffer.valueOf.mdx | 6 +- .../product/Buffer/methods/Buffer.values.mdx | 8 +- .../product/Buffer/methods/Buffer.write.mdx | 12 +- .../Buffer/methods/Buffer.writeBigInt64BE.mdx | 2 +- .../Buffer/methods/Buffer.writeBigInt64LE.mdx | 2 +- .../methods/Buffer.writeBigUInt64BE.mdx | 2 +- .../methods/Buffer.writeBigUInt64LE.mdx | 2 +- .../methods/Buffer.writeBigUint64BE-1.mdx | 2 +- .../methods/Buffer.writeBigUint64LE-1.mdx | 2 +- .../Buffer/methods/Buffer.writeDoubleBE.mdx | 2 +- .../Buffer/methods/Buffer.writeDoubleLE.mdx | 2 +- .../Buffer/methods/Buffer.writeFloatBE.mdx | 2 +- .../Buffer/methods/Buffer.writeFloatLE.mdx | 2 +- .../Buffer/methods/Buffer.writeInt16BE.mdx | 2 +- .../Buffer/methods/Buffer.writeInt16LE.mdx | 2 +- .../Buffer/methods/Buffer.writeInt32BE.mdx | 2 +- .../Buffer/methods/Buffer.writeInt32LE.mdx | 2 +- .../Buffer/methods/Buffer.writeInt8.mdx | 2 +- .../Buffer/methods/Buffer.writeIntBE.mdx | 2 +- .../Buffer/methods/Buffer.writeIntLE.mdx | 2 +- .../Buffer/methods/Buffer.writeUInt16BE.mdx | 2 +- .../Buffer/methods/Buffer.writeUInt16LE.mdx | 2 +- .../Buffer/methods/Buffer.writeUInt32BE.mdx | 2 +- .../Buffer/methods/Buffer.writeUInt32LE.mdx | 2 +- .../Buffer/methods/Buffer.writeUInt8.mdx | 2 +- .../Buffer/methods/Buffer.writeUIntBE.mdx | 2 +- .../Buffer/methods/Buffer.writeUIntLE.mdx | 2 +- .../Buffer/methods/Buffer.writeUint16BE-1.mdx | 2 +- .../Buffer/methods/Buffer.writeUint16LE-1.mdx | 2 +- .../Buffer/methods/Buffer.writeUint32BE-1.mdx | 2 +- .../Buffer/methods/Buffer.writeUint32LE-1.mdx | 2 +- .../Buffer/methods/Buffer.writeUint8-1.mdx | 2 +- .../Buffer/methods/Buffer.writeUintBE-1.mdx | 2 +- .../Buffer/methods/Buffer.writeUintLE-1.mdx | 2 +- .../methods/BufferConstructor.alloc.mdx | 10 +- .../methods/BufferConstructor.allocUnsafe.mdx | 12 +- .../BufferConstructor.allocUnsafeSlow.mdx | 10 +- .../methods/BufferConstructor.byteLength.mdx | 14 +- .../methods/BufferConstructor.compare.mdx | 8 +- .../methods/BufferConstructor.concat.mdx | 8 +- .../BufferConstructor.copyBytesFrom.mdx | 10 +- .../methods/BufferConstructor.from.mdx | 42 +- .../methods/BufferConstructor.isBuffer.mdx | 2 +- .../methods/BufferConstructor.isEncoding.mdx | 2 +- .../methods/BufferConstructor.of.mdx | 8 +- .../methods/IProductModuleService.create.mdx | 48 +- .../IProductModuleService.createCategory.mdx | 20 +- ...ProductModuleService.createCollections.mdx | 14 +- .../IProductModuleService.createOptions.mdx | 14 +- .../IProductModuleService.createTags.mdx | 12 +- .../IProductModuleService.createTypes.mdx | 12 +- .../methods/IProductModuleService.delete.mdx | 4 +- .../IProductModuleService.deleteCategory.mdx | 4 +- ...ProductModuleService.deleteCollections.mdx | 4 +- .../IProductModuleService.deleteOptions.mdx | 4 +- .../IProductModuleService.deleteTags.mdx | 4 +- .../IProductModuleService.deleteTypes.mdx | 4 +- .../methods/IProductModuleService.list.mdx | 38 +- .../IProductModuleService.listAndCount.mdx | 20 +- ...ctModuleService.listAndCountCategories.mdx | 14 +- ...tModuleService.listAndCountCollections.mdx | 14 +- ...oductModuleService.listAndCountOptions.mdx | 14 +- ...IProductModuleService.listAndCountTags.mdx | 14 +- ...ProductModuleService.listAndCountTypes.mdx | 14 +- ...ductModuleService.listAndCountVariants.mdx | 14 +- .../IProductModuleService.listCategories.mdx | 18 +- .../IProductModuleService.listCollections.mdx | 18 +- .../IProductModuleService.listOptions.mdx | 20 +- .../IProductModuleService.listTags.mdx | 18 +- .../IProductModuleService.listTypes.mdx | 16 +- .../IProductModuleService.listVariants.mdx | 20 +- .../methods/IProductModuleService.restore.mdx | 10 +- .../IProductModuleService.restoreVariants.mdx | 10 +- .../IProductModuleService.retrieve.mdx | 48 +- ...IProductModuleService.retrieveCategory.mdx | 18 +- ...roductModuleService.retrieveCollection.mdx | 28 +- .../IProductModuleService.retrieveOption.mdx | 36 +- .../IProductModuleService.retrieveTag.mdx | 28 +- .../IProductModuleService.retrieveType.mdx | 8 +- .../IProductModuleService.retrieveVariant.mdx | 36 +- .../IProductModuleService.softDelete.mdx | 10 +- .../methods/IProductModuleService.update.mdx | 44 +- .../IProductModuleService.updateCategory.mdx | 20 +- ...ProductModuleService.updateCollections.mdx | 14 +- .../IProductModuleService.updateOptions.mdx | 14 +- .../IProductModuleService.updateTags.mdx | 12 +- .../IProductModuleService.updateTypes.mdx | 12 +- .../methods/IterableIterator._iterator_.mdx | 6 +- .../methods/IterableIterator.next.mdx | 6 +- .../methods/IterableIterator.return.mdx | 6 +- .../methods/IterableIterator.throw.mdx | 6 +- .../Iterator/methods/Iterator.next.mdx | 6 +- .../Iterator/methods/Iterator.return.mdx | 6 +- .../Iterator/methods/Iterator.throw.mdx | 6 +- .../methods/SharedArrayBuffer.slice.mdx | 10 +- .../product/enums/ProductStatus.mdx | 8 +- .../product/interfaces/BaseFilterable.mdx | 4 +- .../references/product/interfaces/Buffer.mdx | 2 +- .../product/interfaces/BufferConstructor.mdx | 36 +- .../interfaces/CreateProductCategoryDTO.mdx | 2 +- .../interfaces/CreateProductCollectionDTO.mdx | 2 +- .../product/interfaces/CreateProductDTO.mdx | 22 +- .../interfaces/CreateProductTypeDTO.mdx | 2 +- .../interfaces/CreateProductVariantDTO.mdx | 4 +- .../FilterableProductCategoryProps.mdx | 4 +- .../FilterableProductCollectionProps.mdx | 4 +- .../FilterableProductOptionProps.mdx | 4 +- .../interfaces/FilterableProductProps.mdx | 12 +- .../interfaces/FilterableProductTagProps.mdx | 4 +- .../interfaces/FilterableProductTypeProps.mdx | 4 +- .../FilterableProductVariantProps.mdx | 4 +- .../interfaces/JoinerServiceConfig.mdx | 18 +- .../interfaces/JoinerServiceConfigAlias.mdx | 2 +- .../product/interfaces/ProductCategoryDTO.mdx | 28 +- .../interfaces/ProductCollectionDTO.mdx | 46 +- .../product/interfaces/ProductDTO.mdx | 126 +- .../product/interfaces/ProductImageDTO.mdx | 2 +- .../product/interfaces/ProductOptionDTO.mdx | 66 +- .../interfaces/ProductOptionValueDTO.mdx | 66 +- .../product/interfaces/ProductTagDTO.mdx | 46 +- .../product/interfaces/ProductTypeDTO.mdx | 2 +- .../product/interfaces/ProductVariantDTO.mdx | 66 +- .../product/interfaces/SharedArrayBuffer.mdx | 6 +- .../SharedArrayBufferConstructor.mdx | 8 +- .../interfaces/UpdateProductCategoryDTO.mdx | 2 +- .../interfaces/UpdateProductCollectionDTO.mdx | 2 +- .../product/interfaces/UpdateProductDTO.mdx | 18 +- .../interfaces/UpdateProductTypeDTO.mdx | 2 +- .../interfaces/UpdateProductVariantDTO.mdx | 4 +- .../product/types/ArrayBufferLike.mdx | 2 +- .../product/types/ArrayBufferView.mdx | 2 +- .../product/types/BufferEncoding.mdx | 2 +- .../references/product/types/Exclude.mdx | 4 +- .../references/product/types/ExpandScalar.mdx | 4 +- .../references/product/types/FilterQuery.mdx | 4 +- .../references/product/types/FilterValue.mdx | 4 +- .../references/product/types/FilterValue2.mdx | 4 +- .../product/types/IteratorResult.mdx | 4 +- .../product/types/JoinerRelationship.mdx | 4 +- .../product/types/ModuleJoinerConfig.mdx | 2 +- .../types/ModuleJoinerRelationship.mdx | 2 +- .../content/references/product/types/Omit.mdx | 4 +- .../references/product/types/OperatorMap.mdx | 28 +- .../references/product/types/Partial.mdx | 4 +- .../content/references/product/types/Pick.mdx | 4 +- .../references/product/types/PrevLimit.mdx | 2 +- .../references/product/types/Primary.mdx | 4 +- .../references/product/types/Query.mdx | 4 +- .../references/product/types/Readonly.mdx | 4 +- .../product/types/ReadonlyPrimary.mdx | 4 +- .../references/product/types/Record.mdx | 4 +- .../references/product/types/Scalar.mdx | 2 +- .../references/product/types/TypedArray.mdx | 2 +- .../product/types/WithImplicitCoercion.mdx | 4 +- .../references/product/variables/Buffer-1.mdx | 2 +- .../product/variables/SharedArrayBuffer-1.mdx | 2 +- .../classes/AbstractBatchJobStrategy.mdx | 88 +- .../classes/AbstractEventBusModuleService.mdx | 52 +- .../classes/AbstractNotificationService.mdx | 60 +- .../classes/AbstractPaymentProcessor.mdx | 96 +- .../classes/AbstractPaymentService.mdx | 168 +- .../classes/AbstractSearchService.mdx | 28 +- .../references/services/classes/Address.mdx | 10 +- .../services/classes/AddressCreatePayload.mdx | 2 +- .../services/classes/AddressPayload.mdx | 4 +- .../AdminGetDiscountsDiscountRuleParams.mdx | 6 +- .../classes/AdminPriceListPricesCreateReq.mdx | 2 +- .../classes/AdminPriceListPricesUpdateReq.mdx | 2 +- .../services/classes/AnalyticsConfig.mdx | 4 +- .../classes/AnalyticsConfigService.mdx | 74 +- .../services/classes/AuthService.mdx | 72 +- .../services/classes/BaseEntity.mdx | 2 +- .../references/services/classes/BatchJob.mdx | 20 +- .../services/classes/BatchJobService.mdx | 156 +- .../references/services/classes/Cart.mdx | 36 +- .../services/classes/CartService.mdx | 434 +- .../services/classes/ClaimImage.mdx | 8 +- .../references/services/classes/ClaimItem.mdx | 18 +- .../services/classes/ClaimItemService.mdx | 82 +- .../services/classes/ClaimOrder.mdx | 26 +- .../services/classes/ClaimService.mdx | 158 +- .../references/services/classes/ClaimTag.mdx | 6 +- .../references/services/classes/Country.mdx | 4 +- .../references/services/classes/Currency.mdx | 2 +- .../services/classes/CurrencyService.mdx | 72 +- .../services/classes/CustomShippingOption.mdx | 10 +- .../classes/CustomShippingOptionService.mdx | 68 +- .../references/services/classes/Customer.mdx | 14 +- .../services/classes/CustomerGroup.mdx | 10 +- .../services/classes/CustomerGroupService.mdx | 112 +- .../services/classes/CustomerGroupUpdate.mdx | 4 +- .../services/classes/CustomerService.mdx | 198 +- .../classes/DateComparisonOperator.mdx | 2 +- .../services/classes/Discount-1.mdx | 2 +- .../references/services/classes/Discount.mdx | 12 +- .../services/classes/DiscountCondition.mdx | 32 +- .../DiscountConditionCustomerGroup.mdx | 12 +- .../classes/DiscountConditionProduct.mdx | 8 +- .../DiscountConditionProductCollection.mdx | 8 +- .../classes/DiscountConditionProductTag.mdx | 8 +- .../classes/DiscountConditionProductType.mdx | 8 +- .../classes/DiscountConditionService.mdx | 86 +- .../services/classes/DiscountRule.mdx | 14 +- .../services/classes/DiscountService.mdx | 218 +- .../services/classes/DraftOrder.mdx | 16 +- .../services/classes/DraftOrderService.mdx | 118 +- .../services/classes/EventBusService.mdx | 116 +- .../classes/FilterableBatchJobProps.mdx | 8 +- .../services/classes/FilterableCartProps.mdx | 8 +- .../classes/FilterableDiscountProps.mdx | 4 +- .../FilterableLineItemAdjustmentProps.mdx | 8 +- .../classes/FilterablePriceListProps.mdx | 12 +- .../classes/FilterableProductProps.mdx | 10 +- .../classes/FilterableProductVariantProps.mdx | 18 +- .../services/classes/FlagRouter.mdx | 24 +- .../services/classes/Fulfillment.mdx | 20 +- .../services/classes/FulfillmentItem.mdx | 6 +- .../services/classes/FulfillmentProvider.mdx | 4 +- .../classes/FulfillmentProviderService.mdx | 144 +- .../services/classes/FulfillmentService.mdx | 130 +- .../services/classes/GiftCard-1.mdx | 2 +- .../references/services/classes/GiftCard.mdx | 10 +- .../services/classes/GiftCardService.mdx | 138 +- .../services/classes/GiftCardTransaction.mdx | 8 +- .../services/classes/IdempotencyKey.mdx | 8 +- .../classes/IdempotencyKeyService.mdx | 90 +- .../references/services/classes/Image.mdx | 6 +- .../references/services/classes/LineItem.mdx | 28 +- .../services/classes/LineItemAdjustment.mdx | 10 +- .../classes/LineItemAdjustmentService.mdx | 120 +- .../services/classes/LineItemService.mdx | 150 +- .../services/classes/LineItemTaxLine.mdx | 8 +- .../services/classes/MiddlewareService.mdx | 54 +- .../services/classes/MoneyAmount.mdx | 18 +- .../services/classes/NewTotalsService.mdx | 156 +- .../references/services/classes/Note.mdx | 8 +- .../services/classes/NoteService.mdx | 96 +- .../services/classes/Notification.mdx | 14 +- .../services/classes/NotificationProvider.mdx | 4 +- .../services/classes/NotificationService.mdx | 120 +- .../classes/NumericalComparisonOperator.mdx | 2 +- .../references/services/classes/Oauth.mdx | 6 +- .../services/classes/OauthService.mdx | 104 +- .../references/services/classes/Order.mdx | 58 +- .../references/services/classes/OrderEdit.mdx | 16 +- .../classes/OrderEditItemChangeService.mdx | 82 +- .../services/classes/OrderEditService.mdx | 198 +- .../services/classes/OrderItemChange.mdx | 12 +- .../services/classes/OrderService.mdx | 344 +- .../services/classes/OrdersReturnItem.mdx | 2 +- .../references/services/classes/Payment.mdx | 16 +- .../services/classes/PaymentCollection.mdx | 18 +- .../classes/PaymentCollectionService.mdx | 122 +- .../services/classes/PaymentProvider.mdx | 4 +- .../classes/PaymentProviderService.mdx | 264 +- .../services/classes/PaymentService.mdx | 88 +- .../services/classes/PaymentSession.mdx | 10 +- .../references/services/classes/PriceList.mdx | 12 +- .../services/classes/PriceListService.mdx | 182 +- .../services/classes/PricingService.mdx | 300 +- .../references/services/classes/Product.mdx | 32 +- .../services/classes/ProductCategory.mdx | 14 +- .../classes/ProductCategoryService.mdx | 168 +- .../services/classes/ProductCollection.mdx | 8 +- .../classes/ProductCollectionService.mdx | 116 +- .../services/classes/ProductOption.mdx | 10 +- .../services/classes/ProductOptionValue.mdx | 10 +- .../services/classes/ProductService.mdx | 232 +- .../services/classes/ProductTag.mdx | 6 +- .../services/classes/ProductTaxRate.mdx | 8 +- .../services/classes/ProductType.mdx | 6 +- .../services/classes/ProductTypeService.mdx | 70 +- .../services/classes/ProductTypeTaxRate.mdx | 8 +- .../services/classes/ProductVariant.mdx | 16 +- .../classes/ProductVariantInventoryItem.mdx | 6 +- .../ProductVariantInventoryService.mdx | 254 +- .../classes/ProductVariantService.mdx | 250 +- .../references/services/classes/Refund.mdx | 10 +- .../references/services/classes/Region.mdx | 18 +- .../services/classes/RegionService.mdx | 190 +- .../references/services/classes/Return.mdx | 20 +- .../services/classes/ReturnItem.mdx | 10 +- .../services/classes/ReturnReason.mdx | 10 +- .../services/classes/ReturnReasonService.mdx | 84 +- .../services/classes/ReturnService.mdx | 166 +- .../services/classes/SalesChannel.mdx | 8 +- .../classes/SalesChannelInventoryService.mdx | 114 +- .../services/classes/SalesChannelLocation.mdx | 6 +- .../classes/SalesChannelLocationService.mdx | 88 +- .../services/classes/SalesChannelService.mdx | 136 +- .../services/classes/SearchService.mdx | 62 +- .../services/classes/ShippingMethod.mdx | 20 +- .../classes/ShippingMethodTaxLine.mdx | 8 +- .../services/classes/ShippingOption.mdx | 22 +- .../classes/ShippingOptionRequirement.mdx | 10 +- .../classes/ShippingOptionService.mdx | 202 +- .../services/classes/ShippingProfile.mdx | 18 +- .../classes/ShippingProfileService.mdx | 168 +- .../services/classes/ShippingTaxRate.mdx | 8 +- .../services/classes/SoftDeletableEntity.mdx | 2 +- .../references/services/classes/StagedJob.mdx | 8 +- .../services/classes/StagedJobService.mdx | 66 +- .../references/services/classes/Store.mdx | 16 +- ...stCustomersCustomerAddressesAddressReq.mdx | 4 +- .../services/classes/StoreService.mdx | 88 +- .../classes/StrategyResolverService.mdx | 50 +- .../classes/StringComparisonOperator.mdx | 2 +- .../references/services/classes/Swap.mdx | 28 +- .../services/classes/SwapService.mdx | 208 +- .../classes/SystemPaymentProviderService.mdx | 100 +- .../references/services/classes/TaxLine.mdx | 4 +- .../services/classes/TaxProvider.mdx | 4 +- .../services/classes/TaxProviderService.mdx | 156 +- .../references/services/classes/TaxRate.mdx | 14 +- .../services/classes/TaxRateService.mdx | 148 +- .../services/classes/TokenService.mdx | 12 +- .../services/classes/TotalsService.mdx | 248 +- .../services/classes/TrackingLink.mdx | 8 +- .../classes/TransactionBaseService.mdx | 44 +- .../references/services/classes/User.mdx | 8 +- .../services/classes/UserService.mdx | 120 +- .../services/enums/AllocationType.mdx | 4 +- .../services/enums/BatchJobStatus.mdx | 14 +- .../references/services/enums/CartType.mdx | 10 +- .../services/enums/ClaimFulfillmentStatus.mdx | 18 +- .../services/enums/ClaimPaymentStatus.mdx | 6 +- .../references/services/enums/ClaimReason.mdx | 8 +- .../references/services/enums/ClaimType.mdx | 4 +- .../DiscountConditionJoinTableForeignKey.mdx | 10 +- .../enums/DiscountConditionOperator.mdx | 4 +- .../services/enums/DiscountConditionType.mdx | 10 +- .../services/enums/DiscountRuleType.mdx | 6 +- .../services/enums/DraftOrderStatus.mdx | 4 +- .../services/enums/FulfillmentStatus-1.mdx | 18 +- .../services/enums/FulfillmentStatus.mdx | 18 +- .../services/enums/MODULE_RESOURCE_TYPE.mdx | 4 +- .../enums/OrderEditItemChangeType.mdx | 6 +- .../services/enums/OrderEditStatus.mdx | 10 +- .../services/enums/OrderStatus-1.mdx | 10 +- .../references/services/enums/OrderStatus.mdx | 10 +- .../enums/PaymentCollectionStatus.mdx | 10 +- .../services/enums/PaymentSessionStatus.mdx | 10 +- .../services/enums/PaymentStatus-1.mdx | 14 +- .../services/enums/PaymentStatus.mdx | 14 +- .../services/enums/PriceListStatus.mdx | 4 +- .../services/enums/PriceListType.mdx | 4 +- .../services/enums/ProductStatus.mdx | 8 +- .../services/enums/RequirementType.mdx | 4 +- .../services/enums/ReturnStatus.mdx | 8 +- .../enums/ShippingOptionPriceType.mdx | 4 +- .../services/enums/ShippingProfileType.mdx | 6 +- .../services/enums/SwapFulfillmentStatus.mdx | 12 +- .../services/enums/SwapPaymentStatus.mdx | 18 +- .../references/services/enums/UserRoles.mdx | 6 +- .../docs/content/references/services/index.md | 136 +- .../services/interfaces/AddPricesDTO.mdx | 2 +- .../services/interfaces/AddRulesDTO.mdx | 2 +- .../services/interfaces/BaseFilterable.mdx | 4 +- .../services/interfaces/Boolean.mdx | 2 +- .../references/services/interfaces/Buffer.mdx | 394 +- .../services/interfaces/BufferConstructor.mdx | 160 +- .../interfaces/CreateMoneyAmountDTO.mdx | 2 +- .../services/interfaces/CreateNoteInput.mdx | 4 +- .../services/interfaces/CreatePriceSetDTO.mdx | 4 +- .../services/interfaces/CreatePricesDTO.mdx | 4 +- .../services/interfaces/CreateRuleTypeDTO.mdx | 2 +- .../services/interfaces/CreateUserInput.mdx | 4 +- .../interfaces/FilterableCurrencyProps.mdx | 4 +- .../interfaces/FilterableMoneyAmountProps.mdx | 4 +- .../interfaces/FilterablePriceRuleProps.mdx | 4 +- .../FilterablePriceSetMoneyAmountProps.mdx | 4 +- ...ilterablePriceSetMoneyAmountRulesProps.mdx | 4 +- .../interfaces/FilterablePriceSetProps.mdx | 6 +- .../interfaces/FilterableRuleTypeProps.mdx | 4 +- .../services/interfaces/IBatchJobStrategy.mdx | 64 +- .../services/interfaces/ICacheService.mdx | 18 +- .../interfaces/IEventBusModuleService.mdx | 36 +- .../services/interfaces/IEventBusService.mdx | 34 +- .../services/interfaces/IFlagRouter.mdx | 2 +- .../services/interfaces/IInventoryService.mdx | 264 +- .../interfaces/INotificationService.mdx | 50 +- .../interfaces/IPriceSelectionStrategy.mdx | 24 +- .../interfaces/IPricingModuleService.mdx | 458 +- .../services/interfaces/ISearchService.mdx | 18 +- .../interfaces/IStockLocationService.mdx | 68 +- .../interfaces/ITaxCalculationStrategy.mdx | 12 +- .../services/interfaces/ITaxService.mdx | 12 +- .../interfaces/ITransactionBaseService.mdx | 8 +- .../services/interfaces/IterableIterator.mdx | 24 +- .../services/interfaces/Iterator.mdx | 18 +- .../interfaces/JoinerServiceConfig.mdx | 12 +- .../interfaces/JoinerServiceConfigAlias.mdx | 2 +- .../services/interfaces/MoneyAmountDTO.mdx | 2 +- .../services/interfaces/PaymentProcessor.mdx | 84 +- .../services/interfaces/PriceRuleDTO.mdx | 4 +- .../services/interfaces/PriceSetDTO.mdx | 4 +- .../interfaces/PriceSetMoneyAmountDTO.mdx | 6 +- .../PriceSetMoneyAmountRulesDTO.mdx | 4 +- .../services/interfaces/PricingContext.mdx | 2 +- .../services/interfaces/RemoteJoinerQuery.mdx | 4 +- .../services/interfaces/RuleTypeDTO.mdx | 2 +- .../services/interfaces/SharedArrayBuffer.mdx | 8 +- .../SharedArrayBufferConstructor.mdx | 4 +- .../services/interfaces/UpdateRuleTypeDTO.mdx | 2 +- .../services/interfaces/UpdateUserInput.mdx | 4 +- .../types/AddOrderEditLineItemInput.mdx | 4 +- .../services/types/AdjustmentContext.mdx | 2 +- .../services/types/AllocationMapOptions.mdx | 2 +- .../services/types/ArrayBufferLike.mdx | 2 +- .../services/types/ArrayBufferView.mdx | 2 +- .../services/types/AuthenticateResult.mdx | 6 +- .../services/types/AvailabilityContext.mdx | 6 +- .../services/types/BatchJobCreateProps.mdx | 2 +- .../services/types/BatchJobResultError.mdx | 4 +- .../types/BatchJobResultStatDescriptor.mdx | 2 +- .../services/types/BufferEncoding.mdx | 2 +- .../types/CalculateOptionPriceInput.mdx | 4 +- .../services/types/CalculationContextData.mdx | 18 +- .../types/CalculationContextOptions.mdx | 2 +- .../services/types/CartCreateProps.mdx | 16 +- .../services/types/CartUpdateProps.mdx | 12 +- .../services/types/CategoryQueryParams.mdx | 2 +- .../services/types/ClaimTypeValue.mdx | 2 +- .../services/types/ConfigModule-1.mdx | 2 +- .../services/types/ConfigModule.mdx | 10 +- .../services/types/CreateAnalyticsConfig.mdx | 2 +- .../services/types/CreateBatchJobInput.mdx | 4 +- .../services/types/CreateClaimInput.mdx | 18 +- .../CreateClaimItemAdditionalItemInput.mdx | 2 +- .../services/types/CreateClaimItemInput.mdx | 4 +- .../types/CreateClaimReturnShippingInput.mdx | 2 +- .../types/CreateClaimShippingMethodInput.mdx | 4 +- .../types/CreateCustomShippingOptionInput.mdx | 4 +- .../services/types/CreateCustomerInput.mdx | 4 +- .../services/types/CreateDiscountInput.mdx | 8 +- .../types/CreateDiscountRuleInput.mdx | 8 +- .../types/CreateDynamicDiscountInput.mdx | 4 +- .../services/types/CreateFulfillmentOrder.mdx | 2 +- .../services/types/CreateGiftCardInput.mdx | 4 +- .../types/CreateGiftCardTransactionInput.mdx | 2 +- .../types/CreateIdempotencyKeyInput.mdx | 4 +- .../types/CreateInventoryItemInput.mdx | 4 +- .../types/CreateInventoryLevelInput.mdx | 2 +- .../services/types/CreateOauthInput.mdx | 2 +- .../services/types/CreateOrderEditInput.mdx | 2 +- .../types/CreateOrderEditItemChangeInput.mdx | 4 +- .../types/CreatePaymentCollectionInput.mdx | 4 +- .../services/types/CreatePaymentInput.mdx | 4 +- .../services/types/CreatePriceListInput.mdx | 10 +- .../types/CreateProductCategoryInput.mdx | 2 +- .../types/CreateProductCollection.mdx | 4 +- .../services/types/CreateProductInput.mdx | 18 +- .../CreateProductProductCategoryInput.mdx | 2 +- .../types/CreateProductProductOption.mdx | 2 +- .../CreateProductProductSalesChannelInput.mdx | 2 +- .../types/CreateProductProductTagInput.mdx | 2 +- .../types/CreateProductProductTypeInput.mdx | 2 +- .../CreateProductProductVariantInput.mdx | 8 +- .../CreateProductProductVariantPriceInput.mdx | 2 +- .../types/CreateProductVariantInput.mdx | 8 +- .../services/types/CreateRegionInput.mdx | 4 +- .../types/CreateReservationItemInput.mdx | 4 +- .../services/types/CreateReturnInput.mdx | 6 +- .../services/types/CreateReturnReason.mdx | 4 +- .../services/types/CreateReturnType.mdx | 2 +- .../types/CreateSalesChannelInput.mdx | 2 +- .../services/types/CreateShipmentConfig.mdx | 4 +- .../services/types/CreateShippingMethod.mdx | 2 +- .../types/CreateShippingMethodDto.mdx | 2 +- .../types/CreateShippingOptionInput.mdx | 10 +- .../services/types/CreateShippingProfile.mdx | 6 +- .../types/CreateStockLocationInput.mdx | 6 +- .../services/types/CreateTaxRateInput.mdx | 2 +- .../types/CustomerGroupConstructorProps.mdx | 6 +- .../references/services/types/Data.mdx | 2 +- .../types/DefaultWithoutRelations-1.mdx | 2 +- .../types/DefaultWithoutRelations.mdx | 2 +- .../references/services/types/Discount-2.mdx | 2 +- .../services/types/DiscountAllocation.mdx | 2 +- .../services/types/DiscountConditionInput.mdx | 14 +- .../types/DiscountConditionResourceType.mdx | 2 +- .../services/types/DraftOrderCreateProps.mdx | 14 +- .../references/services/types/EmitData.mdx | 8 +- .../references/services/types/Exclude.mdx | 4 +- .../services/types/ExtendedFindConfig-1.mdx | 4 +- .../services/types/ExtendedFindConfig.mdx | 4 +- .../types/ExternalModuleDeclaration.mdx | 8 +- .../services/types/FeatureFlagsResponse.mdx | 2 +- .../types/FilterableInventoryItemProps.mdx | 6 +- .../types/FilterableInventoryLevelProps.mdx | 8 +- .../types/FilterableReservationItemProps.mdx | 6 +- .../types/FilterableStockLocationProps.mdx | 4 +- .../services/types/FilterableTaxRateProps.mdx | 12 +- .../services/types/FilterableUserProps.mdx | 2 +- .../services/types/FindProductConfig.mdx | 2 +- .../types/FindWithRelationsOptions.mdx | 2 +- .../types/FindWithoutRelationsOptions-1.mdx | 2 +- .../types/FindWithoutRelationsOptions.mdx | 2 +- .../services/types/FulFillmentItemType.mdx | 2 +- .../types/FulfillmentItemPartition.mdx | 6 +- .../services/types/FulfillmentOptions.mdx | 4 +- .../types/FulfillmentProviderContainer.mdx | 2 +- .../services/types/FulfillmentProviderKey.mdx | 2 +- .../services/types/GenerateInputData.mdx | 4 +- .../types/GenerateLineItemContext.mdx | 6 +- .../services/types/GeneratedAdjustment.mdx | 2 +- .../types/GetLineItemTotalOptions.mdx | 2 +- .../services/types/GetRegionPriceContext.mdx | 2 +- .../types/GetShippingMethodTotalsOptions.mdx | 4 +- .../services/types/GetTotalsOptions.mdx | 2 +- .../services/types/GiftCardAllocation.mdx | 2 +- .../services/types/GiftCardTransaction-1.mdx | 4 +- .../services/types/HttpCompressionOptions.mdx | 2 +- .../types/IdempotencyCallbackResult.mdx | 4 +- .../services/types/InjectedDependencies-1.mdx | 6 +- .../types/InjectedDependencies-10.mdx | 8 +- .../types/InjectedDependencies-11.mdx | 18 +- .../types/InjectedDependencies-12.mdx | 10 +- .../types/InjectedDependencies-13.mdx | 4 +- .../types/InjectedDependencies-14.mdx | 22 +- .../types/InjectedDependencies-15.mdx | 8 +- .../types/InjectedDependencies-16.mdx | 6 +- .../types/InjectedDependencies-17.mdx | 8 +- .../types/InjectedDependencies-18.mdx | 2 +- .../types/InjectedDependencies-19.mdx | 44 +- .../services/types/InjectedDependencies-2.mdx | 8 +- .../types/InjectedDependencies-20.mdx | 22 +- .../types/InjectedDependencies-21.mdx | 10 +- .../types/InjectedDependencies-22.mdx | 8 +- .../types/InjectedDependencies-23.mdx | 10 +- .../types/InjectedDependencies-24.mdx | 2 +- .../types/InjectedDependencies-25.mdx | 16 +- .../types/InjectedDependencies-26.mdx | 24 +- .../types/InjectedDependencies-27.mdx | 6 +- .../types/InjectedDependencies-28.mdx | 8 +- .../types/InjectedDependencies-29.mdx | 14 +- .../services/types/InjectedDependencies-3.mdx | 56 +- .../types/InjectedDependencies-30.mdx | 24 +- .../types/InjectedDependencies-31.mdx | 24 +- .../types/InjectedDependencies-32.mdx | 4 +- .../types/InjectedDependencies-33.mdx | 8 +- .../types/InjectedDependencies-34.mdx | 8 +- .../types/InjectedDependencies-35.mdx | 8 +- .../types/InjectedDependencies-36.mdx | 4 +- .../types/InjectedDependencies-37.mdx | 14 +- .../types/InjectedDependencies-38.mdx | 14 +- .../types/InjectedDependencies-39.mdx | 8 +- .../services/types/InjectedDependencies-4.mdx | 34 +- .../types/InjectedDependencies-40.mdx | 4 +- .../types/InjectedDependencies-41.mdx | 4 +- .../services/types/InjectedDependencies-5.mdx | 8 +- .../services/types/InjectedDependencies-6.mdx | 4 +- .../services/types/InjectedDependencies-7.mdx | 8 +- .../services/types/InjectedDependencies-8.mdx | 6 +- .../services/types/InjectedDependencies-9.mdx | 20 +- .../services/types/InjectedDependencies.mdx | 4 +- .../services/types/InjectedProps.mdx | 28 +- .../types/InternalModuleDeclaration.mdx | 10 +- .../services/types/InventoryItemDTO.mdx | 4 +- .../services/types/InventoryLevelDTO.mdx | 4 +- .../references/services/types/Item.mdx | 4 +- .../services/types/ItemTaxCalculationLine.mdx | 6 +- .../services/types/IteratorResult.mdx | 4 +- .../services/types/JoinerRelationship.mdx | 4 +- .../services/types/LineAllocationsMap.mdx | 6 +- .../services/types/LineDiscount.mdx | 4 +- .../services/types/LineDiscountAmount.mdx | 4 +- .../types/LineItemAdjustmentServiceProps.mdx | 6 +- .../services/types/LineItemTotals-1.mdx | 4 +- .../services/types/LineItemTotals.mdx | 4 +- .../services/types/LineItemTotalsOptions.mdx | 4 +- .../services/types/LineItemUpdate.mdx | 4 +- .../services/types/LineItemValidateData.mdx | 2 +- .../services/types/ListAndCountSelector.mdx | 2 +- .../references/services/types/Logger-1.mdx | 2 +- .../services/types/MedusaContainer-1.mdx | 2 +- .../services/types/MedusaContainer.mdx | 2 +- .../services/types/ModuleDefinition.mdx | 4 +- .../services/types/ModuleJoinerConfig.mdx | 2 +- .../types/ModuleJoinerRelationship.mdx | 2 +- .../references/services/types/Omit.mdx | 4 +- .../services/types/OrdersReturnItem-1.mdx | 2 +- .../references/services/types/Partial.mdx | 4 +- .../references/services/types/PartialPick.mdx | 4 +- .../PaymentCollectionsSessionsBatchInput.mdx | 2 +- .../types/PaymentCollectionsSessionsInput.mdx | 2 +- .../services/types/PaymentContext.mdx | 14 +- .../services/types/PaymentDataInput.mdx | 4 +- .../types/PaymentProcessorContext.mdx | 10 +- .../types/PaymentProcessorSessionResponse.mdx | 6 +- .../services/types/PaymentProviderKey.mdx | 2 +- .../services/types/PaymentSessionInput.mdx | 8 +- .../services/types/PaymentSessionResponse.mdx | 6 +- .../references/services/types/Pick.mdx | 4 +- .../references/services/types/Price.mdx | 2 +- .../types/PriceListConstructorProps.mdx | 18 +- .../services/types/PriceListLoadConfig.mdx | 2 +- .../types/PriceListPriceCreateInput.mdx | 2 +- .../types/PriceListPriceUpdateInput.mdx | 2 +- .../services/types/PriceSelectionContext.mdx | 4 +- .../services/types/PriceSelectionResult.mdx | 6 +- .../references/services/types/PriceType.mdx | 2 +- .../services/types/PricedProduct.mdx | 2 +- .../services/types/PricedShippingOption.mdx | 2 +- .../services/types/PricedVariant.mdx | 2 +- .../services/types/PricingContext-1.mdx | 4 +- .../services/types/ProductCategoryInput.mdx | 4 +- .../services/types/ProductOptionInput.mdx | 4 +- .../services/types/ProductSelector.mdx | 2 +- .../services/types/ProductVariantOption.mdx | 2 +- .../services/types/ProductVariantPrice.mdx | 2 +- .../services/types/ProductVariantPricing.mdx | 2 +- .../services/types/ProjectConfigOptions.mdx | 8 +- .../types/ProviderLineItemTaxLine.mdx | 4 +- .../types/ProviderShippingMethodTaxLine.mdx | 4 +- .../services/types/ProviderTaxLine.mdx | 2 +- .../services/types/QuerySelector.mdx | 4 +- .../references/services/types/Record.mdx | 4 +- .../services/types/RegionDetails.mdx | 2 +- .../services/types/RemoteQueryFunction.mdx | 16 +- .../services/types/ReorderConditions.mdx | 2 +- .../references/services/types/Required.mdx | 4 +- .../services/types/ReservationItemDTO.mdx | 4 +- .../services/types/ReserveQuantityContext.mdx | 2 +- .../services/types/ReturnedData.mdx | 4 +- .../references/services/types/Selector.mdx | 4 +- .../services/types/SessionOptions.mdx | 2 +- .../services/types/SharedContext.mdx | 2 +- .../services/types/ShippingMethod-1.mdx | 4 +- .../services/types/ShippingMethodTotals-1.mdx | 4 +- .../services/types/ShippingMethodTotals.mdx | 4 +- .../services/types/ShippingMethodUpdate.mdx | 2 +- .../services/types/ShippingOptionPricing.mdx | 4 +- .../types/ShippingTaxCalculationLine.mdx | 6 +- .../services/types/StagedJobServiceProps.mdx | 4 +- .../types/StockLocationAddressDTO.mdx | 4 +- .../types/StockLocationAddressInput.mdx | 4 +- .../services/types/StockLocationDTO.mdx | 6 +- .../references/services/types/Subscriber.mdx | 12 +- .../services/types/SubscriberContext.mdx | 2 +- .../services/types/SubscriberDescriptor.mdx | 4 +- .../services/types/SubtotalOptions.mdx | 2 +- .../services/types/TaxCalculationContext.mdx | 12 +- .../services/types/TaxLinesMaps.mdx | 2 +- .../services/types/TaxRateListByConfig.mdx | 2 +- .../services/types/TaxServiceRate.mdx | 2 +- .../services/types/TaxedPricing.mdx | 4 +- .../references/services/types/TotalField.mdx | 2 +- .../services/types/TotalsConfig.mdx | 2 +- .../services/types/TotalsContext.mdx | 2 +- .../services/types/TotalsServiceProps.mdx | 10 +- .../references/services/types/Transformer.mdx | 16 +- .../services/types/TreeQuerySelector.mdx | 4 +- .../references/services/types/TypedArray.mdx | 2 +- .../services/types/UpdateAnalyticsConfig.mdx | 2 +- .../services/types/UpdateClaimInput.mdx | 8 +- .../types/UpdateClaimItemImageInput.mdx | 2 +- .../services/types/UpdateClaimItemInput.mdx | 8 +- .../types/UpdateClaimItemTagInput.mdx | 2 +- .../types/UpdateClaimShippingMethodInput.mdx | 4 +- .../services/types/UpdateCurrencyInput.mdx | 2 +- .../services/types/UpdateCustomerInput.mdx | 8 +- .../services/types/UpdateDiscountInput.mdx | 6 +- .../types/UpdateDiscountRuleInput.mdx | 6 +- .../services/types/UpdateGiftCardInput.mdx | 4 +- .../types/UpdateInventoryLevelInput.mdx | 2 +- .../services/types/UpdateOauthInput.mdx | 4 +- .../services/types/UpdateOrderInput.mdx | 20 +- .../services/types/UpdatePriceListInput.mdx | 2 +- .../types/UpdateProductCategoryInput.mdx | 2 +- .../types/UpdateProductCollection.mdx | 4 +- .../services/types/UpdateProductInput.mdx | 2 +- .../types/UpdateProductProductVariantDTO.mdx | 8 +- .../types/UpdateProductVariantData.mdx | 6 +- .../types/UpdateProductVariantInput.mdx | 8 +- .../services/types/UpdateRegionInput.mdx | 4 +- .../types/UpdateReservationItemInput.mdx | 4 +- .../services/types/UpdateReturnInput.mdx | 6 +- .../services/types/UpdateReturnReason.mdx | 4 +- .../types/UpdateShippingOptionInput.mdx | 8 +- .../services/types/UpdateShippingProfile.mdx | 6 +- .../types/UpdateStockLocationInput.mdx | 6 +- .../services/types/UpdateStoreInput.mdx | 4 +- .../services/types/UpdateTaxRateInput.mdx | 2 +- .../types/UpdateVariantPricesData.mdx | 4 +- .../types/UpdateVariantRegionPriceData.mdx | 2 +- .../services/types/UpsertTagsInput.mdx | 2 +- .../services/types/UpsertTypeInput.mdx | 2 +- .../services/types/UserServiceProps.mdx | 10 +- .../types/ValidatePriceTypeAndAmountInput.mdx | 4 +- .../services/types/WithImplicitCoercion.mdx | 4 +- .../services/types/WithRequiredProperty.mdx | 4 +- .../services/types/middlewareHandlerType.mdx | 8 +- .../services/types/middlewareType.mdx | 6 +- .../starters/nextjs-medusa-starter.mdx | 6 +- .../cli-installation-errors/_yarn-error.mdx | 24 +- .../_module-x-error.mdx | 24 +- .../_other-errors.mdx | 24 +- .../content/upgrade-guides/admin/1-0-0.md | 2 +- www/apps/docs/content/usage.md | 2 + www/apps/docs/content/user-guide.mdx | 2 +- www/apps/docs/docusaurus.config.js | 29 +- www/apps/docs/package.json | 25 +- www/apps/docs/sidebars.js | 2 +- .../docs/src/components/LargeCard/index.tsx | 5 +- .../MobileLogo/index.tsx | 2 +- .../components/ParameterTypes/Items/index.tsx | 7 +- .../docs/src/theme/Admonition/Icon/Danger.tsx | 16 + .../docs/src/theme/Admonition/Icon/Info.tsx | 7 + .../docs/src/theme/Admonition/Icon/Note.tsx | 19 + .../docs/src/theme/Admonition/Icon/Tip.tsx | 19 + .../src/theme/Admonition/Icon/Warning.tsx | 7 + .../src/theme/Admonition/Layout/index.tsx | 51 + www/apps/docs/src/theme/Admonition/index.tsx | 188 - .../AnnouncementBar/CloseButton/index.tsx | 2 +- .../docs/src/theme/AnnouncementBar/index.tsx | 1 + .../src/theme/CodeBlock/Content/String.tsx | 16 +- www/apps/docs/src/theme/CodeBlock/index.tsx | 1 - www/apps/docs/src/theme/DocCard/index.tsx | 9 +- www/apps/docs/src/theme/DocCardList/index.tsx | 9 +- .../docs/src/theme/DocItem/Content/index.tsx | 3 +- .../docs/src/theme/DocItem/Footer/index.tsx | 5 +- .../docs/src/theme/DocItem/Layout/index.tsx | 7 +- www/apps/docs/src/theme/DocPage/index.tsx | 73 - .../Layout/Main/index.tsx | 7 +- .../Layout/Sidebar/index.tsx | 8 +- .../{DocPage => DocRoot}/Layout/index.tsx | 25 +- www/apps/docs/src/theme/DocRoot/index.tsx | 33 + .../src/theme/DocSidebar/Desktop/index.tsx | 2 +- .../theme/DocSidebarItem/Category/index.tsx | 11 +- .../src/theme/DocSidebarItem/Link/index.tsx | 2 +- .../docs/src/theme/DocSidebarItems/index.tsx | 54 + www/apps/docs/src/theme/DocsRoot/index.tsx | 21 + .../docs/src/theme/EditThisPage/index.tsx | 2 +- .../docs/src/theme/Footer/Layout/index.tsx | 2 +- www/apps/docs/src/theme/Footer/index.tsx | 26 - www/apps/docs/src/theme/Layout/index.tsx | 1 + www/apps/docs/src/theme/MDXComponents/A.tsx | 4 +- .../docs/src/theme/MDXComponents/Code.tsx | 17 + .../docs/src/theme/MDXComponents/Details.tsx | 23 +- www/apps/docs/src/theme/MDXComponents/H1.tsx | 2 +- .../docs/src/theme/MDXComponents/index.tsx | 10 +- .../docs/src/theme/Navbar/Content/index.tsx | 6 +- www/apps/docs/src/theme/Navbar/Logo/index.tsx | 2 +- .../Navbar/MobileSidebar/Header/index.tsx | 13 +- .../src/theme/NavbarItem/NavbarNavLink.tsx | 2 +- www/apps/docs/src/theme/NotFound.tsx | 86 - .../docs/src/theme/NotFound/Content/index.tsx | 75 + www/apps/docs/src/theme/NotFound/index.tsx | 21 + www/apps/docs/src/theme/TOCItems/index.tsx | 2 +- www/apps/docs/src/theme/Tabs/index.tsx | 28 +- www/apps/docs/src/themes/medusaDocs.js | 12 - www/apps/docs/src/utils/reverse-sidebar.js | 2 +- www/packages/docs-ui/package.json | 16 +- .../src/components/BorderedIcon/index.tsx | 3 +- .../docs-ui/src/components/Modal/index.tsx | 2 +- .../docs-ui/src/components/Tooltip/index.tsx | 11 +- www/packages/tsconfig/docusaurus.json | 5 +- www/packages/tsconfig/package.json | 2 +- www/yarn.lock | 4707 +++++++++++------ 2265 files changed, 46163 insertions(+), 47195 deletions(-) delete mode 100644 www/apps/docs/content/admin/onboarding.md create mode 100644 www/apps/docs/content/admin/onboarding.mdx rename www/apps/docs/content/modules/products/{products.md => products.mdx} (99%) rename www/apps/docs/content/modules/products/{serverless-module.md => serverless-module.mdx} (99%) rename www/apps/docs/content/plugins/cms/{contentful.md => contentful.mdx} (64%) rename www/apps/docs/src/{theme => components}/MobileLogo/index.tsx (96%) create mode 100644 www/apps/docs/src/theme/Admonition/Icon/Danger.tsx create mode 100644 www/apps/docs/src/theme/Admonition/Icon/Info.tsx create mode 100644 www/apps/docs/src/theme/Admonition/Icon/Note.tsx create mode 100644 www/apps/docs/src/theme/Admonition/Icon/Tip.tsx create mode 100644 www/apps/docs/src/theme/Admonition/Icon/Warning.tsx create mode 100644 www/apps/docs/src/theme/Admonition/Layout/index.tsx delete mode 100644 www/apps/docs/src/theme/Admonition/index.tsx delete mode 100644 www/apps/docs/src/theme/DocPage/index.tsx rename www/apps/docs/src/theme/{DocPage => DocRoot}/Layout/Main/index.tsx (81%) rename www/apps/docs/src/theme/{DocPage => DocRoot}/Layout/Sidebar/index.tsx (93%) rename www/apps/docs/src/theme/{DocPage => DocRoot}/Layout/index.tsx (69%) create mode 100644 www/apps/docs/src/theme/DocRoot/index.tsx create mode 100644 www/apps/docs/src/theme/DocSidebarItems/index.tsx create mode 100644 www/apps/docs/src/theme/DocsRoot/index.tsx delete mode 100644 www/apps/docs/src/theme/Footer/index.tsx create mode 100644 www/apps/docs/src/theme/MDXComponents/Code.tsx delete mode 100644 www/apps/docs/src/theme/NotFound.tsx create mode 100644 www/apps/docs/src/theme/NotFound/Content/index.tsx create mode 100644 www/apps/docs/src/theme/NotFound/index.tsx delete mode 100644 www/apps/docs/src/themes/medusaDocs.js diff --git a/.github/workflows/docs-test.yml b/.github/workflows/docs-test.yml index 9dc556f4fe..8d4678d06a 100644 --- a/.github/workflows/docs-test.yml +++ b/.github/workflows/docs-test.yml @@ -22,7 +22,7 @@ jobs: - name: Setup Node.js environment uses: actions/setup-node@v3 with: - node-version: "16.14.0" + node-version: "18" cache: "yarn" - name: Install dependencies diff --git a/docs-util/packages/typedoc-config/entities.js b/docs-util/packages/typedoc-config/entities.js index e793fde101..5de58698b7 100644 --- a/docs-util/packages/typedoc-config/entities.js +++ b/docs-util/packages/typedoc-config/entities.js @@ -20,6 +20,12 @@ module.exports = { sections: { member_sources_definedIn: false, reflection_hierarchy: false, + member_sources_inheritedFrom: false, + member_sources_implementationOf: false, + reflection_implementedBy: false, + member_signature_sources: false, + reflection_callable: false, + reflection_indexable: false, }, parameterStyle: "component", parameterComponent: "ParameterTypes", diff --git a/docs-util/packages/typedoc-config/js-client.js b/docs-util/packages/typedoc-config/js-client.js index 003a144ee5..080c8fb168 100644 --- a/docs-util/packages/typedoc-config/js-client.js +++ b/docs-util/packages/typedoc-config/js-client.js @@ -14,6 +14,10 @@ const defaultFormattingOptions = { member_signature_title: false, member_signature_returns: false, title_reflectionPath: false, + reflection_callable: false, + reflection_indexable: false, + reflection_implementedBy: false, + member_declaration_title: false, }, parameterStyle: "component", parameterComponent: "ParameterTypes", diff --git a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/helpers/comment.ts b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/helpers/comment.ts index e5f3882193..6f63846091 100644 --- a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/helpers/comment.ts +++ b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/helpers/comment.ts @@ -3,6 +3,7 @@ import * as Handlebars from "handlebars" import * as Path from "path" import { CommentDisplayPart } from "typedoc/dist/lib/models/comments/comment" import { MarkdownTheme } from "../../theme" +import { escapeChars } from "../../utils" export default function (theme: MarkdownTheme) { Handlebars.registerHelper("comment", function (parts: CommentDisplayPart[]) { @@ -10,6 +11,8 @@ export default function (theme: MarkdownTheme) { for (const part of parts) { switch (part.kind) { case "text": + result.push(escapeChars(part.text, false)) + break case "code": result.push(part.text) break diff --git a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/helpers/declaration-title.ts b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/helpers/declaration-title.ts index 7d85fabad2..c3f596e974 100644 --- a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/helpers/declaration-title.ts +++ b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/helpers/declaration-title.ts @@ -31,7 +31,8 @@ export default function (theme: MarkdownTheme) { (reflection.parent?.kindOf(ReflectionKind.Enum) ? " = " : ": ") + Handlebars.helpers.type.call( reflectionType ? reflectionType : reflection, - "object" + "object", + false ) ) } @@ -43,11 +44,7 @@ export default function (theme: MarkdownTheme) { `${this.flags.isRest ? "... " : ""} **${escapeChars(this.name)}**` ) if (this instanceof DeclarationReflection && this.typeParameters) { - md.push( - `<${this.typeParameters - .map((typeParameter) => `\`${typeParameter.name}\``) - .join(", ")}\\>` - ) + md.push(`\`<${this.typeParameters.join(", ")}>\``) } md.push(getType(this)) diff --git a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/helpers/reflection-title.ts b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/helpers/reflection-title.ts index cd11732572..2fa95ec9b1 100644 --- a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/helpers/reflection-title.ts +++ b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/helpers/reflection-title.ts @@ -28,7 +28,7 @@ export default function (theme: MarkdownTheme) { const typeParameters = this.model.typeParameters .map((typeParameter: ParameterReflection) => typeParameter.name) .join(", ") - title.push(`<${typeParameters}${shouldEscape ? "\\>" : ">"}`) + title.push(`\`<${typeParameters}>\``) } } if (reflectionTitle?.suffix) { diff --git a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/helpers/signature-title.ts b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/helpers/signature-title.ts index 3892e160e8..3793ff45e1 100644 --- a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/helpers/signature-title.ts +++ b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/helpers/signature-title.ts @@ -4,7 +4,7 @@ import { ReflectionKind, SignatureReflection, } from "typedoc" -import { memberSymbol } from "../../utils" +import { getHTMLChar, memberSymbol } from "../../utils" import { MarkdownTheme } from "../../theme" export default function (theme: MarkdownTheme) { @@ -21,30 +21,23 @@ export default function (theme: MarkdownTheme) { } const md: string[] = [] + if (!expandMembers) { + md.push("`") + } + if (standalone && !theme.hideMembersSymbol) { md.push(`${memberSymbol(this)} `) } if (this.parent && this.parent.flags?.length > 0) { - md.push( - this.parent.flags - .map( - (flag) => - `${!expandMembers ? "`" : ""}${flag}${ - !expandMembers ? "`" : "" - }` - ) - .join(" ") + " " - ) + md.push(this.parent.flags.join(" ") + " ") } if (accessor) { md.push( - `${!expandMembers ? "`" : ""}${accessor}${ - !expandMembers ? "`" : "" - } ${expandMembers ? `${Handlebars.helpers.titleLevel(4)} ` : "**"}${ - this.name - }${!expandMembers ? "**" : ""}` + `${accessor}${ + expandMembers ? `${Handlebars.helpers.titleLevel(4)} ` : "**" + }${this.name}${!expandMembers ? "**" : ""}` ) } else if (this.name !== "__call" && this.name !== "__type") { md.push( @@ -56,22 +49,19 @@ export default function (theme: MarkdownTheme) { if (this.typeParameters) { md.push( - `<${this.typeParameters - .map( - (typeParameter) => - `${!expandMembers ? "`" : ""}${typeParameter.name}${ - !expandMembers ? "`" : "" - }` - ) - .join(", ")}\\>` + `${expandMembers ? getHTMLChar("<") : "<"}${this.typeParameters.join( + ", " + )}${expandMembers ? getHTMLChar(">") : ">"}` ) } - md.push(`(${getParameters(this.parameters, !expandMembers)})`) + md.push(`(${getParameters(this.parameters, false)})`) if (this.type && !this.parent?.kindOf(ReflectionKind.Constructor)) { - md.push( - `: ${Handlebars.helpers.type.call(this.type, "none", !expandMembers)}` - ) + md.push(`: ${Handlebars.helpers.type.call(this.type, "none", false)}`) + } + + if (!expandMembers) { + md.push("`") } return md.join("") + (standalone ? "\n" : "") } diff --git a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/comment.hbs b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/comment.hbs index c3a2f4572f..1d950b6ffd 100755 --- a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/comment.hbs +++ b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/comment.hbs @@ -4,7 +4,7 @@ {{#if hasVisibleComponent}} -{{{comments this}}} +{{{comments this true true 4 model}}} {{/if}} diff --git a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/member.declaration.hbs b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/member.declaration.hbs index 40b259ef54..cf79ca1071 100755 --- a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/member.declaration.hbs +++ b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/member.declaration.hbs @@ -1,10 +1,18 @@ +{{#if (sectionEnabled "member_declaration_title")}} + {{{declarationTitle}}} +{{/if}} + +{{#if (sectionEnabled "member_declaration_comment")}} + {{> comment}} +{{/if}} + {{#if (sectionEnabled "member_declaration_example")}} -{{{example this 4}}} +{{{example this 3}}} {{/if}} @@ -12,7 +20,7 @@ {{#if typeParameters}} -{{titleLevel 4}} Type parameters +{{titleLevel 3}} Type parameters {{#with typeParameters}} @@ -32,7 +40,7 @@ {{#with type.declaration.indexSignature}} -{{titleLevel 4}} Index signature +{{titleLevel 3}} Index signature {{{indexSignatureTitle}}} @@ -50,11 +58,11 @@ {{#if type.declaration.children}} -{{titleLevel 4}} Call signature +{{titleLevel 3}} Call signature {{else}} -{{titleLevel 4}} Type declaration +{{titleLevel 3}} Type declaration {{/if}} @@ -74,7 +82,7 @@ {{#with type.declaration}} -{{titleLevel 4}} Type declaration +{{titleLevel 3}} Type declaration {{/with}} diff --git a/docs-util/packages/typedoc-plugin-markdown-medusa/src/types.ts b/docs-util/packages/typedoc-plugin-markdown-medusa/src/types.ts index f7d48876df..8187cf1d80 100644 --- a/docs-util/packages/typedoc-plugin-markdown-medusa/src/types.ts +++ b/docs-util/packages/typedoc-plugin-markdown-medusa/src/types.ts @@ -19,6 +19,9 @@ export type ObjectLiteralDeclarationStyle = "table" | "list" | "component" export type SectionKey = | "comment" + | "member_declaration" + | "member_declaration_title" + | "member_declaration_comment" | "member_declaration_typeParameters" | "member_declaration_indexSignature" | "member_declaration_signatures" @@ -29,7 +32,6 @@ export type SectionKey = | "member_signatures" | "member_getterSetter" | "member_reference" - | "member_declaration" | "member_signature_title" | "member_signature_comment" | "member_signature_typeParameters" diff --git a/docs-util/packages/typedoc-plugin-markdown-medusa/src/utils.ts b/docs-util/packages/typedoc-plugin-markdown-medusa/src/utils.ts index 32f0bc1594..462b0c684b 100644 --- a/docs-util/packages/typedoc-plugin-markdown-medusa/src/utils.ts +++ b/docs-util/packages/typedoc-plugin-markdown-medusa/src/utils.ts @@ -16,13 +16,17 @@ export function formatContents(contents: string) { ) } -export function escapeChars(str: string) { +export function getHTMLChar(str: string) { return str - .replace(/>/g, "\\>") - .replace(/>/g, "\\>") - .replace(/_/g, "\\_") - .replace(/`/g, "\\`") - .replace(/\|/g, "\\|") + .replace(//g, ">") +} + +export function escapeChars(str: string, escapeBackticks = true) { + const result = getHTMLChar(str).replace(/_/g, "\\_").replace(/\|/g, "\\|") + return escapeBackticks ? result.replace(/`/g, "\\`") : result } export function memberSymbol( diff --git a/docs-util/packages/typedoc-plugin-markdown-medusa/src/utils/reflection-formatter.ts b/docs-util/packages/typedoc-plugin-markdown-medusa/src/utils/reflection-formatter.ts index 94983c1c03..fc7909b1dd 100644 --- a/docs-util/packages/typedoc-plugin-markdown-medusa/src/utils/reflection-formatter.ts +++ b/docs-util/packages/typedoc-plugin-markdown-medusa/src/utils/reflection-formatter.ts @@ -1,4 +1,9 @@ -import { Comment, ReflectionKind, ReflectionType } from "typedoc" +import { + Comment, + DeclarationReflection, + ReflectionKind, + ReflectionType, +} from "typedoc" import * as Handlebars from "handlebars" import { stripCode, stripLineBreaks } from "../utils" import { Parameter, ParameterStyle, ReflectionParameterType } from "../types" @@ -72,7 +77,7 @@ export function reflectionListFormatter( : getTypeChildren(reflection.type!, reflection.project) const itemChildren: string[] = [] let itemChildrenKind: ReflectionKind | null = null - children?.forEach((childItem) => { + children?.forEach((childItem: DeclarationReflection) => { if (!itemChildrenKind) { itemChildrenKind = childItem.kind } @@ -102,7 +107,7 @@ export function reflectionComponentFormatter( name: reflection.name, type: reflection.type ? getType(reflection.type, "object") - : getReflectionType(reflection, "object"), + : getReflectionType(reflection, "object", true), description: comments ? stripLineBreaks(Handlebars.helpers.comments(comments, true, false)) : "", @@ -124,8 +129,10 @@ export function reflectionComponentFormatter( : getTypeChildren(reflection.type!, reflection.project) children - ?.filter((childItem) => childItem.kindOf(ALLOWED_KINDS)) - .forEach((childItem) => { + ?.filter((childItem: DeclarationReflection) => + childItem.kindOf(ALLOWED_KINDS) + ) + .forEach((childItem: DeclarationReflection) => { componentItem.children?.push( reflectionComponentFormatter(childItem, level + 1, maxLevel) ) @@ -163,7 +170,7 @@ export function reflectionTableFormatter( row.push( parameter.type ? Handlebars.helpers.type.call(parameter.type, "object") - : getReflectionType(parameter, "object") + : getReflectionType(parameter, "object", true) ) if (showDefaults) { diff --git a/docs-util/packages/typedoc-plugin-markdown-medusa/src/utils/return-reflection-formatter.ts b/docs-util/packages/typedoc-plugin-markdown-medusa/src/utils/return-reflection-formatter.ts index 976a9b332b..1155fe2852 100644 --- a/docs-util/packages/typedoc-plugin-markdown-medusa/src/utils/return-reflection-formatter.ts +++ b/docs-util/packages/typedoc-plugin-markdown-medusa/src/utils/return-reflection-formatter.ts @@ -21,7 +21,7 @@ export function returnReflectionComponentFormatter( level = 1, maxLevel?: number | undefined ): Parameter[] { - const typeName = getType(reflectionType, "object", false) + const typeName = getType(reflectionType, "object", false, true) const type = getType(reflectionType, "object") const componentItem: Parameter[] = [] if (reflectionType.type === "reference") { diff --git a/docs-util/packages/typedoc-plugin-markdown-medusa/src/utils/type-utils.ts b/docs-util/packages/typedoc-plugin-markdown-medusa/src/utils/type-utils.ts index 79fc69a266..5816b4859d 100644 --- a/docs-util/packages/typedoc-plugin-markdown-medusa/src/utils/type-utils.ts +++ b/docs-util/packages/typedoc-plugin-markdown-medusa/src/utils/type-utils.ts @@ -20,33 +20,34 @@ import { } from "typedoc" import * as Handlebars from "handlebars" import { ReflectionParameterType } from "../types" -import { escapeChars } from "../utils" +import { escapeChars, getHTMLChar } from "../utils" export type Collapse = "object" | "function" | "all" | "none" export default function getType( reflectionType: SomeType, collapse: Collapse = "none", - emphasis = true + emphasis = true, + hideLink = false ): string { if (reflectionType instanceof ReferenceType) { - return getReferenceType(reflectionType, emphasis) + return getReferenceType(reflectionType, emphasis, hideLink) } if (reflectionType instanceof ArrayType && reflectionType.elementType) { - return getArrayType(reflectionType, emphasis) + return getArrayType(reflectionType, emphasis, hideLink) } if (reflectionType instanceof UnionType && reflectionType.types) { - return getUnionType(reflectionType, emphasis) + return getUnionType(reflectionType, emphasis, hideLink) } if (reflectionType instanceof IntersectionType && reflectionType.types) { - return getIntersectionType(reflectionType) + return getIntersectionType(reflectionType, emphasis, hideLink) } if (reflectionType instanceof TupleType && reflectionType.elements) { - return getTupleType(reflectionType) + return getTupleType(reflectionType, emphasis, hideLink) } if (reflectionType instanceof IntrinsicType && reflectionType.name) { @@ -54,27 +55,32 @@ export default function getType( } if (reflectionType instanceof ReflectionType) { - return getReflectionType(reflectionType.declaration, collapse) + return getReflectionType( + reflectionType.declaration, + collapse, + emphasis, + hideLink + ) } if (reflectionType instanceof DeclarationReflection) { - return getReflectionType(reflectionType, collapse) + return getReflectionType(reflectionType, collapse, emphasis, hideLink) } if (reflectionType instanceof TypeOperatorType) { - return getTypeOperatorType(reflectionType) + return getTypeOperatorType(reflectionType, emphasis, hideLink) } if (reflectionType instanceof QueryType) { - return getQueryType(reflectionType) + return getQueryType(reflectionType, emphasis, hideLink) } if (reflectionType instanceof ConditionalType) { - return getConditionalType(reflectionType) + return getConditionalType(reflectionType, emphasis, hideLink) } if (reflectionType instanceof IndexedAccessType) { - return getIndexAccessType(reflectionType) + return getIndexAccessType(reflectionType, emphasis, hideLink) } if (reflectionType instanceof UnknownType) { @@ -86,7 +92,7 @@ export default function getType( } if (reflectionType instanceof LiteralType) { - return getLiteralType(reflectionType) + return getLiteralType(reflectionType, emphasis) } return reflectionType ? escapeChars(reflectionType.toString()) : "" @@ -94,148 +100,203 @@ export default function getType( export function getReflectionType( model: ReflectionParameterType, - collapse: Collapse + collapse: Collapse, + emphasis: boolean, + hideLink = false ): string { if ("signatures" in model && model.signatures) { return collapse === "function" || collapse === "all" - ? `\`fn\`` - : getFunctionType(model.signatures) + ? `${emphasis ? "`" : ""}fn${emphasis ? "`" : ""}` + : getFunctionType(model.signatures, emphasis, hideLink) } return collapse === "object" || collapse === "all" - ? `\`object\`` - : getDeclarationType(model as DeclarationReflection) + ? `${emphasis ? "`" : ""}object${emphasis ? "`" : ""}` + : `${emphasis ? "`" : ""}${getDeclarationType( + model as DeclarationReflection, + false, + hideLink + )}${emphasis ? "`" : ""}` } -export function getDeclarationType(model: DeclarationReflection): string { +export function getDeclarationType( + model: DeclarationReflection, + emphasis: boolean, + hideLink = false +): string { if (model.indexSignature || model.children) { let indexSignature = "" const declarationIndexSignature = model.indexSignature if (declarationIndexSignature) { const key = declarationIndexSignature.parameters ? declarationIndexSignature.parameters.map( - (param) => `\`[${param.name}: ${param.type}]\`` + (param) => `[${param.name}: ${param.type}]` ) : "" const obj = declarationIndexSignature.type - ? getType(declarationIndexSignature.type) + ? getType(declarationIndexSignature.type, "none", false, hideLink) : "" indexSignature = `${key}: ${obj}; ` } const types = model.children && model.children.map((obj) => { - return `\`${obj.name}${obj.flags.isOptional ? "?" : ""}\`: ${ - obj.type ? getType(obj.type) : escapeChars(obj.toString()) + return `${obj.name}${obj.flags.isOptional ? "?" : ""}: ${ + obj.type + ? getType(obj.type, "none", false, hideLink) + : escapeChars(obj.toString()) } ${ obj.defaultValue && obj.defaultValue !== "..." ? `= ${escapeChars(`${obj.defaultValue}`)}` : "" }` }) - return `{ ${indexSignature ? indexSignature : ""}${ - types ? types.join("; ") : "" - } }${ + return `${emphasis ? "`{" : getHTMLChar("{")} ${ + indexSignature ? indexSignature : "" + }${types ? types.join("; ") : ""} ${emphasis ? "}`" : getHTMLChar("}")}${ model.defaultValue && model.defaultValue !== "..." ? `= ${escapeChars(`${model.defaultValue}`)}` : "" }` } - return "{}" + return emphasis ? "`{}`" : escapeChars("{}") } export function getFunctionType( - modelSignatures: SignatureReflection[] + modelSignatures: SignatureReflection[], + emphasis: boolean, + hideLink = false ): string { const functions = modelSignatures.map((fn) => { const typeParams = fn.typeParameters - ? `<${fn.typeParameters + ? `${emphasis ? "`<" : getHTMLChar("<")}${fn.typeParameters .map((typeParameter) => typeParameter.name) - .join(", ")}\\>` + .join(", ")}${emphasis ? ">`" : getHTMLChar(">")}` : [] const params = fn.parameters ? fn.parameters.map((param) => { - return `${param.flags.isRest ? "..." : ""}\`${param.name}${ - param.flags.isOptional ? "?" : "" - }\`: ${ - param.type ? getType(param.type) : escapeChars(param.toString()) + return `${param.flags.isRest ? "..." : ""}${emphasis ? "`" : ""}${ + param.name + }${param.flags.isOptional ? "?" : ""}${emphasis ? "`" : ""}: ${ + param.type + ? getType(param.type, "none", emphasis, hideLink) + : escapeChars(param.toString()) }` }) : [] - const returns = fn.type ? getType(fn.type) : escapeChars(fn.toString()) + const returns = fn.type + ? getType(fn.type, "none", emphasis, hideLink) + : escapeChars(fn.toString()) return typeParams + `(${params.join(", ")}) => ${returns}` }) return functions.join("") } -export function getLiteralType(model: LiteralType): string { +export function getLiteralType(model: LiteralType, emphasis: boolean): string { if (typeof model.value === "bigint") { - return `\`${model.value}n\`` + return `${emphasis ? "`" : ""}${model.value}n${emphasis ? "`" : ""}` } - return `\`\`${JSON.stringify(model.value)}\`\`` + return `${emphasis ? "`" : ""}\`${JSON.stringify(model.value)}\`${ + emphasis ? "`" : "" + }` } export function getReferenceType( model: ReferenceType, - emphasis: boolean + emphasis: boolean, + hideLink = false ): string { - const shouldShowLink = emphasis && model.name !== "Record" + const shouldShowLink = !hideLink && model.name !== "Record" + const wrappingBackticks = emphasis && !shouldShowLink if (model.reflection || (model.name && model.typeArguments)) { - const reflection: string[] = [] + const reflection: string[] = [wrappingBackticks ? "`" : ""] if (model.reflection?.url) { reflection.push( shouldShowLink - ? `[${`\`${model.reflection.name}\``}](${Handlebars.helpers.relativeURL( + ? `[${model.reflection.name}](${Handlebars.helpers.relativeURL( model.reflection.url )})` - : model.reflection.name + : emphasis + ? model.reflection.name + : escapeChars(model.reflection.name) ) } else { reflection.push( shouldShowLink ? model.externalUrl - ? `[${`\`${model.name}\``}]( ${model.externalUrl} )` - : `\`${model.name}\`` - : model.name + ? `[${model.name}]( ${model.externalUrl} )` + : model.name + : emphasis + ? model.name + : escapeChars(model.name) ) } if (model.typeArguments && model.typeArguments.length > 0) { reflection.push( - `<${model.typeArguments - .map((typeArgument) => getType(typeArgument, "none", emphasis)) - .join(", ")}\\>` + `${wrappingBackticks ? "<" : getHTMLChar("<")}${model.typeArguments + .map((typeArgument) => getType(typeArgument, "none", false, hideLink)) + .join(", ")}${wrappingBackticks ? ">" : getHTMLChar(">")}` ) } + if (wrappingBackticks) { + reflection.push("`") + } return reflection.join("") } return shouldShowLink ? model.externalUrl - ? `[${`\`${model.name}\``}]( ${model.externalUrl} )` - : `\`${model.name}\`` + ? `[${emphasis ? `\`${model.name}\`` : escapeChars(model.name)}]( ${ + model.externalUrl + } )` + : emphasis + ? `\`${model.name}\`` + : escapeChars(model.name) + : emphasis + ? `\`${model.name}\`` : escapeChars(model.name) } -export function getArrayType(model: ArrayType, emphasis: boolean): string { - const arrayType = getType(model.elementType, "none", emphasis) +export function getArrayType( + model: ArrayType, + emphasis: boolean, + hideLink = false +): string { + const arrayType = getType(model.elementType, "none", emphasis, hideLink) return model.elementType.type === "union" ? `(${arrayType})[]` : `${arrayType}[]` } -export function getUnionType(model: UnionType, emphasis: boolean): string { +export function getUnionType( + model: UnionType, + emphasis: boolean, + hideLink = false +): string { return model.types - .map((unionType) => getType(unionType, "none", emphasis)) + .map((unionType) => getType(unionType, "none", emphasis, hideLink)) .join(` \\| `) } -export function getIntersectionType(model: IntersectionType): string { +export function getIntersectionType( + model: IntersectionType, + emphasis: boolean, + hideLink = false +): string { return model.types - .map((intersectionType) => getType(intersectionType)) + .map((intersectionType) => + getType(intersectionType, "none", emphasis, hideLink) + ) .join(" & ") } -export function getTupleType(model: TupleType): string { - return `[${model.elements.map((element) => getType(element)).join(", ")}]` +export function getTupleType( + model: TupleType, + emphasis: boolean, + hideLink = false +): string { + return `[${model.elements + .map((element) => getType(element, "none", emphasis, hideLink)) + .join(", ")}]` } export function getIntrinsicType( @@ -245,12 +306,25 @@ export function getIntrinsicType( return emphasis ? `\`${model.name}\`` : escapeChars(model.name) } -export function getTypeOperatorType(model: TypeOperatorType): string { - return `${model.operator} ${getType(model.target)}` +export function getTypeOperatorType( + model: TypeOperatorType, + emphasis: boolean, + hideLink = false +): string { + return `${model.operator} ${getType( + model.target, + "none", + emphasis, + hideLink + )}` } -export function getQueryType(model: QueryType): string { - return `typeof ${getType(model.queryType)}` +export function getQueryType( + model: QueryType, + emphasis: boolean, + hideLink = false +): string { + return `typeof ${getType(model.queryType, "none", emphasis, hideLink)}` } export function getInferredType(model: InferredType): string { @@ -261,33 +335,41 @@ export function getUnknownType(model: UnknownType): string { return escapeChars(model.name) } -export function getConditionalType(model: ConditionalType): string { +export function getConditionalType( + model: ConditionalType, + emphasis: boolean, + hideLink = false +): string { const md: string[] = [] if (model.checkType) { - md.push(getType(model.checkType)) + md.push(getType(model.checkType, "none", emphasis, hideLink)) } md.push("extends") if (model.extendsType) { - md.push(getType(model.extendsType)) + md.push(getType(model.extendsType, "none", emphasis, hideLink)) } md.push("?") if (model.trueType) { - md.push(getType(model.trueType)) + md.push(getType(model.trueType, "none", emphasis, hideLink)) } md.push(":") if (model.falseType) { - md.push(getType(model.falseType)) + md.push(getType(model.falseType, "none", emphasis, hideLink)) } return md.join(" ") } -export function getIndexAccessType(model: IndexedAccessType): string { +export function getIndexAccessType( + model: IndexedAccessType, + emphasis: boolean, + hideLink = false +): string { const md: string[] = [] if (model.objectType) { - md.push(getType(model.objectType)) + md.push(getType(model.objectType, "none", emphasis, hideLink)) } if (model.indexType) { - md.push(`[${getType(model.indexType)}]`) + md.push(`[${getType(model.indexType, "none", false, hideLink)}]`) } return md.join("") } diff --git a/packages/utils/src/feature-flags/utils/flag-router.ts b/packages/utils/src/feature-flags/utils/flag-router.ts index 64bbbdce71..734c38e182 100644 --- a/packages/utils/src/feature-flags/utils/flag-router.ts +++ b/packages/utils/src/feature-flags/utils/flag-router.ts @@ -40,8 +40,8 @@ export class FlagRouter implements FeatureFlagTypes.IFlagRouter { /** * Sets a feature flag. * Flags take two shapes: - * setFlag("myFeatureFlag", true) - * setFlag("myFeatureFlag", { nestedFlag: true }) + * `setFlag("myFeatureFlag", true)` + * `setFlag("myFeatureFlag", { nestedFlag: true })` * These shapes are used for top-level and nested flags respectively, as explained in isFeatureEnabled. * @param key - The key of the flag to set. * @param value - The value of the flag to set. diff --git a/www/apps/docs/content/admin/onboarding.md b/www/apps/docs/content/admin/onboarding.md deleted file mode 100644 index 7035f16312..0000000000 --- a/www/apps/docs/content/admin/onboarding.md +++ /dev/null @@ -1,2012 +0,0 @@ ---- -title: 'Example: How to Create Onboarding Widget' -description: 'Learn how to build the onboarding widget available in the admin dashboard the first time you install a Medusa project.' -addHowToData: true ---- - -In this guide, you’ll learn how to build the onboarding widget available in the admin dashboard the first time you install a Medusa project. - -:::note - -The onboarding widget is already implemented within the codebase of your Medusa backend. This guide is helpful if you want to understand how it was implemented or you want an example of customizing the Medusa admin and backend. - -::: - -## What you’ll be Building - -By following this tutorial, you’ll: - -- Build an onboarding flow in the admin that takes the user through creating a sample product and order. This flow has four steps and navigates the user between four pages in the admin before completing the guide. This will be implemented using [Admin Widgets](./widgets.md). -- Keep track of the current step the user has reached by creating a table in the database and an API Route that the admin widget uses to retrieve and update the current step. These customizations will be applied to the backend. - -![Onboarding Widget Demo](https://res.cloudinary.com/dza7lstvk/image/upload/v1686839259/Medusa%20Docs/Screenshots/onboarding-gif_nalqps.gif) - ---- - -## Prerequisites - -Before you follow along this tutorial, you must have a Medusa backend installed. If not, you can use the following command to get started: - -```bash -npx create-medusa-app@latest -``` - -Please refer to the [create-medusa-app documentation](../create-medusa-app) for more details on this command, including prerequisites and troubleshooting. - ---- - -## Preparation Steps - -The steps in this section are used to prepare for the custom functionalities you’ll be creating in this tutorial. - -### (Optional) TypeScript Configurations and package.json - -If you're using TypeScript in your project, it's highly recommended to setup your TypeScript configurations and package.json as mentioned in [this guide](./widgets.md#optional-typescript-preparations). - -### Install Medusa React - -[Medusa React](../medusa-react/overview) is a React library that facilitates using Medusa’s API Routes within your React application. It also provides the utility to register and use custom API Routes. - -To install Medusa React and its required dependencies, run the following command in the root directory of the Medusa backend: - -```bash npm2yarn -npm install medusa-react @tanstack/react-query -``` - -### Implement Helper Resources - -The resources in this section are used for typing, layout, and design purposes, and they’re used in other essential components in this tutorial. - -Each of the collapsible elements below hold the path to the file that you should create, and the content of that file. - -
- -src/admin/types/icon-type.ts - - -```tsx title=src/admin/types/icon-type.ts -import React from "react" - -type IconProps = { - color?: string - size?: string | number -} & React.SVGAttributes - -export default IconProps -``` - -
- -
- -src/admin/components/shared/icons/get-started.tsx - - - - -```tsx title=src/admin/components/shared/icons/get-started.tsx -import React from "react" -import IconProps from "../../../types/icon-type" - -const GetStarted: React.FC = ({ - size = "40", - color = "currentColor", - ...attributes -}) => { - return ( - - - - - - - - - - - - ) -} - -export default GetStarted - -``` - -
- -
- -src/admin/components/shared/icons/active-circle-dotted-line.tsx - - - - -```tsx title=src/admin/components/shared/icons/dollar-sign-icon.tsx -import React from "react" -import IconProps from "../../../types/icon-type" - -const ActiveCircleDottedLine: React.FC = ({ - size = "24", - color = "currentColor", - ...attributes -}) => { - return ( - - - - - - - - - - - - - - - - - - - - - - - - - ) -} - -export default ActiveCircleDottedLine -``` - -
- -
- -src/admin/components/shared/accordion.tsx - - - - -```tsx title=src/admin/components/shared/accordion.tsx -import * as AccordionPrimitive from "@radix-ui/react-accordion" -import React from "react" -import { CheckCircleSolid, CircleMiniSolid } from "@medusajs/icons" -import { Heading, Text, clx } from "@medusajs/ui" -import ActiveCircleDottedLine from "./icons/active-circle-dotted-line" - -type AccordionItemProps = AccordionPrimitive.AccordionItemProps & { - title: string; - subtitle?: string; - description?: string; - required?: boolean; - tooltip?: string; - forceMountContent?: true; - headingSize?: "small" | "medium" | "large"; - customTrigger?: React.ReactNode; - complete?: boolean; - active?: boolean; - triggerable?: boolean; -}; - -const Accordion: React.FC< - | (AccordionPrimitive.AccordionSingleProps & - React.RefAttributes) - | (AccordionPrimitive.AccordionMultipleProps & - React.RefAttributes) -> & { - Item: React.FC; -} = ({ children, ...props }) => { - return ( - {children} - ) -} - -const Item: React.FC = ({ - title, - subtitle, - description, - required, - tooltip, - children, - className, - complete, - headingSize = "large", - customTrigger = undefined, - forceMountContent = undefined, - active, - triggerable, - ...props -}) => { - return ( - - -
-
-
-
- {complete ? ( - - ) : ( - <> - {active && ( - - )} - {!active && ( - - )} - - )} -
- - {title} - -
- - {customTrigger || } - -
- {subtitle && ( - - {subtitle} - - )} -
-
- -
- {description && {description}} -
{children}
-
-
-
- ) -} - -Accordion.Item = Item - -const MorphingTrigger = () => { - return ( -
-
- - -
-
- ) -} - -export default Accordion -``` - -
- -
- -src/admin/components/shared/card.tsx - - - - -```tsx title=src/admin/components/shared/card.tsx -import { Text, clx } from "@medusajs/ui" - -type CardProps = { - icon?: React.ReactNode - children?: React.ReactNode - className?: string -} - -const Card = ({ - icon, - children, - className, -}: CardProps) => { - return ( -
- {icon} - {children} -
- ) -} - -export default Card -``` - -
- ---- - -## Step 1: Customize Medusa Backend - -:::note - -If you’re not interested in learning about backend customizations, you can skip to [step 2](#step-2-create-onboarding-widget). - -::: - -In this step, you’ll customize the Medusa backend to: - -1. Add a new table in the database that stores the current onboarding step. This requires creating a new entity, repository, and migration. -2. Add new API Routes that allow retrieving and updating the current onboarding step. This also requires creating a new service. - -### Create Entity - -An [entity](../development/entities/overview.mdx) represents a table in the database. It’s based on Typeorm, so it requires creating a repository and a migration to be used in the backend. - -To create the entity, create the file `src/models/onboarding.ts` with the following content: - -```ts title=src/models/onboarding.ts -import { BaseEntity } from "@medusajs/medusa" -import { Column, Entity } from "typeorm" - -@Entity() -export class OnboardingState extends BaseEntity { - @Column() - current_step: string - - @Column() - is_complete: boolean - - @Column() - product_id: string -} -``` - -Then, create the file `src/repositories/onboarding.ts` that holds the repository of the entity with the following content: - -```ts title=src/repositories/onboarding.ts -import { - dataSource, -} from "@medusajs/medusa/dist/loaders/database" -import { OnboardingState } from "../models/onboarding" - -const OnboardingRepository = dataSource.getRepository( - OnboardingState -) - -export default OnboardingRepository -``` - -You can learn more about entities and repositories in [this documentation](../development/entities/overview.mdx). - -### Create Migration - -A [migration](../development/entities/migrations/overview.mdx) is used to reflect database changes in your database schema. - -To create a migration, run the following command in the root of your Medusa backend: - -```bash -npx typeorm migration:create src/migrations/CreateOnboarding -``` - -This will create a file in the `src/migrations` directory with the name formatted as `-CreateOnboarding.ts`. - -In that file, import the `generateEntityId` utility method at the top of the file: - -```ts -import { generateEntityId } from "@medusajs/utils" -``` - -Then, replace the `up` and `down` methods in the migration class with the following content: - - - -```ts -export class CreateOnboarding1685715079776 implements MigrationInterface { - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TABLE "onboarding_state" ("id" character varying NOT NULL, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "current_step" character varying NULL, "is_complete" boolean, "product_id" character varying NULL)` - ) - - await queryRunner.query( - `INSERT INTO "onboarding_state" ("id", "current_step", "is_complete") VALUES ('${generateEntityId( - "", - "onboarding" - )}' , NULL, false)` - ) - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP TABLE "onboarding_state"`) - } -} -``` - -:::warning - -Don’t copy the name of the class in the code snippet above. Keep the name you have in the file. - -::: - -Finally, to reflect the migration in the database, run the `build` and `migration` commands: - -```bash npm2yarn -npm run build -npx medusa migrations run -``` - -You can learn more about migrations in [this guide](../development/entities/migrations/overview.mdx). - -### Create Service - -A [service](../development/services/overview.mdx) is a class that holds helper methods related to an entity. For example, methods to create or retrieve a record of that entity. Services are used by other resources, such as API Routes, to perform functionalities related to an entity. - -So, before you add the API Routes that allow retrieving and updating the onboarding state, you need to add the service that implements these helper functionalities. - -Start by creating the file `src/types/onboarding.ts` with the following content: - - - -```ts title=src/types/onboarding.ts -import { OnboardingState } from "../models/onboarding" - -export type UpdateOnboardingStateInput = { - current_step?: string; - is_complete?: boolean; - product_id?: string; -}; - -export interface AdminOnboardingUpdateStateReq {} - -export type OnboardingStateRes = { - status: OnboardingState; -}; -``` - -This file holds the necessary types that will be used within the service you’ll create, and later in your onboarding flow widget. - -Then, create the file `src/services/onboarding.ts` with the following content: - - - -```ts title=src/services/onboarding.ts -import { TransactionBaseService } from "@medusajs/medusa" -import OnboardingRepository from "../repositories/onboarding" -import { OnboardingState } from "../models/onboarding" -import { EntityManager, IsNull, Not } from "typeorm" -import { UpdateOnboardingStateInput } from "../types/onboarding" - -type InjectedDependencies = { - manager: EntityManager; - onboardingRepository: typeof OnboardingRepository; -}; - -class OnboardingService extends TransactionBaseService { - protected onboardingRepository_: typeof OnboardingRepository - - constructor({ onboardingRepository }: InjectedDependencies) { - super(arguments[0]) - - this.onboardingRepository_ = onboardingRepository - } - - async retrieve(): Promise { - const onboardingRepo = this.activeManager_.withRepository( - this.onboardingRepository_ - ) - - const status = await onboardingRepo.findOne({ - where: { id: Not(IsNull()) }, - }) - - return status - } - - async update( - data: UpdateOnboardingStateInput - ): Promise { - return await this.atomicPhase_( - async (transactionManager: EntityManager) => { - const onboardingRepository = - transactionManager.withRepository( - this.onboardingRepository_ - ) - - const status = await this.retrieve() - - for (const [key, value] of Object.entries(data)) { - status[key] = value - } - - return await onboardingRepository.save(status) - } - ) - } -} - -export default OnboardingService -``` - -This service class implements two methods `retrieve` to retrieve the current onboarding state, and `update` to update the current onboarding state. - -You can learn more about services in [this documentation](../development/services/overview.mdx). - -### Create API Routes - -The last part of this step is to create the [API Routes](../development/api-routes/overview) that you’ll consume in the admin widget. There will be two API Routes: Get Onboarding State and Update Onboarding State. - -To add these API Routes, create the file `src/api/admin/onboarding/route.ts` with the following content: - -```ts title=src/api/admin/onboarding/route.ts -import type { - MedusaRequest, - MedusaResponse, -} from "@medusajs/medusa" -import { EntityManager } from "typeorm" - -import OnboardingService from "../../../services/onboarding" - -export async function GET( - req: MedusaRequest, - res: MedusaResponse -) { - const onboardingService: OnboardingService = - req.scope.resolve("onboardingService") - - const status = await onboardingService.retrieve() - - res.status(200).json({ status }) -} - -export async function POST( - req: MedusaRequest, - res: MedusaResponse -) { - const onboardingService: OnboardingService = - req.scope.resolve("onboardingService") - const manager: EntityManager = req.scope.resolve("manager") - - const status = await manager.transaction( - async (transactionManager) => { - return await onboardingService - .withTransaction(transactionManager) - .update(req.body) - } - ) - - res.status(200).json({ status }) -} -``` - -Notice how these API Routes use the `OnboardingService`'s `retrieve` and `update` methods to retrieve and update the current onboarding state. They resolve the `OnboardingService` using the [Dependency Container](../development/fundamentals/dependency-injection.md). - -You can learn more about API Routes in [this documentation](../development/api-routes/overview.mdx). - ---- - -## Step 2: Create Onboarding Widget - -In this step, you’ll create the onboarding widget with a general implementation. Some implementation details will be added later in the tutorial. - -Create the file `src/admin/widgets/onboarding-flow/onboarding-flow.tsx` with the following content: - - - - -```tsx title=src/admin/widgets/onboarding-flow/onboarding-flow.tsx -import { OrderDetailsWidgetProps, ProductDetailsWidgetProps, WidgetConfig, WidgetProps } from "@medusajs/admin" -import { useAdminCustomPost, useAdminCustomQuery, useMedusa } from "medusa-react" -import React, { useEffect, useState, useMemo, useCallback } from "react" -import { useNavigate, useSearchParams, useLocation } from "react-router-dom" -import { OnboardingState } from "../../../models/onboarding" -import { - AdminOnboardingUpdateStateReq, - OnboardingStateRes, - UpdateOnboardingStateInput, -} from "../../../types/onboarding" -import OrderDetailDefault from "../../components/onboarding-flow/default/orders/order-detail" -import OrdersListDefault from "../../components/onboarding-flow/default/orders/orders-list" -import ProductDetailDefault from "../../components/onboarding-flow/default/products/product-detail" -import ProductsListDefault from "../../components/onboarding-flow/default/products/products-list" -import { Button, Container, Heading, Text, clx } from "@medusajs/ui" -import Accordion from "../../components/shared/accordion" -import GetStarted from "../../components/shared/icons/get-started" -import { Order, Product } from "@medusajs/medusa" -import ProductsListNextjs from "../../components/onboarding-flow/nextjs/products/products-list" -import ProductDetailNextjs from "../../components/onboarding-flow/nextjs/products/product-detail" -import OrdersListNextjs from "../../components/onboarding-flow/nextjs/orders/orders-list" -import OrderDetailNextjs from "../../components/onboarding-flow/nextjs/orders/order-detail" - -type STEP_ID = - | "create_product" - | "preview_product" - | "create_order" - | "setup_finished" - | "create_product_nextjs" - | "preview_product_nextjs" - | "create_order_nextjs" - | "setup_finished_nextjs" - -type OnboardingWidgetProps = WidgetProps | ProductDetailsWidgetProps | OrderDetailsWidgetProps - -export type StepContentProps = OnboardingWidgetProps & { - onNext?: Function; - isComplete?: boolean; - data?: OnboardingState; -}; - -type Step = { - id: STEP_ID; - title: string; - component: React.FC; - onNext?: Function; -}; - -const QUERY_KEY = ["onboarding_state"] - -const OnboardingFlow = (props: OnboardingWidgetProps) => { - // create custom hooks for custom API Routes - const { data, isLoading } = useAdminCustomQuery< - undefined, - OnboardingStateRes - >("/onboarding", QUERY_KEY) - const { mutate } = useAdminCustomPost< - AdminOnboardingUpdateStateReq, - OnboardingStateRes - >("/onboarding", QUERY_KEY) - - const navigate = useNavigate() - const location = useLocation() - // will be used if onboarding step - // is passed as a path parameter - const { client } = useMedusa() - - // get current step from custom API Route - const currentStep: STEP_ID | undefined = useMemo(() => { - return data?.status - ?.current_step as STEP_ID - }, [data]) - - // initialize some state - const [openStep, setOpenStep] = useState(currentStep) - const [completed, setCompleted] = useState(false) - - // this method is used to move from one step to the next - const setStepComplete = ({ - step_id, - extraData, - onComplete, - }: { - step_id: STEP_ID; - extraData?: UpdateOnboardingStateInput; - onComplete?: () => void; - }) => { - const next = steps[findStepIndex(step_id) + 1] - mutate({ current_step: next.id, ...extraData }, { - onSuccess: onComplete, - }) - } - - // this is useful if you want to change the current step - // using a path parameter. It can only be changed if the passed - // step in the path parameter is the next step. - const [ searchParams ] = useSearchParams() - - // the steps are set based on the - // onboarding type - const steps: Step[] = useMemo(() => { - { - switch(process.env.MEDUSA_ADMIN_ONBOARDING_TYPE) { - case "nextjs": - return [ - { - id: "create_product_nextjs", - title: "Create Products", - component: ProductsListNextjs, - onNext: (product: Product) => { - setStepComplete({ - step_id: "create_product_nextjs", - extraData: { product_id: product.id }, - onComplete: () => { - if (!location.pathname.startsWith(`/a/products/${product.id}`)) { - navigate(`/a/products/${product.id}`) - } - }, - }) - }, - }, - { - id: "preview_product_nextjs", - title: "Preview Product in your Next.js Storefront", - component: ProductDetailNextjs, - onNext: () => { - setStepComplete({ - step_id: "preview_product_nextjs", - onComplete: () => navigate(`/a/orders`), - }) - }, - }, - { - id: "create_order_nextjs", - title: "Create an Order using your Next.js Storefront", - component: OrdersListNextjs, - onNext: (order: Order) => { - setStepComplete({ - step_id: "create_order_nextjs", - onComplete: () => { - if (!location.pathname.startsWith(`/a/orders/${order.id}`)) { - navigate(`/a/orders/${order.id}`) - } - }, - }) - }, - }, - { - id: "setup_finished_nextjs", - title: "Setup Finished: Continue Building your Ecommerce Store", - component: OrderDetailNextjs, - }, - ] - default: - return [ - { - id: "create_product", - title: "Create Product", - component: ProductsListDefault, - onNext: (product: Product) => { - setStepComplete({ - step_id: "create_product", - extraData: { product_id: product.id }, - onComplete: () => { - if (!location.pathname.startsWith(`/a/products/${product.id}`)) { - navigate(`/a/products/${product.id}`) - } - }, - }) - }, - }, - { - id: "preview_product", - title: "Preview Product", - component: ProductDetailDefault, - onNext: () => { - setStepComplete({ - step_id: "preview_product", - onComplete: () => navigate(`/a/orders`), - }) - }, - }, - { - id: "create_order", - title: "Create an Order", - component: OrdersListDefault, - onNext: (order: Order) => { - setStepComplete({ - step_id: "create_order", - onComplete: () => { - if (!location.pathname.startsWith(`/a/orders/${order.id}`)) { - navigate(`/a/orders/${order.id}`) - } - }, - }) - }, - }, - { - id: "setup_finished", - title: "Setup Finished: Start developing with Medusa", - component: OrderDetailDefault, - }, - ] - } - } - }, [location.pathname]) - - // used to retrieve the index of a step by its ID - const findStepIndex = useCallback((step_id: STEP_ID) => { - return steps.findIndex((step) => step.id === step_id) - }, [steps]) - - // used to check if a step is completed - const isStepComplete = useCallback((step_id: STEP_ID) => { - return findStepIndex(currentStep) > findStepIndex(step_id) - }, [findStepIndex, currentStep]) - - // this is used to retrieve the data necessary - // to move to the next onboarding step - const getOnboardingParamStepData = useCallback(async (onboardingStep: string, data?: { - orderId?: string, - productId?: string, - }) => { - switch (onboardingStep) { - case "setup_finished_nextjs": - case "setup_finished": - if (!data?.orderId && "order" in props) { - return props.order - } - const orderId = data?.orderId || searchParams.get("order_id") - if (orderId) { - return (await client.admin.orders.retrieve(orderId)).order - } - - throw new Error ("Required `order_id` parameter was not passed as a parameter") - case "preview_product_nextjs": - case "preview_product": - if (!data?.productId && "product" in props) { - return props.product - } - const productId = data?.productId || searchParams.get("product_id") - if (productId) { - return (await client.admin.products.retrieve(productId)).product - } - - throw new Error ("Required `product_id` parameter was not passed as a parameter") - default: - return undefined - } - }, [searchParams, props]) - - const isProductCreateStep = useMemo(() => { - return currentStep === "create_product" || - currentStep === "create_product_nextjs" - }, [currentStep]) - - const isOrderCreateStep = useMemo(() => { - return currentStep === "create_order" || - currentStep === "create_order_nextjs" - }, [currentStep]) - - // used to change the open step when the current - // step is retrieved from custom API Routes - useEffect(() => { - setOpenStep(currentStep) - - if (findStepIndex(currentStep) === steps.length - 1) {setCompleted(true)} - }, [currentStep, findStepIndex]) - - // used to check if the user created a product and has entered its details page - // the step is changed to the next one - useEffect(() => { - if (location.pathname.startsWith("/a/products/prod_") && isProductCreateStep && "product" in props) { - // change to the preview product step - const currentStepIndex = findStepIndex(currentStep) - steps[currentStepIndex].onNext?.(props.product) - } - }, [location.pathname, isProductCreateStep]) - - // used to check if the user created an order and has entered its details page - // the step is changed to the next one. - useEffect(() => { - if (location.pathname.startsWith("/a/orders/order_") && isOrderCreateStep && "order" in props) { - // change to the preview product step - const currentStepIndex = findStepIndex(currentStep) - steps[currentStepIndex].onNext?.(props.order) - } - }, [location.pathname, isOrderCreateStep]) - - // used to check if the `onboarding_step` path - // parameter is passed and, if so, moves to that step - // only if it's the next step and its necessary data is passed - useEffect(() => { - const onboardingStep = searchParams.get("onboarding_step") as STEP_ID - const onboardingStepIndex = findStepIndex(onboardingStep) - if (onboardingStep && onboardingStepIndex !== -1 && onboardingStep !== openStep) { - // change current step to the onboarding step - const openStepIndex = findStepIndex(openStep) - - if (onboardingStepIndex !== openStepIndex + 1) { - // can only go forward one step - return - } - - // retrieve necessary data and trigger the next function - getOnboardingParamStepData(onboardingStep) - .then((data) => { - steps[openStepIndex].onNext?.(data) - }) - .catch((e) => console.error(e)) - } - }, [searchParams, openStep, getOnboardingParamStepData]) - - if ( - !isLoading && - data?.status?.is_complete && - !localStorage.getItem("override_onboarding_finish") - ) - {return null} - - // a method that will be triggered when - // the setup is started - const onStart = () => { - mutate({ current_step: steps[0].id }) - navigate(`/a/products`) - } - - // a method that will be triggered when - // the setup is completed - const onComplete = () => { - setCompleted(true) - } - - // a method that will be triggered when - // the setup is closed - const onHide = () => { - mutate({ is_complete: true }) - } - - // used to get text for get started header - const getStartedText = () => { - switch(process.env.MEDUSA_ADMIN_ONBOARDING_TYPE) { - case "nextjs": - return "Learn the basics of Medusa by creating your first order using the Next.js storefront." - default: - return "Learn the basics of Medusa by creating your first order." - } - } - - return ( - <> - - setOpenStep(value as STEP_ID)} - > -
-
- -
- {!completed ? ( - <> -
- Get started - - {getStartedText()} - -
-
- {!!currentStep ? ( - <> - {currentStep === steps[steps.length - 1].id ? ( - - ) : ( - - )} - - ) : ( - <> - - - - )} -
- - ) : ( - <> -
- - Thank you for completing the setup guide! - - - This whole experience was built using our new{" "} - widgets feature. -
You can find out more details and build your own by - following{" "} - - our guide - - . -
-
-
- -
- - )} -
- { -
- {(!completed ? steps : steps.slice(-1)).map((step) => { - const isComplete = isStepComplete(step.id) - const isCurrent = currentStep === step.id - return ( - , - })} - > -
- -
-
- ) - })} -
- } -
-
- - ) -} - -export const config: WidgetConfig = { - zone: [ - "product.list.before", - "product.details.before", - "order.list.before", - "order.details.before", - ], -} - -export default OnboardingFlow -``` - -Notice that you'll see errors related to components not being defined. You'll create these components in upcoming sections. - -There are three important details to ensure that Medusa reads this file as a widget: - -1. The file is placed under the `src/admin/widget` directory. -2. The file exports a `config` object of type `WidgetConfig`, which is imported from `@medusajs/admin`. -3. The file default exports a React component, which in this case is `OnboardingFlow` - -The extension uses `react-router-dom`, which is available as a dependency of the `@medusajs/admin` package, to navigate to other pages in the dashboard. - -The `OnboardingFlow` widget also implements functionalities related to handling the steps of the onboarding flow, including navigating between them and updating the current step in the backend. - -To use the custom API Routes created in a previous step, you use the `useAdminCustomQuery` and `useAdminCustomPost` hooks from the `medusa-react` package. You can learn more about these hooks in the [Medusa React](../medusa-react/overview.mdx#custom-hooks) documentation. - -You can learn more about Admin Widgets in [this documentation](./widgets.md). - ---- - -## Step 3: Create Step Components - -In this section, you’ll create the components for each step in the onboarding flow. You’ll then update the `OnboardingFlow` widget to use these components. - -Notice that as there are two types of flows, you'll be creating the components for the default flow and for the Next.js flow. - -
- -ProductsListDefault component - - - -The `ProductsListDefault` component is used in the first step of the onboarding widget's default flow. It allows the user to create a sample product. - -Create the file `src/admin/components/onboarding-flow/default/products/products-list.tsx` with the following content: - - - -```tsx title=src/admin/components/onboarding-flow/default/products/products-list.tsx -import React, { useMemo } from "react" -import { - useAdminCreateProduct, - useAdminCreateCollection, - useMedusa, -} from "medusa-react" -import { StepContentProps } from "../../../../widgets/onboarding-flow/onboarding-flow" -import { Button, Text } from "@medusajs/ui" -import getSampleProducts from "../../../../utils/sample-products" -import prepareRegions from "../../../../utils/prepare-region" - -const ProductsListDefault = ({ onNext, isComplete }: StepContentProps) => { - const { mutateAsync: createCollection, isLoading: collectionLoading } = - useAdminCreateCollection() - const { mutateAsync: createProduct, isLoading: productLoading } = - useAdminCreateProduct() - const { client } = useMedusa() - - const isLoading = useMemo(() => - collectionLoading || productLoading, - [collectionLoading, productLoading] - ) - - const createSample = async () => { - try { - const { collection } = await createCollection({ - title: "Merch", - handle: "merch", - }) - - const regions = await prepareRegions(client) - - const sampleProducts = getSampleProducts({ - regions, - collection_id: collection.id, - }) - const { product } = await createProduct(sampleProducts[0]) - onNext(product) - } catch (e) { - console.error(e) - } - } - - return ( -
- - Create a product and set its general details such as title and - description, its price, options, variants, images, and more. You'll then - use the product to create a sample order. - - - You can create a product by clicking the "New Product" button below. - Alternatively, if you're not ready to create your own product, we can - create a sample one for you. - - {!isComplete && ( -
- -
- )} -
- ) -} - -export default ProductsListDefault -``` - -
- -
- -ProductDetailDefault component - - - -The `ProductDetailDefault` component is used in the second step of the onboarding's default flow. It shows the user a code snippet to preview the product created in the first step. - -Create the file `src/admin/components/onboarding-flow/default/products/product-detail.tsx` with the following content: - - - -```tsx title=src/admin/components/onboarding-flow/default/products/product-detail.tsx -import React, { useEffect, useMemo } from "react" -import { - useAdminPublishableApiKeys, - useAdminCreatePublishableApiKey, -} from "medusa-react" -import { StepContentProps } from "../../../../widgets/onboarding-flow/onboarding-flow" -import { Button, CodeBlock, Text } from "@medusajs/ui" - -const ProductDetailDefault = ({ onNext, isComplete, data }: StepContentProps) => { - const { publishable_api_keys: keys, isLoading, refetch } = useAdminPublishableApiKeys({ - offset: 0, - limit: 1, - }) - const createPublishableApiKey = useAdminCreatePublishableApiKey() - - const api_key = useMemo(() => keys?.[0]?.id || "", [keys]) - const backendUrl = process.env.MEDUSA_BACKEND_URL === "/" || process.env.MEDUSA_ADMIN_BACKEND_URL === "/" ? - location.origin : - process.env.MEDUSA_BACKEND_URL || process.env.MEDUSA_ADMIN_BACKEND_URL || "http://location:9000" - - useEffect(() => { - if (!isLoading && !keys?.length) { - createPublishableApiKey.mutate({ - "title": "Development", - }, { - onSuccess: () => { - refetch() - }, - }) - } - }, [isLoading, keys]) - - return ( -
-
- On this page, you can view your product's details and edit them. - - You can preview your product using Medusa's Store APIs. You can copy any - of the following code snippets to try it out. - -
-
- {!isLoading && ( - {\n // ...\n const productService = await initializeProductModule()\n const products = await productService.list({\n id: "${data?.product_id}",\n })\n\n console.log(products[0])\n}`, - }, - ]} className="my-6"> - - - - )} -
-
- - - - {!isComplete && ( - - )} -
-
- ) -} - -export default ProductDetailDefault -``` - -
- -
- -OrdersListDefault component - - - -The `OrdersListDefault` component is used in the third step of the onboarding's default flow. It allows the user to create a sample order. - -Create the file `src/admin/components/onboarding-flow/default/orders/orders-list.tsx` with the following content: - - - -```tsx title=src/admin/components/onboarding-flow/default/orders/orders-list.tsx -import React from "react" -import { - useAdminProduct, - useAdminCreateDraftOrder, - useMedusa, -} from "medusa-react" -import { StepContentProps } from "../../../../widgets/onboarding-flow/onboarding-flow" -import { Button, Text } from "@medusajs/ui" -import prepareRegions from "../../../../utils/prepare-region" -import prepareShippingOptions from "../../../../utils/prepare-shipping-options" - -const OrdersListDefault = ({ onNext, isComplete, data }: StepContentProps) => { - const { product } = useAdminProduct(data.product_id) - const { mutateAsync: createDraftOrder, isLoading } = - useAdminCreateDraftOrder() - const { client } = useMedusa() - - const createOrder = async () => { - const variant = product.variants[0] ?? null - try { - // check if there is a shipping option and a region - // and if not, create demo ones - const regions = await prepareRegions(client) - const shipping_options = await prepareShippingOptions(client, regions[0]) - - const { draft_order } = await createDraftOrder({ - email: "customer@medusajs.com", - items: [ - variant - ? { - quantity: 1, - variant_id: variant?.id, - } - : { - quantity: 1, - title: product.title, - unit_price: 50, - }, - ], - shipping_methods: [ - { - option_id: shipping_options[0].id, - }, - ], - region_id: regions[0].id, - }) - - const { order } = await client.admin.draftOrders.markPaid(draft_order.id) - - onNext(order) - } catch (e) { - console.error(e) - } - } - return ( - <> -
- - The last step is to create a sample order using the product you just created. You can then view your order’s details, process its payment, fulfillment, inventory, and more. - - - By clicking the “Create a Sample Order” button, we’ll generate an order using the product you created and default configurations. - -
-
- {!isComplete && ( - - )} -
- - ) -} - -export default OrdersListDefault -``` - -
- -
- -OrderDetailDefault component - - - -The `OrderDetailDefault` component is used in the fourth and final step of the onboarding's default flow. It educates the user on the next steps when developing with Medusa. - -Create the file `src/admin/components/onboarding-flow/default/orders/order-detail.tsx` with the following content: - - - -```tsx title=src/admin/components/onboarding-flow/default/orders/order-detail.tsx -import React from "react" -import { - ComputerDesktopSolid, - CurrencyDollarSolid, - ToolsSolid, -} from "@medusajs/icons" -import { IconBadge, Heading, Text } from "@medusajs/ui" - -const OrderDetailDefault = () => { - return ( - <> - - You finished the setup guide 🎉 You now have your first order. Feel free - to play around with the order management functionalities, such as - capturing payment, creating fulfillments, and more. - - - Start developing with Medusa - - - Medusa is a completely customizable commerce solution. We've curated - some essential guides to kickstart your development with Medusa. - - -
- You can find more useful guides in{" "} - - our documentation - - . If you like Medusa, please{" "} - - star us on GitHub - - . -
- - ) -} - -export default OrderDetailDefault - -``` -
- -
- -ProductsListNextjs component - - - -The `ProductsListNextjs` component is used in the first step of the onboarding widget's Next.js flow. It allows the user to create sample products. - -Create the file `src/admin/components/onboarding-flow/nextjs/products/products-list.tsx` with the following content: - - - -```tsx title=src/admin/components/onboarding-flow/nextjs/products/products-list.tsx -import React from "react" -import { - useAdminCreateProduct, - useAdminCreateCollection, - useMedusa, -} from "medusa-react" -import { StepContentProps } from "../../../../widgets/onboarding-flow/onboarding-flow" -import { Button, Text } from "@medusajs/ui" -import { AdminPostProductsReq, Product } from "@medusajs/medusa" -import getSampleProducts from "../../../../utils/sample-products" -import prepareRegions from "../../../../utils/prepare-region" - -const ProductsListNextjs = ({ onNext, isComplete }: StepContentProps) => { - const { mutateAsync: createCollection, isLoading: collectionLoading } = - useAdminCreateCollection() - const { mutateAsync: createProduct, isLoading: productLoading } = - useAdminCreateProduct() - const { client } = useMedusa() - - const isLoading = collectionLoading || productLoading - - const createSample = async () => { - try { - const { collection } = await createCollection({ - title: "Merch", - handle: "merch", - }) - - const regions = await prepareRegions(client) - - const tryCreateProduct = async (sampleProduct: AdminPostProductsReq): Promise => { - try { - return (await createProduct(sampleProduct)).product - } catch { - // ignore if product already exists - return null - } - } - - let product: Product - const sampleProducts = getSampleProducts({ - regions, - collection_id: collection.id, - }) - await Promise.all( - sampleProducts.map(async (sampleProduct, index) => { - const createdProduct = await tryCreateProduct(sampleProduct) - if (index === 0 && createProduct) { - product = createdProduct - } - }) - ) - onNext(product) - } catch (e) { - console.error(e) - } - } - - return ( -
- - Products is Medusa represent the products you sell. You can set their general details including a - title and description. Each product has options and variants, and you can set a price for each variant. - - - Click the button below to create sample products. - - {!isComplete && ( -
- -
- )} -
- ) -} - -export default ProductsListNextjs -``` - -
- -
- -ProductDetailNextjs component - - - -The `ProductDetailNextjs` component is used in the second step of the onboarding's Next.js flow. It shows the user a button to preview the product created in the first step using the Next.js starter. - -Create the file `src/admin/components/onboarding-flow/nextjs/products/product-detail.tsx` with the following content: - - - -```tsx title=src/admin/components/onboarding-flow/nextjs/products/product-detail.tsx -import { useAdminProduct } from "medusa-react" -import { StepContentProps } from "../../../../widgets/onboarding-flow/onboarding-flow" -import { Button, Text } from "@medusajs/ui" - -const ProductDetailNextjs = ({ onNext, isComplete, data }: StepContentProps) => { - const { product, isLoading: productIsLoading } = useAdminProduct(data?.product_id) - return ( -
-
- - We have now created a few sample products in your Medusa store. You can scroll down to see what the Product Detail view looks like in the Admin dashboard. - This is also the view you use to edit existing products. - - - To view the products in your store, you can visit the Next.js Storefront that was installed with create-medusa-app. - - - The Next.js Storefront Starter is a template that helps you start building an ecommerce store with Medusa. - You control the code for the storefront and you can customize it further to fit your specific needs. - - - Click the button below to view the products in your Next.js Storefront. - - - Having trouble? Click{" "} - - here - . - -
-
- - - - {!isComplete && ( - - )} -
-
- ) -} - -export default ProductDetailNextjs -``` - -
- -
- -OrdersListNextjs component - - - -The `OrdersListNextjs` component is used in the third step of the onboarding's Next.js flow. It links the user to the checkout flow in the Next.js storefront so that they can create an order. - -Create the file `src/admin/components/onboarding-flow/nextjs/orders/orders-list.tsx` with the following content: - - - -```tsx title=src/admin/components/onboarding-flow/nextjs/orders/orders-list.tsx -import React from "react" -import { - useAdminProduct, - useCreateCart, - useMedusa, -} from "medusa-react" -import { StepContentProps } from "../../../../widgets/onboarding-flow/onboarding-flow" -import { Button, Text } from "@medusajs/ui" -import prepareRegions from "../../../../utils/prepare-region" -import prepareShippingOptions from "../../../../utils/prepare-shipping-options" - -const OrdersListNextjs = ({ isComplete, data }: StepContentProps) => { - const { product } = useAdminProduct(data.product_id) - const { mutateAsync: createCart, isLoading: cartIsLoading } = useCreateCart() - const { client } = useMedusa() - - const prepareNextjsCheckout = async () => { - const variant = product.variants[0] ?? null - try { - const regions = await prepareRegions(client) - await prepareShippingOptions(client, regions[0]) - const { cart } = await createCart({ - region_id: regions[0]?.id, - items: [ - { - variant_id: variant?.id, - quantity: 1, - }, - ], - }) - - window.open(`http://localhost:8000/checkout?cart_id=${cart?.id}&onboarding=true`, "_blank") - } catch (e) { - console.error(e) - } - } - - return ( - <> -
- - The last step is to create a sample order using one of your products. You can then view your order’s details, process its payment, fulfillment, inventory, and more. - - - You can use the button below to experience hand-first the checkout flow in the Next.js storefront. After placing the order in the storefront, you’ll be directed back here to view the order’s details. - -
-
- {!isComplete && ( - <> - - - )} -
- - ) -} - -export default OrdersListNextjs -``` - -
- -
- -OrderDetailNextjs component - - - -The `OrderDetailNextjs` component is used in the fourth and final step of the onboarding's default flow. It educates the user on the next steps when developing with Medusa. - -Create the file `src/admin/components/onboarding-flow/nextjs/orders/order-detail.tsx` with the following content: - - - -```tsx title=src/admin/components/onboarding-flow/nextjs/orders/order-detail.tsx -import React from "react" -import { CurrencyDollarSolid, NextJs, SquaresPlusSolid } from "@medusajs/icons" -import { IconBadge, Heading, Text } from "@medusajs/ui" - -const OrderDetailNextjs = () => { - const queryParams = `?ref=onboarding&type=${ - process.env.MEDUSA_ADMIN_ONBOARDING_TYPE || "nextjs" - }` - return ( - <> - - You finished the setup guide 🎉. You have now a complete ecommerce store - with a backend, admin, and a Next.js storefront. Feel free to play - around with each of these components to experience all commerce features - that Medusa provides. - - - Continue Building your Ecommerce Store - - - Your ecommerce store provides all basic ecommerce features you need to - start selling. You can add more functionalities, add plugins for - third-party integrations, and customize the storefront’s look and feel - to support your use case. - - -
- You can find more useful guides in{" "} - - our documentation - - . If you like Medusa, please{" "} - - star us on GitHub - - . -
- - ) -} - -export default OrderDetailNextjs -``` -
- ---- - -## Step 4: Test it Out - -You’ve now implemented everything necessary for the onboarding flow! You can test it out by building the changes and running the `develop` command: - -```bash npm2yarn -npm run build -npx medusa develop -``` - -If you open the admin at `localhost:7001` and log in, you’ll see the onboarding widget in the Products listing page. You can try using it and see your implementation in action! - ---- - -## Next Steps: Continue Development - -- [Learn more about Admin Widgets](./widgets.md) -- [Learn how you can start custom development in your backend](../recipes/index.mdx) diff --git a/www/apps/docs/content/admin/onboarding.mdx b/www/apps/docs/content/admin/onboarding.mdx new file mode 100644 index 0000000000..c2b361c0a3 --- /dev/null +++ b/www/apps/docs/content/admin/onboarding.mdx @@ -0,0 +1,1981 @@ +--- +title: 'Example: How to Create Onboarding Widget' +description: 'Learn how to build the onboarding widget available in the admin dashboard the first time you install a Medusa project.' +addHowToData: true +--- + +In this guide, you’ll learn how to build the onboarding widget available in the admin dashboard the first time you install a Medusa project. + +:::note + +The onboarding widget is already implemented within the codebase of your Medusa backend. This guide is helpful if you want to understand how it was implemented or you want an example of customizing the Medusa admin and backend. + +::: + +## What you’ll be Building + +By following this tutorial, you’ll: + +- Build an onboarding flow in the admin that takes the user through creating a sample product and order. This flow has four steps and navigates the user between four pages in the admin before completing the guide. This will be implemented using [Admin Widgets](./widgets.md). +- Keep track of the current step the user has reached by creating a table in the database and an API Route that the admin widget uses to retrieve and update the current step. These customizations will be applied to the backend. + +![Onboarding Widget Demo](https://res.cloudinary.com/dza7lstvk/image/upload/v1686839259/Medusa%20Docs/Screenshots/onboarding-gif_nalqps.gif) + +--- + +## Prerequisites + +Before you follow along this tutorial, you must have a Medusa backend installed. If not, you can use the following command to get started: + +```bash +npx create-medusa-app@latest +``` + +Please refer to the [create-medusa-app documentation](../create-medusa-app) for more details on this command, including prerequisites and troubleshooting. + +--- + +## Preparation Steps + +The steps in this section are used to prepare for the custom functionalities you’ll be creating in this tutorial. + +### (Optional) TypeScript Configurations and package.json + +If you're using TypeScript in your project, it's highly recommended to setup your TypeScript configurations and package.json as mentioned in [this guide](./widgets.md#optional-typescript-preparations). + +### Install Medusa React + +[Medusa React](../medusa-react/overview) is a React library that facilitates using Medusa’s API Routes within your React application. It also provides the utility to register and use custom API Routes. + +To install Medusa React and its required dependencies, run the following command in the root directory of the Medusa backend: + +```bash npm2yarn +npm install medusa-react @tanstack/react-query +``` + +### Implement Helper Resources + +The resources in this section are used for typing, layout, and design purposes, and they’re used in other essential components in this tutorial. + +Each of the collapsible elements below hold the path to the file that you should create, and the content of that file. + +
+ src/admin/types/icon-type.ts + + ```tsx title=src/admin/types/icon-type.ts + import React from "react" + + type IconProps = { + color?: string + size?: string | number + } & React.SVGAttributes + + export default IconProps + ``` + +
+ +
+ src/admin/components/shared/icons/get-started.tsx + + + + ```tsx title=src/admin/components/shared/icons/get-started.tsx + import React from "react" + import IconProps from "../../../types/icon-type" + + const GetStarted: React.FC = ({ + size = "40", + color = "currentColor", + ...attributes + }) => { + return ( + + + + + + + + + + + + ) + } + + export default GetStarted + + ``` + +
+ +
+ src/admin/components/shared/icons/active-circle-dotted-line.tsx + + + + ```tsx title=src/admin/components/shared/icons/dollar-sign-icon.tsx + import React from "react" + import IconProps from "../../../types/icon-type" + + const ActiveCircleDottedLine: React.FC = ({ + size = "24", + color = "currentColor", + ...attributes + }) => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + ) + } + + export default ActiveCircleDottedLine + ``` + +
+ +
+ src/admin/components/shared/accordion.tsx + + + + ```tsx title=src/admin/components/shared/accordion.tsx + import * as AccordionPrimitive from "@radix-ui/react-accordion" + import React from "react" + import { CheckCircleSolid, CircleMiniSolid } from "@medusajs/icons" + import { Heading, Text, clx } from "@medusajs/ui" + import ActiveCircleDottedLine from "./icons/active-circle-dotted-line" + + type AccordionItemProps = AccordionPrimitive.AccordionItemProps & { + title: string; + subtitle?: string; + description?: string; + required?: boolean; + tooltip?: string; + forceMountContent?: true; + headingSize?: "small" | "medium" | "large"; + customTrigger?: React.ReactNode; + complete?: boolean; + active?: boolean; + triggerable?: boolean; + }; + + const Accordion: React.FC< + | (AccordionPrimitive.AccordionSingleProps & + React.RefAttributes) + | (AccordionPrimitive.AccordionMultipleProps & + React.RefAttributes) + > & { + Item: React.FC; + } = ({ children, ...props }) => { + return ( + {children} + ) + } + + const Item: React.FC = ({ + title, + subtitle, + description, + required, + tooltip, + children, + className, + complete, + headingSize = "large", + customTrigger = undefined, + forceMountContent = undefined, + active, + triggerable, + ...props + }) => { + return ( + + +
+
+
+
+ {complete ? ( + + ) : ( + <> + {active && ( + + )} + {!active && ( + + )} + + )} +
+ + {title} + +
+ + {customTrigger || } + +
+ {subtitle && ( + + {subtitle} + + )} +
+
+ +
+ {description && {description}} +
{children}
+
+
+
+ ) + } + + Accordion.Item = Item + + const MorphingTrigger = () => { + return ( +
+
+ + +
+
+ ) + } + + export default Accordion + ``` + +
+ +
+ src/admin/components/shared/card.tsx + + + + ```tsx title=src/admin/components/shared/card.tsx + import { Text, clx } from "@medusajs/ui" + + type CardProps = { + icon?: React.ReactNode + children?: React.ReactNode + className?: string + } + + const Card = ({ + icon, + children, + className, + }: CardProps) => { + return ( +
+ {icon} + {children} +
+ ) + } + + export default Card + ``` + +
+ +--- + +## Step 1: Customize Medusa Backend + +:::note + +If you’re not interested in learning about backend customizations, you can skip to [step 2](#step-2-create-onboarding-widget). + +::: + +In this step, you’ll customize the Medusa backend to: + +1. Add a new table in the database that stores the current onboarding step. This requires creating a new entity, repository, and migration. +2. Add new API Routes that allow retrieving and updating the current onboarding step. This also requires creating a new service. + +### Create Entity + +An [entity](../development/entities/overview.mdx) represents a table in the database. It’s based on Typeorm, so it requires creating a repository and a migration to be used in the backend. + +To create the entity, create the file `src/models/onboarding.ts` with the following content: + +```ts title=src/models/onboarding.ts +import { BaseEntity } from "@medusajs/medusa" +import { Column, Entity } from "typeorm" + +@Entity() +export class OnboardingState extends BaseEntity { + @Column() + current_step: string + + @Column() + is_complete: boolean + + @Column() + product_id: string +} +``` + +Then, create the file `src/repositories/onboarding.ts` that holds the repository of the entity with the following content: + +```ts title=src/repositories/onboarding.ts +import { + dataSource, +} from "@medusajs/medusa/dist/loaders/database" +import { OnboardingState } from "../models/onboarding" + +const OnboardingRepository = dataSource.getRepository( + OnboardingState +) + +export default OnboardingRepository +``` + +You can learn more about entities and repositories in [this documentation](../development/entities/overview.mdx). + +### Create Migration + +A [migration](../development/entities/migrations/overview.mdx) is used to reflect database changes in your database schema. + +To create a migration, run the following command in the root of your Medusa backend: + +```bash +npx typeorm migration:create src/migrations/CreateOnboarding +``` + +This will create a file in the `src/migrations` directory with the name formatted as `-CreateOnboarding.ts`. + +In that file, import the `generateEntityId` utility method at the top of the file: + +```ts +import { generateEntityId } from "@medusajs/utils" +``` + +Then, replace the `up` and `down` methods in the migration class with the following content: + + + +```ts +export class CreateOnboarding1685715079776 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "onboarding_state" ("id" character varying NOT NULL, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "current_step" character varying NULL, "is_complete" boolean, "product_id" character varying NULL)` + ) + + await queryRunner.query( + `INSERT INTO "onboarding_state" ("id", "current_step", "is_complete") VALUES ('${generateEntityId( + "", + "onboarding" + )}' , NULL, false)` + ) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP TABLE "onboarding_state"`) + } +} +``` + +:::warning + +Don’t copy the name of the class in the code snippet above. Keep the name you have in the file. + +::: + +Finally, to reflect the migration in the database, run the `build` and `migration` commands: + +```bash npm2yarn +npm run build +npx medusa migrations run +``` + +You can learn more about migrations in [this guide](../development/entities/migrations/overview.mdx). + +### Create Service + +A [service](../development/services/overview.mdx) is a class that holds helper methods related to an entity. For example, methods to create or retrieve a record of that entity. Services are used by other resources, such as API Routes, to perform functionalities related to an entity. + +So, before you add the API Routes that allow retrieving and updating the onboarding state, you need to add the service that implements these helper functionalities. + +Start by creating the file `src/types/onboarding.ts` with the following content: + + + +```ts title=src/types/onboarding.ts +import { OnboardingState } from "../models/onboarding" + +export type UpdateOnboardingStateInput = { + current_step?: string; + is_complete?: boolean; + product_id?: string; +}; + +export interface AdminOnboardingUpdateStateReq {} + +export type OnboardingStateRes = { + status: OnboardingState; +}; +``` + +This file holds the necessary types that will be used within the service you’ll create, and later in your onboarding flow widget. + +Then, create the file `src/services/onboarding.ts` with the following content: + + + +```ts title=src/services/onboarding.ts +import { TransactionBaseService } from "@medusajs/medusa" +import OnboardingRepository from "../repositories/onboarding" +import { OnboardingState } from "../models/onboarding" +import { EntityManager, IsNull, Not } from "typeorm" +import { UpdateOnboardingStateInput } from "../types/onboarding" + +type InjectedDependencies = { + manager: EntityManager; + onboardingRepository: typeof OnboardingRepository; +}; + +class OnboardingService extends TransactionBaseService { + protected onboardingRepository_: typeof OnboardingRepository + + constructor({ onboardingRepository }: InjectedDependencies) { + super(arguments[0]) + + this.onboardingRepository_ = onboardingRepository + } + + async retrieve(): Promise { + const onboardingRepo = this.activeManager_.withRepository( + this.onboardingRepository_ + ) + + const status = await onboardingRepo.findOne({ + where: { id: Not(IsNull()) }, + }) + + return status + } + + async update( + data: UpdateOnboardingStateInput + ): Promise { + return await this.atomicPhase_( + async (transactionManager: EntityManager) => { + const onboardingRepository = + transactionManager.withRepository( + this.onboardingRepository_ + ) + + const status = await this.retrieve() + + for (const [key, value] of Object.entries(data)) { + status[key] = value + } + + return await onboardingRepository.save(status) + } + ) + } +} + +export default OnboardingService +``` + +This service class implements two methods `retrieve` to retrieve the current onboarding state, and `update` to update the current onboarding state. + +You can learn more about services in [this documentation](../development/services/overview.mdx). + +### Create API Routes + +The last part of this step is to create the [API Routes](../development/api-routes/overview) that you’ll consume in the admin widget. There will be two API Routes: Get Onboarding State and Update Onboarding State. + +To add these API Routes, create the file `src/api/admin/onboarding/route.ts` with the following content: + +```ts title=src/api/admin/onboarding/route.ts +import type { + MedusaRequest, + MedusaResponse, +} from "@medusajs/medusa" +import { EntityManager } from "typeorm" + +import OnboardingService from "../../../services/onboarding" + +export async function GET( + req: MedusaRequest, + res: MedusaResponse +) { + const onboardingService: OnboardingService = + req.scope.resolve("onboardingService") + + const status = await onboardingService.retrieve() + + res.status(200).json({ status }) +} + +export async function POST( + req: MedusaRequest, + res: MedusaResponse +) { + const onboardingService: OnboardingService = + req.scope.resolve("onboardingService") + const manager: EntityManager = req.scope.resolve("manager") + + const status = await manager.transaction( + async (transactionManager) => { + return await onboardingService + .withTransaction(transactionManager) + .update(req.body) + } + ) + + res.status(200).json({ status }) +} +``` + +Notice how these API Routes use the `OnboardingService`'s `retrieve` and `update` methods to retrieve and update the current onboarding state. They resolve the `OnboardingService` using the [Dependency Container](../development/fundamentals/dependency-injection.md). + +You can learn more about API Routes in [this documentation](../development/api-routes/overview.mdx). + +--- + +## Step 2: Create Onboarding Widget + +In this step, you’ll create the onboarding widget with a general implementation. Some implementation details will be added later in the tutorial. + +Create the file `src/admin/widgets/onboarding-flow/onboarding-flow.tsx` with the following content: + + + + + +```tsx title=src/admin/widgets/onboarding-flow/onboarding-flow.tsx +import { OrderDetailsWidgetProps, ProductDetailsWidgetProps, WidgetConfig, WidgetProps } from "@medusajs/admin" +import { useAdminCustomPost, useAdminCustomQuery, useMedusa } from "medusa-react" +import React, { useEffect, useState, useMemo, useCallback } from "react" +import { useNavigate, useSearchParams, useLocation } from "react-router-dom" +import { OnboardingState } from "../../../models/onboarding" +import { + AdminOnboardingUpdateStateReq, + OnboardingStateRes, + UpdateOnboardingStateInput, +} from "../../../types/onboarding" +import OrderDetailDefault from "../../components/onboarding-flow/default/orders/order-detail" +import OrdersListDefault from "../../components/onboarding-flow/default/orders/orders-list" +import ProductDetailDefault from "../../components/onboarding-flow/default/products/product-detail" +import ProductsListDefault from "../../components/onboarding-flow/default/products/products-list" +import { Button, Container, Heading, Text, clx } from "@medusajs/ui" +import Accordion from "../../components/shared/accordion" +import GetStarted from "../../components/shared/icons/get-started" +import { Order, Product } from "@medusajs/medusa" +import ProductsListNextjs from "../../components/onboarding-flow/nextjs/products/products-list" +import ProductDetailNextjs from "../../components/onboarding-flow/nextjs/products/product-detail" +import OrdersListNextjs from "../../components/onboarding-flow/nextjs/orders/orders-list" +import OrderDetailNextjs from "../../components/onboarding-flow/nextjs/orders/order-detail" + +type STEP_ID = + | "create_product" + | "preview_product" + | "create_order" + | "setup_finished" + | "create_product_nextjs" + | "preview_product_nextjs" + | "create_order_nextjs" + | "setup_finished_nextjs" + +type OnboardingWidgetProps = WidgetProps | ProductDetailsWidgetProps | OrderDetailsWidgetProps + +export type StepContentProps = OnboardingWidgetProps & { + onNext?: Function; + isComplete?: boolean; + data?: OnboardingState; +}; + +type Step = { + id: STEP_ID; + title: string; + component: React.FC; + onNext?: Function; +}; + +const QUERY_KEY = ["onboarding_state"] + +const OnboardingFlow = (props: OnboardingWidgetProps) => { + // create custom hooks for custom API Routes + const { data, isLoading } = useAdminCustomQuery< + undefined, + OnboardingStateRes + >("/onboarding", QUERY_KEY) + const { mutate } = useAdminCustomPost< + AdminOnboardingUpdateStateReq, + OnboardingStateRes + >("/onboarding", QUERY_KEY) + + const navigate = useNavigate() + const location = useLocation() + // will be used if onboarding step + // is passed as a path parameter + const { client } = useMedusa() + + // get current step from custom API Route + const currentStep: STEP_ID | undefined = useMemo(() => { + return data?.status + ?.current_step as STEP_ID + }, [data]) + + // initialize some state + const [openStep, setOpenStep] = useState(currentStep) + const [completed, setCompleted] = useState(false) + + // this method is used to move from one step to the next + const setStepComplete = ({ + step_id, + extraData, + onComplete, + }: { + step_id: STEP_ID; + extraData?: UpdateOnboardingStateInput; + onComplete?: () => void; + }) => { + const next = steps[findStepIndex(step_id) + 1] + mutate({ current_step: next.id, ...extraData }, { + onSuccess: onComplete, + }) + } + + // this is useful if you want to change the current step + // using a path parameter. It can only be changed if the passed + // step in the path parameter is the next step. + const [ searchParams ] = useSearchParams() + + // the steps are set based on the + // onboarding type + const steps: Step[] = useMemo(() => { + { + switch(process.env.MEDUSA_ADMIN_ONBOARDING_TYPE) { + case "nextjs": + return [ + { + id: "create_product_nextjs", + title: "Create Products", + component: ProductsListNextjs, + onNext: (product: Product) => { + setStepComplete({ + step_id: "create_product_nextjs", + extraData: { product_id: product.id }, + onComplete: () => { + if (!location.pathname.startsWith(`/a/products/${product.id}`)) { + navigate(`/a/products/${product.id}`) + } + }, + }) + }, + }, + { + id: "preview_product_nextjs", + title: "Preview Product in your Next.js Storefront", + component: ProductDetailNextjs, + onNext: () => { + setStepComplete({ + step_id: "preview_product_nextjs", + onComplete: () => navigate(`/a/orders`), + }) + }, + }, + { + id: "create_order_nextjs", + title: "Create an Order using your Next.js Storefront", + component: OrdersListNextjs, + onNext: (order: Order) => { + setStepComplete({ + step_id: "create_order_nextjs", + onComplete: () => { + if (!location.pathname.startsWith(`/a/orders/${order.id}`)) { + navigate(`/a/orders/${order.id}`) + } + }, + }) + }, + }, + { + id: "setup_finished_nextjs", + title: "Setup Finished: Continue Building your Ecommerce Store", + component: OrderDetailNextjs, + }, + ] + default: + return [ + { + id: "create_product", + title: "Create Product", + component: ProductsListDefault, + onNext: (product: Product) => { + setStepComplete({ + step_id: "create_product", + extraData: { product_id: product.id }, + onComplete: () => { + if (!location.pathname.startsWith(`/a/products/${product.id}`)) { + navigate(`/a/products/${product.id}`) + } + }, + }) + }, + }, + { + id: "preview_product", + title: "Preview Product", + component: ProductDetailDefault, + onNext: () => { + setStepComplete({ + step_id: "preview_product", + onComplete: () => navigate(`/a/orders`), + }) + }, + }, + { + id: "create_order", + title: "Create an Order", + component: OrdersListDefault, + onNext: (order: Order) => { + setStepComplete({ + step_id: "create_order", + onComplete: () => { + if (!location.pathname.startsWith(`/a/orders/${order.id}`)) { + navigate(`/a/orders/${order.id}`) + } + }, + }) + }, + }, + { + id: "setup_finished", + title: "Setup Finished: Start developing with Medusa", + component: OrderDetailDefault, + }, + ] + } + } + }, [location.pathname]) + + // used to retrieve the index of a step by its ID + const findStepIndex = useCallback((step_id: STEP_ID) => { + return steps.findIndex((step) => step.id === step_id) + }, [steps]) + + // used to check if a step is completed + const isStepComplete = useCallback((step_id: STEP_ID) => { + return findStepIndex(currentStep) > findStepIndex(step_id) + }, [findStepIndex, currentStep]) + + // this is used to retrieve the data necessary + // to move to the next onboarding step + const getOnboardingParamStepData = useCallback(async (onboardingStep: string, data?: { + orderId?: string, + productId?: string, + }) => { + switch (onboardingStep) { + case "setup_finished_nextjs": + case "setup_finished": + if (!data?.orderId && "order" in props) { + return props.order + } + const orderId = data?.orderId || searchParams.get("order_id") + if (orderId) { + return (await client.admin.orders.retrieve(orderId)).order + } + + throw new Error ("Required `order_id` parameter was not passed as a parameter") + case "preview_product_nextjs": + case "preview_product": + if (!data?.productId && "product" in props) { + return props.product + } + const productId = data?.productId || searchParams.get("product_id") + if (productId) { + return (await client.admin.products.retrieve(productId)).product + } + + throw new Error ("Required `product_id` parameter was not passed as a parameter") + default: + return undefined + } + }, [searchParams, props]) + + const isProductCreateStep = useMemo(() => { + return currentStep === "create_product" || + currentStep === "create_product_nextjs" + }, [currentStep]) + + const isOrderCreateStep = useMemo(() => { + return currentStep === "create_order" || + currentStep === "create_order_nextjs" + }, [currentStep]) + + // used to change the open step when the current + // step is retrieved from custom API Routes + useEffect(() => { + setOpenStep(currentStep) + + if (findStepIndex(currentStep) === steps.length - 1) {setCompleted(true)} + }, [currentStep, findStepIndex]) + + // used to check if the user created a product and has entered its details page + // the step is changed to the next one + useEffect(() => { + if (location.pathname.startsWith("/a/products/prod_") && isProductCreateStep && "product" in props) { + // change to the preview product step + const currentStepIndex = findStepIndex(currentStep) + steps[currentStepIndex].onNext?.(props.product) + } + }, [location.pathname, isProductCreateStep]) + + // used to check if the user created an order and has entered its details page + // the step is changed to the next one. + useEffect(() => { + if (location.pathname.startsWith("/a/orders/order_") && isOrderCreateStep && "order" in props) { + // change to the preview product step + const currentStepIndex = findStepIndex(currentStep) + steps[currentStepIndex].onNext?.(props.order) + } + }, [location.pathname, isOrderCreateStep]) + + // used to check if the `onboarding_step` path + // parameter is passed and, if so, moves to that step + // only if it's the next step and its necessary data is passed + useEffect(() => { + const onboardingStep = searchParams.get("onboarding_step") as STEP_ID + const onboardingStepIndex = findStepIndex(onboardingStep) + if (onboardingStep && onboardingStepIndex !== -1 && onboardingStep !== openStep) { + // change current step to the onboarding step + const openStepIndex = findStepIndex(openStep) + + if (onboardingStepIndex !== openStepIndex + 1) { + // can only go forward one step + return + } + + // retrieve necessary data and trigger the next function + getOnboardingParamStepData(onboardingStep) + .then((data) => { + steps[openStepIndex].onNext?.(data) + }) + .catch((e) => console.error(e)) + } + }, [searchParams, openStep, getOnboardingParamStepData]) + + if ( + !isLoading && + data?.status?.is_complete && + !localStorage.getItem("override_onboarding_finish") + ) + {return null} + + // a method that will be triggered when + // the setup is started + const onStart = () => { + mutate({ current_step: steps[0].id }) + navigate(`/a/products`) + } + + // a method that will be triggered when + // the setup is completed + const onComplete = () => { + setCompleted(true) + } + + // a method that will be triggered when + // the setup is closed + const onHide = () => { + mutate({ is_complete: true }) + } + + // used to get text for get started header + const getStartedText = () => { + switch(process.env.MEDUSA_ADMIN_ONBOARDING_TYPE) { + case "nextjs": + return "Learn the basics of Medusa by creating your first order using the Next.js storefront." + default: + return "Learn the basics of Medusa by creating your first order." + } + } + + return ( + <> + + setOpenStep(value as STEP_ID)} + > +
+
+ +
+ {!completed ? ( + <> +
+ Get started + + {getStartedText()} + +
+
+ {!!currentStep ? ( + <> + {currentStep === steps[steps.length - 1].id ? ( + + ) : ( + + )} + + ) : ( + <> + + + + )} +
+ + ) : ( + <> +
+ + Thank you for completing the setup guide! + + + This whole experience was built using our new{" "} + widgets feature. +
You can find out more details and build your own by + following{" "} + + our guide + + . +
+
+
+ +
+ + )} +
+ { +
+ {(!completed ? steps : steps.slice(-1)).map((step) => { + const isComplete = isStepComplete(step.id) + const isCurrent = currentStep === step.id + return ( + , + })} + > +
+ +
+
+ ) + })} +
+ } +
+
+ + ) +} + +export const config: WidgetConfig = { + zone: [ + "product.list.before", + "product.details.before", + "order.list.before", + "order.details.before", + ], +} + +export default OnboardingFlow +``` + +Notice that you'll see errors related to components not being defined. You'll create these components in upcoming sections. + +There are three important details to ensure that Medusa reads this file as a widget: + +1. The file is placed under the `src/admin/widget` directory. +2. The file exports a `config` object of type `WidgetConfig`, which is imported from `@medusajs/admin`. +3. The file default exports a React component, which in this case is `OnboardingFlow` + +The extension uses `react-router-dom`, which is available as a dependency of the `@medusajs/admin` package, to navigate to other pages in the dashboard. + +The `OnboardingFlow` widget also implements functionalities related to handling the steps of the onboarding flow, including navigating between them and updating the current step in the backend. + +To use the custom API Routes created in a previous step, you use the `useAdminCustomQuery` and `useAdminCustomPost` hooks from the `medusa-react` package. You can learn more about these hooks in the [Medusa React](../medusa-react/overview.mdx#custom-hooks) documentation. + +You can learn more about Admin Widgets in [this documentation](./widgets.md). + +--- + +## Step 3: Create Step Components + +In this section, you’ll create the components for each step in the onboarding flow. You’ll then update the `OnboardingFlow` widget to use these components. + +Notice that as there are two types of flows, you'll be creating the components for the default flow and for the Next.js flow. + +
+ ProductsListDefault component + + The `ProductsListDefault` component is used in the first step of the onboarding widget's default flow. It allows the user to create a sample product. + + Create the file `src/admin/components/onboarding-flow/default/products/products-list.tsx` with the following content: + + + + ```tsx title=src/admin/components/onboarding-flow/default/products/products-list.tsx + import React, { useMemo } from "react" + import { + useAdminCreateProduct, + useAdminCreateCollection, + useMedusa, + } from "medusa-react" + import { StepContentProps } from "../../../../widgets/onboarding-flow/onboarding-flow" + import { Button, Text } from "@medusajs/ui" + import getSampleProducts from "../../../../utils/sample-products" + import prepareRegions from "../../../../utils/prepare-region" + + const ProductsListDefault = ({ onNext, isComplete }: StepContentProps) => { + const { mutateAsync: createCollection, isLoading: collectionLoading } = + useAdminCreateCollection() + const { mutateAsync: createProduct, isLoading: productLoading } = + useAdminCreateProduct() + const { client } = useMedusa() + + const isLoading = useMemo(() => + collectionLoading || productLoading, + [collectionLoading, productLoading] + ) + + const createSample = async () => { + try { + const { collection } = await createCollection({ + title: "Merch", + handle: "merch", + }) + + const regions = await prepareRegions(client) + + const sampleProducts = getSampleProducts({ + regions, + collection_id: collection.id, + }) + const { product } = await createProduct(sampleProducts[0]) + onNext(product) + } catch (e) { + console.error(e) + } + } + + return ( +
+ + Create a product and set its general details such as title and + description, its price, options, variants, images, and more. You'll then + use the product to create a sample order. + + + You can create a product by clicking the "New Product" button below. + Alternatively, if you're not ready to create your own product, we can + create a sample one for you. + + {!isComplete && ( +
+ +
+ )} +
+ ) + } + + export default ProductsListDefault + ``` + +
+ +
+ ProductDetailDefault component + + The `ProductDetailDefault` component is used in the second step of the onboarding's default flow. It shows the user a code snippet to preview the product created in the first step. + + Create the file `src/admin/components/onboarding-flow/default/products/product-detail.tsx` with the following content: + + + + ```tsx title=src/admin/components/onboarding-flow/default/products/product-detail.tsx + import React, { useEffect, useMemo } from "react" + import { + useAdminPublishableApiKeys, + useAdminCreatePublishableApiKey, + } from "medusa-react" + import { StepContentProps } from "../../../../widgets/onboarding-flow/onboarding-flow" + import { Button, CodeBlock, Text } from "@medusajs/ui" + + const ProductDetailDefault = ({ onNext, isComplete, data }: StepContentProps) => { + const { publishable_api_keys: keys, isLoading, refetch } = useAdminPublishableApiKeys({ + offset: 0, + limit: 1, + }) + const createPublishableApiKey = useAdminCreatePublishableApiKey() + + const api_key = useMemo(() => keys?.[0]?.id || "", [keys]) + const backendUrl = process.env.MEDUSA_BACKEND_URL === "/" || process.env.MEDUSA_ADMIN_BACKEND_URL === "/" ? + location.origin : + process.env.MEDUSA_BACKEND_URL || process.env.MEDUSA_ADMIN_BACKEND_URL || "http://location:9000" + + useEffect(() => { + if (!isLoading && !keys?.length) { + createPublishableApiKey.mutate({ + "title": "Development", + }, { + onSuccess: () => { + refetch() + }, + }) + } + }, [isLoading, keys]) + + return ( +
+
+ On this page, you can view your product's details and edit them. + + You can preview your product using Medusa's Store APIs. You can copy any + of the following code snippets to try it out. + +
+
+ {!isLoading && ( + {\n // ...\n const productService = await initializeProductModule()\n const products = await productService.list({\n id: "${data?.product_id}",\n })\n\n console.log(products[0])\n}`, + }, + ]} className="my-6"> + + + + )} +
+
+ + + + {!isComplete && ( + + )} +
+
+ ) + } + + export default ProductDetailDefault + ``` + +
+ +
+ OrdersListDefault component + + The `OrdersListDefault` component is used in the third step of the onboarding's default flow. It allows the user to create a sample order. + + Create the file `src/admin/components/onboarding-flow/default/orders/orders-list.tsx` with the following content: + + + + ```tsx title=src/admin/components/onboarding-flow/default/orders/orders-list.tsx + import React from "react" + import { + useAdminProduct, + useAdminCreateDraftOrder, + useMedusa, + } from "medusa-react" + import { StepContentProps } from "../../../../widgets/onboarding-flow/onboarding-flow" + import { Button, Text } from "@medusajs/ui" + import prepareRegions from "../../../../utils/prepare-region" + import prepareShippingOptions from "../../../../utils/prepare-shipping-options" + + const OrdersListDefault = ({ onNext, isComplete, data }: StepContentProps) => { + const { product } = useAdminProduct(data.product_id) + const { mutateAsync: createDraftOrder, isLoading } = + useAdminCreateDraftOrder() + const { client } = useMedusa() + + const createOrder = async () => { + const variant = product.variants[0] ?? null + try { + // check if there is a shipping option and a region + // and if not, create demo ones + const regions = await prepareRegions(client) + const shipping_options = await prepareShippingOptions(client, regions[0]) + + const { draft_order } = await createDraftOrder({ + email: "customer@medusajs.com", + items: [ + variant + ? { + quantity: 1, + variant_id: variant?.id, + } + : { + quantity: 1, + title: product.title, + unit_price: 50, + }, + ], + shipping_methods: [ + { + option_id: shipping_options[0].id, + }, + ], + region_id: regions[0].id, + }) + + const { order } = await client.admin.draftOrders.markPaid(draft_order.id) + + onNext(order) + } catch (e) { + console.error(e) + } + } + return ( + <> +
+ + The last step is to create a sample order using the product you just created. You can then view your order’s details, process its payment, fulfillment, inventory, and more. + + + By clicking the “Create a Sample Order” button, we’ll generate an order using the product you created and default configurations. + +
+
+ {!isComplete && ( + + )} +
+ + ) + } + + export default OrdersListDefault + ``` + +
+ +
+ OrderDetailDefault component + + The `OrderDetailDefault` component is used in the fourth and final step of the onboarding's default flow. It educates the user on the next steps when developing with Medusa. + + Create the file `src/admin/components/onboarding-flow/default/orders/order-detail.tsx` with the following content: + + + + ```tsx title=src/admin/components/onboarding-flow/default/orders/order-detail.tsx + import React from "react" + import { + ComputerDesktopSolid, + CurrencyDollarSolid, + ToolsSolid, + } from "@medusajs/icons" + import { IconBadge, Heading, Text } from "@medusajs/ui" + + const OrderDetailDefault = () => { + return ( + <> + + You finished the setup guide 🎉 You now have your first order. Feel free + to play around with the order management functionalities, such as + capturing payment, creating fulfillments, and more. + + + Start developing with Medusa + + + Medusa is a completely customizable commerce solution. We've curated + some essential guides to kickstart your development with Medusa. + + +
+ You can find more useful guides in{" "} + + our documentation + + . If you like Medusa, please{" "} + + star us on GitHub + + . +
+ + ) + } + + export default OrderDetailDefault + + ``` + +
+ +
+ ProductsListNextjs component + + The `ProductsListNextjs` component is used in the first step of the onboarding widget's Next.js flow. It allows the user to create sample products. + + Create the file `src/admin/components/onboarding-flow/nextjs/products/products-list.tsx` with the following content: + + + + ```tsx title=src/admin/components/onboarding-flow/nextjs/products/products-list.tsx + import React from "react" + import { + useAdminCreateProduct, + useAdminCreateCollection, + useMedusa, + } from "medusa-react" + import { StepContentProps } from "../../../../widgets/onboarding-flow/onboarding-flow" + import { Button, Text } from "@medusajs/ui" + import { AdminPostProductsReq, Product } from "@medusajs/medusa" + import getSampleProducts from "../../../../utils/sample-products" + import prepareRegions from "../../../../utils/prepare-region" + + const ProductsListNextjs = ({ onNext, isComplete }: StepContentProps) => { + const { mutateAsync: createCollection, isLoading: collectionLoading } = + useAdminCreateCollection() + const { mutateAsync: createProduct, isLoading: productLoading } = + useAdminCreateProduct() + const { client } = useMedusa() + + const isLoading = collectionLoading || productLoading + + const createSample = async () => { + try { + const { collection } = await createCollection({ + title: "Merch", + handle: "merch", + }) + + const regions = await prepareRegions(client) + + const tryCreateProduct = async (sampleProduct: AdminPostProductsReq): Promise => { + try { + return (await createProduct(sampleProduct)).product + } catch { + // ignore if product already exists + return null + } + } + + let product: Product + const sampleProducts = getSampleProducts({ + regions, + collection_id: collection.id, + }) + await Promise.all( + sampleProducts.map(async (sampleProduct, index) => { + const createdProduct = await tryCreateProduct(sampleProduct) + if (index === 0 && createProduct) { + product = createdProduct + } + }) + ) + onNext(product) + } catch (e) { + console.error(e) + } + } + + return ( +
+ + Products is Medusa represent the products you sell. You can set their general details including a + title and description. Each product has options and variants, and you can set a price for each variant. + + + Click the button below to create sample products. + + {!isComplete && ( +
+ +
+ )} +
+ ) + } + + export default ProductsListNextjs + ``` + +
+ +
+ ProductDetailNextjs component + + The `ProductDetailNextjs` component is used in the second step of the onboarding's Next.js flow. It shows the user a button to preview the product created in the first step using the Next.js starter. + + Create the file `src/admin/components/onboarding-flow/nextjs/products/product-detail.tsx` with the following content: + + + + ```tsx title=src/admin/components/onboarding-flow/nextjs/products/product-detail.tsx + import { useAdminProduct } from "medusa-react" + import { StepContentProps } from "../../../../widgets/onboarding-flow/onboarding-flow" + import { Button, Text } from "@medusajs/ui" + + const ProductDetailNextjs = ({ onNext, isComplete, data }: StepContentProps) => { + const { product, isLoading: productIsLoading } = useAdminProduct(data?.product_id) + return ( +
+
+ + We have now created a few sample products in your Medusa store. You can scroll down to see what the Product Detail view looks like in the Admin dashboard. + This is also the view you use to edit existing products. + + + To view the products in your store, you can visit the Next.js Storefront that was installed with create-medusa-app. + + + The Next.js Storefront Starter is a template that helps you start building an ecommerce store with Medusa. + You control the code for the storefront and you can customize it further to fit your specific needs. + + + Click the button below to view the products in your Next.js Storefront. + + + Having trouble? Click{" "} + + here + . + +
+
+ + + + {!isComplete && ( + + )} +
+
+ ) + } + + export default ProductDetailNextjs + ``` + +
+ +
+ OrdersListNextjs component + + The `OrdersListNextjs` component is used in the third step of the onboarding's Next.js flow. It links the user to the checkout flow in the Next.js storefront so that they can create an order. + + Create the file `src/admin/components/onboarding-flow/nextjs/orders/orders-list.tsx` with the following content: + + + + ```tsx title=src/admin/components/onboarding-flow/nextjs/orders/orders-list.tsx + import React from "react" + import { + useAdminProduct, + useCreateCart, + useMedusa, + } from "medusa-react" + import { StepContentProps } from "../../../../widgets/onboarding-flow/onboarding-flow" + import { Button, Text } from "@medusajs/ui" + import prepareRegions from "../../../../utils/prepare-region" + import prepareShippingOptions from "../../../../utils/prepare-shipping-options" + + const OrdersListNextjs = ({ isComplete, data }: StepContentProps) => { + const { product } = useAdminProduct(data.product_id) + const { mutateAsync: createCart, isLoading: cartIsLoading } = useCreateCart() + const { client } = useMedusa() + + const prepareNextjsCheckout = async () => { + const variant = product.variants[0] ?? null + try { + const regions = await prepareRegions(client) + await prepareShippingOptions(client, regions[0]) + const { cart } = await createCart({ + region_id: regions[0]?.id, + items: [ + { + variant_id: variant?.id, + quantity: 1, + }, + ], + }) + + window.open(`http://localhost:8000/checkout?cart_id=${cart?.id}&onboarding=true`, "_blank") + } catch (e) { + console.error(e) + } + } + + return ( + <> +
+ + The last step is to create a sample order using one of your products. You can then view your order’s details, process its payment, fulfillment, inventory, and more. + + + You can use the button below to experience hand-first the checkout flow in the Next.js storefront. After placing the order in the storefront, you’ll be directed back here to view the order’s details. + +
+
+ {!isComplete && ( + <> + + + )} +
+ + ) + } + + export default OrdersListNextjs + ``` + +
+ +
+ OrderDetailNextjs component + + The `OrderDetailNextjs` component is used in the fourth and final step of the onboarding's default flow. It educates the user on the next steps when developing with Medusa. + + Create the file `src/admin/components/onboarding-flow/nextjs/orders/order-detail.tsx` with the following content: + + + + ```tsx title=src/admin/components/onboarding-flow/nextjs/orders/order-detail.tsx + import React from "react" + import { CurrencyDollarSolid, NextJs, SquaresPlusSolid } from "@medusajs/icons" + import { IconBadge, Heading, Text } from "@medusajs/ui" + + const OrderDetailNextjs = () => { + const queryParams = `?ref=onboarding&type=${ + process.env.MEDUSA_ADMIN_ONBOARDING_TYPE || "nextjs" + }` + return ( + <> + + You finished the setup guide 🎉. You have now a complete ecommerce store + with a backend, admin, and a Next.js storefront. Feel free to play + around with each of these components to experience all commerce features + that Medusa provides. + + + Continue Building your Ecommerce Store + + + Your ecommerce store provides all basic ecommerce features you need to + start selling. You can add more functionalities, add plugins for + third-party integrations, and customize the storefront’s look and feel + to support your use case. + + +
+ You can find more useful guides in{" "} + + our documentation + + . If you like Medusa, please{" "} + + star us on GitHub + + . +
+ + ) + } + + export default OrderDetailNextjs + ``` + +
+ +--- + +## Step 4: Test it Out + +You’ve now implemented everything necessary for the onboarding flow! You can test it out by building the changes and running the `develop` command: + +```bash npm2yarn +npm run build +npx medusa develop +``` + +If you open the admin at `localhost:7001` and log in, you’ll see the onboarding widget in the Products listing page. You can try using it and see your implementation in action! + +--- + +## Next Steps: Continue Development + +- [Learn more about Admin Widgets](./widgets.md) +- [Learn how you can start custom development in your backend](../recipes/index.mdx) diff --git a/www/apps/docs/content/contribution/docs.md b/www/apps/docs/content/contribution/docs.md index 6235bdedfd..d56186f98a 100644 --- a/www/apps/docs/content/contribution/docs.md +++ b/www/apps/docs/content/contribution/docs.md @@ -351,26 +351,26 @@ import TabItem from '@theme/TabItem'; - + -```ts -medusa.admin.uploads.create(file) // file is an instance of File -.then(({ uploads }) => { - const key = uploads[0].key -}) -``` + ```ts + medusa.admin.uploads.create(file) // file is an instance of File + .then(({ uploads }) => { + const key = uploads[0].key + }) + ``` - - + + -```bash -curl -L -X POST '/admin/uploads' \ - -H 'Authorization: Bearer ' \ - -H 'Content-Type: text/csv' \ - -F 'files=@""' -``` + ```bash + curl -L -X POST '/admin/uploads' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: text/csv' \ + -F 'files=@""' + ``` - + ~~~ diff --git a/www/apps/docs/content/create-medusa-app.mdx b/www/apps/docs/content/create-medusa-app.mdx index da1b6144f2..1de434facc 100644 --- a/www/apps/docs/content/create-medusa-app.mdx +++ b/www/apps/docs/content/create-medusa-app.mdx @@ -42,9 +42,9 @@ In your terminal, run the following command: - ```bash - npx create-medusa-app@latest - ``` + ```bash + npx create-medusa-app@latest + ``` {/* @@ -56,69 +56,60 @@ In your terminal, run the following command: */} - ```bash - pnpm dlx create-medusa-app@latest - ``` + ```bash + pnpm dlx create-medusa-app@latest + ``` -
- -Command Options - +
+ Command Options + + The `create-medusa-app` command can accept the following options: -The `create-medusa-app` command can accept the following options: + - `--repo-url `: The repository URL to create the project from. By default it will be `https://github.com/medusajs/medusa-starter-default`. + - `--seed`: A flag indicating whether the database should be seeded with demo data. By default, seeding is disabled. + - `--no-boilerplate`: A flag that removes all files added for an enhanced onboarding experience (files under `src/admin`, `src/api`, etc...). This is helpful if you want to create a clean project, and is only recommended if you're familiar with Medusa. + - `--no-browser`: Disables opening the browser at the end of the project creation and only shows success message. + - `--skip-db`: Skips creating the database, running migrations, and seeding, and subsequently skips opening the browser. Useful if you want to set the database URL at a later point in the configurations. + - `--db-url `: Skips database creation and sets the database URL to the provided URL. Throws an error if connection to the database fails. Will still run migrations and open the admin after project creation. Useful if you already have a database created, locally or remotely. + - `--no-migrations`: Skips running migrations, creating admin user, and seeding. If used, it's expected that you pass the `--db-url` option with a URL of a database that has all necessary migrations. Otherwise, unexpected errors will occur. Helpful only if combined with `--db-url`. + - `--directory-path `: Allows specifying the parent directory path to create the directory of the new project in. + - `--with-nextjs-starter`: Installs the Next.js starter storefront under the `-storefront` directory, where `` is the name of the project you enter in the first question. If the `-storefront` directory already exists, random characters are added at the end of `-storefront`. +
-- `--repo-url `: The repository URL to create the project from. By default it will be `https://github.com/medusajs/medusa-starter-default`. -- `--seed`: A flag indicating whether the database should be seeded with demo data. By default, seeding is disabled. -- `--no-boilerplate`: A flag that removes all files added for an enhanced onboarding experience (files under `src/admin`, `src/api`, etc...). This is helpful if you want to create a clean project, and is only recommended if you're familiar with Medusa. -- `--no-browser`: Disables opening the browser at the end of the project creation and only shows success message. -- `--skip-db`: Skips creating the database, running migrations, and seeding, and subsequently skips opening the browser. Useful if you want to set the database URL at a later point in the configurations. -- `--db-url `: Skips database creation and sets the database URL to the provided URL. Throws an error if connection to the database fails. Will still run migrations and open the admin after project creation. Useful if you already have a database created, locally or remotely. -- `--no-migrations`: Skips running migrations, creating admin user, and seeding. If used, it's expected that you pass the `--db-url` option with a URL of a database that has all necessary migrations. Otherwise, unexpected errors will occur. Helpful only if combined with `--db-url`. -- `--directory-path `: Allows specifying the parent directory path to create the directory of the new project in. -- `--with-nextjs-starter`: Installs the Next.js starter storefront under the `-storefront` directory, where `` is the name of the project you enter in the first question. If the `-storefront` directory already exists, random characters are added at the end of `-storefront`. +
+ Example: Connect to a Vercel PostgreSQL Database -
+ If you want to use a PostgreSQL database hosted on Vercel, you must use the `--db-url` option and add to the end of your connection URL `?sslmode=require`. For example: -
- -Example: Connect to a Vercel PostgreSQL Database - + ```bash + npx create-medusa-app@latest --db-url "postgres://default:.postgres.vercel-storage.com:5432/verceldb?sslmode=require" + ``` -If you want to use a PostgreSQL database hosted on Vercel, you must use the `--db-url` option and add to the end of your connection URL `?sslmode=require`. For example: + :::note -```bash -npx create-medusa-app@latest --db-url "postgres://default:.postgres.vercel-storage.com:5432/verceldb?sslmode=require" -``` + If the database already has the necessary migrations and you don't need the command to run migrations, you can pass the `--no-migrations` option. -:::note + ::: +
-If the database already has the necessary migrations and you don't need the command to run migrations, you can pass the `--no-migrations` option. +
+ Example: Connect to a Supabase Database -::: + If you want to connect to a Supabase database, you must use the `--db-url` option with its value beign the connection URL to your Supabase database. For example: -
+ ```bash + npx create-medusa-app@latest --db-url postgresql://postgres:@.supabase.co:5432/postgres + ``` -
- -Example: Connect to a Supabase Database - + :::note -If you want to connect to a Supabase database, you must use the `--db-url` option with its value beign the connection URL to your Supabase database. For example: + If the database already has the necessary migrations and you don't need the command to run migrations, you can pass the `--no-migrations` option. -```bash -npx create-medusa-app@latest --db-url postgresql://postgres:@.supabase.co:5432/postgres -``` - -:::note - -If the database already has the necessary migrations and you don't need the command to run migrations, you can pass the `--no-migrations` option. - -::: - -
+ ::: +
## Step 2: Specify Project Name diff --git a/www/apps/docs/content/deployments/server/deploying-on-railway.md b/www/apps/docs/content/deployments/server/deploying-on-railway.md index 494d5ac9ef..6d8601103c 100644 --- a/www/apps/docs/content/deployments/server/deploying-on-railway.md +++ b/www/apps/docs/content/deployments/server/deploying-on-railway.md @@ -22,8 +22,8 @@ If you're deploying the admin plugin along with the backend, you'll need at leas If you also don't have a Medusa project, you can deploy to Railway instantly with this button: - Deploy with Railway + href="https://railway.app/template/zC7eOq?referralCode=TW4Qi0" className="img-url no-zoom-img"> + Deploy with Railway --- diff --git a/www/apps/docs/content/deployments/storefront/deploying-next-on-vercel.mdx b/www/apps/docs/content/deployments/storefront/deploying-next-on-vercel.mdx index 2ff1871f9d..7d39d12750 100644 --- a/www/apps/docs/content/deployments/storefront/deploying-next-on-vercel.mdx +++ b/www/apps/docs/content/deployments/storefront/deploying-next-on-vercel.mdx @@ -13,8 +13,8 @@ In this document, you’ll learn how to deploy the Next.js Starter Template on V Alternatively, you can directly deploy the Next.js Starter Template to Vercel with this button. - Deploy with Vercel + href="https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fmedusajs%2Fnextjs-starter-medusa.git&env=NEXT_PUBLIC_MEDUSA_BACKEND_URL&envDescription=URL%20of%20your%20Medusa%20Backend" className="img-url no-zoom-img"> + Deploy with Vercel :::note diff --git a/www/apps/docs/content/development/api-routes/create-express-route.mdx b/www/apps/docs/content/development/api-routes/create-express-route.mdx index 3fb5dc49a4..77930f5ae8 100644 --- a/www/apps/docs/content/development/api-routes/create-express-route.mdx +++ b/www/apps/docs/content/development/api-routes/create-express-route.mdx @@ -143,52 +143,52 @@ export default (rootDirectory) => { Then, create an object that will hold the CORS configurations. Based on whether it's storefront or admin CORS options, you pass it the respective configuration from `projectConfig`: - + -```ts -const storeCorsOptions = { - origin: projectConfig.store_cors.split(","), - credentials: true, -} -``` + ```ts + const storeCorsOptions = { + origin: projectConfig.store_cors.split(","), + credentials: true, + } + ``` - - + + -```ts -const adminCorsOptions = { - origin: projectConfig.admin_cors.split(","), - credentials: true, -} -``` + ```ts + const adminCorsOptions = { + origin: projectConfig.admin_cors.split(","), + credentials: true, + } + ``` - + Finally, you can either pass the `cors` middleware for a specific route, or pass it to the entire router: - + -```ts -adminRouter.options("/admin/hello", cors(adminCorsOptions)) -adminRouter.get( - "/admin/hello", - cors(adminCorsOptions), - (req, res) => { - // ... - } -) -``` + ```ts + adminRouter.options("/admin/hello", cors(adminCorsOptions)) + adminRouter.get( + "/admin/hello", + cors(adminCorsOptions), + (req, res) => { + // ... + } + ) + ``` - - + + -```ts -adminRouter.use(cors(adminCorsOptions)) -``` + ```ts + adminRouter.use(cors(adminCorsOptions)) + ``` - + --- @@ -252,43 +252,43 @@ import { requireCustomerAuthentication } from "@medusajs/medusa" Then, pass the middleware to either a single route or an entire router: - + -```ts -// only necessary if you're passing cors options per route -router.options("/store/hello", cors(storeCorsOptions)) -router.get( - "/store/hello", - cors(storeCorsOptions), - requireCustomerAuthentication(), - // authenticateCustomer() - async (req, res) => { - // access current customer - const id = req.user.customer_id - // if you're using authenticateCustomer middleware - // check if id is set first + ```ts + // only necessary if you're passing cors options per route + router.options("/store/hello", cors(storeCorsOptions)) + router.get( + "/store/hello", + cors(storeCorsOptions), + requireCustomerAuthentication(), + // authenticateCustomer() + async (req, res) => { + // access current customer + const id = req.user.customer_id + // if you're using authenticateCustomer middleware + // check if id is set first - const customerService = req.scope.resolve("customerService") - - const customer = await customerService.retrieve(id) - // ... - } -) -``` + const customerService = req.scope.resolve("customerService") + + const customer = await customerService.retrieve(id) + // ... + } + ) + ``` - - + + -```ts -storeRouter.use(requireCustomerAuthentication()) -// all routes added to storeRouter are now protected -// the logged in customer can be accessed using: -// req.user.customer_id + ```ts + storeRouter.use(requireCustomerAuthentication()) + // all routes added to storeRouter are now protected + // the logged in customer can be accessed using: + // req.user.customer_id -// storeRouter.use(authenticateCustomer()) -``` + // storeRouter.use(authenticateCustomer()) + ``` - + ### Protect Admin Routes @@ -304,37 +304,37 @@ import { authenticate } from "@medusajs/medusa" Then, pass the middleware to either a single route or an entire router: - + -```ts -// only necessary if you're passing cors options per route -adminRouter.options("/admin/hello", cors(adminCorsOptions)) -adminRouter.get( - "/admin/hello", - cors(adminCorsOptions), - authenticate(), - async (req, res) => { - // access current user - const id = req.user.userId - const userService = req.scope.resolve("userService") - - const user = await userService.retrieve(id) - // ... - } -) -``` + ```ts + // only necessary if you're passing cors options per route + adminRouter.options("/admin/hello", cors(adminCorsOptions)) + adminRouter.get( + "/admin/hello", + cors(adminCorsOptions), + authenticate(), + async (req, res) => { + // access current user + const id = req.user.userId + const userService = req.scope.resolve("userService") + + const user = await userService.retrieve(id) + // ... + } + ) + ``` - - + + -```ts -adminRouter.use(authenticate()) -// all routes added to adminRouter are now protected -// the logged in user can be accessed using: -// req.user.userId -``` + ```ts + adminRouter.use(authenticate()) + // all routes added to adminRouter are now protected + // the logged in user can be accessed using: + // req.user.userId + ``` - + --- @@ -628,318 +628,318 @@ This section services as an example of creating endpoints that perform Create, R You can refer to the [Entities](../entities/create.mdx#adding-relations) and [Services](../services/create-service.mdx#example-services-with-crud-operations) documentation to learn how to create the custom entities and services used in this example. - + -```ts -import express, { Router } from "express" -import adminRoutes from "./admin" -import storeRoutes from "./store" -import { errorHandler } from "@medusajs/medusa" + ```ts + import express, { Router } from "express" + import adminRoutes from "./admin" + import storeRoutes from "./store" + import { errorHandler } from "@medusajs/medusa" -export default (rootDirectory, options) => { - const router = Router() + export default (rootDirectory, options) => { + const router = Router() - router.use(express.json()) - router.use(express.urlencoded({ extended: true })) + router.use(express.json()) + router.use(express.urlencoded({ extended: true })) - adminRoutes(router, options) - storeRoutes(router, options) + adminRoutes(router, options) + storeRoutes(router, options) - router.use(errorHandler()) + router.use(errorHandler()) - return router -} -``` + return router + } + ``` - - + + -```ts -import { Router } from "express" -import PostService from "../services/post" -import { - ConfigModule, -} from "@medusajs/medusa/dist/types/global" -import cors from "cors" -import { authenticate, wrapHandler } from "@medusajs/medusa" -import AuthorService from "../services/author" + ```ts + import { Router } from "express" + import PostService from "../services/post" + import { + ConfigModule, + } from "@medusajs/medusa/dist/types/global" + import cors from "cors" + import { authenticate, wrapHandler } from "@medusajs/medusa" + import AuthorService from "../services/author" -export default function adminRoutes( - router: Router, - options: ConfigModule -) { - const { projectConfig } = options + export default function adminRoutes( + router: Router, + options: ConfigModule + ) { + const { projectConfig } = options - const corsOptions = { - origin: projectConfig.admin_cors.split(","), - credentials: true, - } - - const adminRouter = Router() - - router.use("/admin/blog", adminRouter) - - adminRouter.use(cors(corsOptions)) - adminRouter.use(authenticate()) - - // it's recommended to define the routes - // in separate files. They're done in - // the same file here for simplicity - - - // list all blog posts - adminRouter.get( - "/posts", - wrapHandler(async (req, res) => { - const postService: PostService = req.scope.resolve( - "postService" - ) - - res.json({ - posts: await postService.list(), - }) - })) - - - // retrieve a single blog post - adminRouter.get( - "/posts/:id", - wrapHandler(async (req, res) => { - const postService: PostService = req.scope.resolve( - "postService" - ) - - const post = await postService.retrieve(req.params.id) - - res.json({ - post, - }) - })) - - // create a blog post - adminRouter.post( - "/posts", - wrapHandler(async (req, res) => { - const postService: PostService = req.scope.resolve( - "postService" - ) - - // basic validation of request body - if (!req.body.title || !req.body.author_id) { - throw new Error("`title` and `author_id` are required.") + const corsOptions = { + origin: projectConfig.admin_cors.split(","), + credentials: true, } - const post = await postService.create(req.body) + const adminRouter = Router() - res.json({ - post, - }) - })) + router.use("/admin/blog", adminRouter) - // update a blog post - adminRouter.post( - "/posts/:id", - wrapHandler(async (req, res) => { - const postService: PostService = req.scope.resolve( - "postService" - ) + adminRouter.use(cors(corsOptions)) + adminRouter.use(authenticate()) - // basic validation of request body - if (req.body.id) { - throw new Error("Can't update post ID") + // it's recommended to define the routes + // in separate files. They're done in + // the same file here for simplicity + + + // list all blog posts + adminRouter.get( + "/posts", + wrapHandler(async (req, res) => { + const postService: PostService = req.scope.resolve( + "postService" + ) + + res.json({ + posts: await postService.list(), + }) + })) + + + // retrieve a single blog post + adminRouter.get( + "/posts/:id", + wrapHandler(async (req, res) => { + const postService: PostService = req.scope.resolve( + "postService" + ) + + const post = await postService.retrieve(req.params.id) + + res.json({ + post, + }) + })) + + // create a blog post + adminRouter.post( + "/posts", + wrapHandler(async (req, res) => { + const postService: PostService = req.scope.resolve( + "postService" + ) + + // basic validation of request body + if (!req.body.title || !req.body.author_id) { + throw new Error("`title` and `author_id` are required.") + } + + const post = await postService.create(req.body) + + res.json({ + post, + }) + })) + + // update a blog post + adminRouter.post( + "/posts/:id", + wrapHandler(async (req, res) => { + const postService: PostService = req.scope.resolve( + "postService" + ) + + // basic validation of request body + if (req.body.id) { + throw new Error("Can't update post ID") + } + + const post = await postService.update( + req.params.id, + req.body + ) + + res.json({ + post, + }) + })) + + // delete a blog post + adminRouter.delete( + "/posts/:id", + wrapHandler(async (req, res) => { + const postService: PostService = req.scope.resolve( + "postService" + ) + + await postService.delete(req.params.id) + + res.status(200).end() + })) + + // list all blog authors + adminRouter.get( + "/authors", + wrapHandler(async (req, res) => { + const authorService: AuthorService = req.scope.resolve( + "authorService" + ) + + res.json({ + authors: await authorService.list(), + }) + })) + + // retrieve a single blog author + adminRouter.get( + "/authors/:id", + wrapHandler(async (req, res) => { + const authorService: AuthorService = req.scope.resolve( + "authorService" + ) + + res.json({ + post: await authorService.retrieve(req.params.id), + }) + })) + + // create a blog author + adminRouter.post( + "/authors", + wrapHandler(async (req, res) => { + const authorService: AuthorService = req.scope.resolve( + "authorService" + ) + + // basic validation of request body + if (!req.body.name) { + throw new Error("`name` is required.") + } + + const author = await authorService.create(req.body) + + res.json({ + author, + }) + })) + + // update a blog author + adminRouter.post( + "/authors/:id", + wrapHandler(async (req, res) => { + const authorService: AuthorService = req.scope.resolve( + "authorService" + ) + + // basic validation of request body + if (req.body.id) { + throw new Error("Can't update author ID") + } + + const author = await authorService.update( + req.params.id, + req.body + ) + + res.json({ + author, + }) + })) + + // delete a blog author + adminRouter.delete( + "/authors/:id", + wrapHandler(async (req, res) => { + const authorService: AuthorService = req.scope.resolve( + "authorService" + ) + + await authorService.delete(req.params.id) + + res.status(200).end() + })) + } + ``` + + + + + ```ts + import { Router } from "express" + import { + ConfigModule, + } from "@medusajs/medusa/dist/types/global" + import PostService from "../services/post" + import cors from "cors" + import AuthorService from "../services/author" + import { wrapHandler } from "@medusajs/medusa" + + export default function storeRoutes( + router: Router, + options: ConfigModule + ) { + const { projectConfig } = options + + const storeCorsOptions = { + origin: projectConfig.store_cors.split(","), + credentials: true, } - const post = await postService.update( - req.params.id, - req.body - ) + const storeRouter = Router() + router.use("/store/blog", storeRouter) - res.json({ - post, - }) - })) + storeRouter.use(cors(storeCorsOptions)) + + // list all blog posts + storeRouter.get( + "/posts", + wrapHandler(async (req, res) => { + const postService: PostService = req.scope.resolve( + "postService" + ) - // delete a blog post - adminRouter.delete( - "/posts/:id", - wrapHandler(async (req, res) => { - const postService: PostService = req.scope.resolve( - "postService" - ) + res.json({ + posts: await postService.list(), + }) + })) - await postService.delete(req.params.id) + // retrieve a single blog post + storeRouter.get( + "/posts/:id", + wrapHandler(async (req, res) => { + const postService: PostService = req.scope.resolve( + "postService" + ) - res.status(200).end() - })) + res.json({ + post: await postService.retrieve(req.params.id), + }) + })) - // list all blog authors - adminRouter.get( - "/authors", - wrapHandler(async (req, res) => { - const authorService: AuthorService = req.scope.resolve( - "authorService" - ) + // list all blog authors + storeRouter.get( + "/authors", + wrapHandler(async (req, res) => { + const authorService: AuthorService = req.scope.resolve( + "authorService" + ) - res.json({ - authors: await authorService.list(), - }) - })) + res.json({ + authors: await authorService.list(), + }) + })) - // retrieve a single blog author - adminRouter.get( - "/authors/:id", - wrapHandler(async (req, res) => { - const authorService: AuthorService = req.scope.resolve( - "authorService" - ) + // retrieve a single blog author + storeRouter.get( + "/authors/:id", + wrapHandler(async (req, res) => { + const authorService: AuthorService = req.scope.resolve( + "authorService" + ) - res.json({ - post: await authorService.retrieve(req.params.id), - }) - })) + res.json({ + post: await authorService.retrieve(req.params.id), + }) + })) + } + ``` - // create a blog author - adminRouter.post( - "/authors", - wrapHandler(async (req, res) => { - const authorService: AuthorService = req.scope.resolve( - "authorService" - ) - - // basic validation of request body - if (!req.body.name) { - throw new Error("`name` is required.") - } - - const author = await authorService.create(req.body) - - res.json({ - author, - }) - })) - - // update a blog author - adminRouter.post( - "/authors/:id", - wrapHandler(async (req, res) => { - const authorService: AuthorService = req.scope.resolve( - "authorService" - ) - - // basic validation of request body - if (req.body.id) { - throw new Error("Can't update author ID") - } - - const author = await authorService.update( - req.params.id, - req.body - ) - - res.json({ - author, - }) - })) - - // delete a blog author - adminRouter.delete( - "/authors/:id", - wrapHandler(async (req, res) => { - const authorService: AuthorService = req.scope.resolve( - "authorService" - ) - - await authorService.delete(req.params.id) - - res.status(200).end() - })) -} -``` - - - - -```ts -import { Router } from "express" -import { - ConfigModule, -} from "@medusajs/medusa/dist/types/global" -import PostService from "../services/post" -import cors from "cors" -import AuthorService from "../services/author" -import { wrapHandler } from "@medusajs/medusa" - -export default function storeRoutes( - router: Router, - options: ConfigModule -) { - const { projectConfig } = options - - const storeCorsOptions = { - origin: projectConfig.store_cors.split(","), - credentials: true, - } - - const storeRouter = Router() - router.use("/store/blog", storeRouter) - - storeRouter.use(cors(storeCorsOptions)) - - // list all blog posts - storeRouter.get( - "/posts", - wrapHandler(async (req, res) => { - const postService: PostService = req.scope.resolve( - "postService" - ) - - res.json({ - posts: await postService.list(), - }) - })) - - // retrieve a single blog post - storeRouter.get( - "/posts/:id", - wrapHandler(async (req, res) => { - const postService: PostService = req.scope.resolve( - "postService" - ) - - res.json({ - post: await postService.retrieve(req.params.id), - }) - })) - - // list all blog authors - storeRouter.get( - "/authors", - wrapHandler(async (req, res) => { - const authorService: AuthorService = req.scope.resolve( - "authorService" - ) - - res.json({ - authors: await authorService.list(), - }) - })) - - // retrieve a single blog author - storeRouter.get( - "/authors/:id", - wrapHandler(async (req, res) => { - const authorService: AuthorService = req.scope.resolve( - "authorService" - ) - - res.json({ - post: await authorService.retrieve(req.params.id), - }) - })) -} -``` - - + --- diff --git a/www/apps/docs/content/development/api-routes/create.mdx b/www/apps/docs/content/development/api-routes/create.mdx index 9ce960b627..ebcbe5d0a4 100644 --- a/www/apps/docs/content/development/api-routes/create.mdx +++ b/www/apps/docs/content/development/api-routes/create.mdx @@ -538,25 +538,23 @@ After using `MedusaError`, the returned error in the response provides a clearer } ``` -
- -Available MedusaError Types and their respective status codes - +
+ Available MedusaError Types and their respective status codes -The default response code is `500` unless mentioned otherwise. + The default response code is `500` unless mentioned otherwise. -- `MedusaError.Types.DB_ERROR`: Sets the response code to `500`. -- `MedusaError.Types.DUPLICATE_ERROR`: Sets the response code to `422`. -- `MedusaError.Types.INVALID_ARGUMENT` -- `MedusaError.Types.INVALID_DATA`: Sets the resposne code to `400`. -- `MedusaError.Types.UNAUTHORIZED`: Sets the resposne code to `401`. -- `MedusaError.Types.NOT_FOUND`: Sets the response code to `404`. -- `MedusaError.Types.NOT_ALLOWED`: Sets the resposne code to `400`. -- `MedusaError.Types.UNEXPECTED_STATE` -- `MedusaError.Types.CONFLICT`: Sets the resposne code to `409`. -- `MedusaError.Types.PAYMENT_AUTHORIZATION_ERROR`: Sets the resposne code to `422`. + - `MedusaError.Types.DB_ERROR`: Sets the response code to `500`. + - `MedusaError.Types.DUPLICATE_ERROR`: Sets the response code to `422`. + - `MedusaError.Types.INVALID_ARGUMENT` + - `MedusaError.Types.INVALID_DATA`: Sets the resposne code to `400`. + - `MedusaError.Types.UNAUTHORIZED`: Sets the resposne code to `401`. + - `MedusaError.Types.NOT_FOUND`: Sets the response code to `404`. + - `MedusaError.Types.NOT_ALLOWED`: Sets the resposne code to `400`. + - `MedusaError.Types.UNEXPECTED_STATE` + - `MedusaError.Types.CONFLICT`: Sets the resposne code to `409`. + - `MedusaError.Types.PAYMENT_AUTHORIZATION_ERROR`: Sets the resposne code to `422`. -
+
### Override Error Handler @@ -691,41 +689,41 @@ Files and directories prefixed with `_` are ignored. This can be helpful if you For example: - + -```ts -import getProducts from "../_methods/get-products" + ```ts + import getProducts from "../_methods/get-products" -export const GET = getProducts -``` + export const GET = getProducts + ``` - - + + -```ts -import { - MedusaRequest, - MedusaResponse, - ProductService, -} from "@medusajs/medusa" + ```ts + import { + MedusaRequest, + MedusaResponse, + ProductService, + } from "@medusajs/medusa" -export default async function ( - req: MedusaRequest, - res: MedusaResponse -) { - const productService = req.scope.resolve( - "productService" - ) + export default async function ( + req: MedusaRequest, + res: MedusaResponse + ) { + const productService = req.scope.resolve( + "productService" + ) - const products = await productService.list({}) + const products = await productService.list({}) - res.json({ - products, - }) -} -``` + res.json({ + products, + }) + } + ``` - + --- @@ -741,117 +739,117 @@ You can refer to the [Entities](../entities/create.mdx#adding-relations) and [Se ::: - + -```ts -import type { - MedusaRequest, - MedusaResponse, -} from "@medusajs/medusa" -import { PostService } from "../../../services/post" + ```ts + import type { + MedusaRequest, + MedusaResponse, + } from "@medusajs/medusa" + import { PostService } from "../../../services/post" -// list posts -export const GET = async ( - req: MedusaRequest, - res: MedusaResponse -) => { - const postService: PostService = req.scope.resolve( - "postService" - ) + // list posts + export const GET = async ( + req: MedusaRequest, + res: MedusaResponse + ) => { + const postService: PostService = req.scope.resolve( + "postService" + ) - res.json({ - posts: await postService.list(), - }) -} + res.json({ + posts: await postService.list(), + }) + } -// create a post -export const POST = async ( - req: MedusaRequest, - res: MedusaResponse -) => { - const postService: PostService = req.scope.resolve( - "postService" - ) + // create a post + export const POST = async ( + req: MedusaRequest, + res: MedusaResponse + ) => { + const postService: PostService = req.scope.resolve( + "postService" + ) - // basic validation of request body - if (!req.body.title || !req.body.author_id) { - throw new Error("`title` and `author_id` are required.") - } + // basic validation of request body + if (!req.body.title || !req.body.author_id) { + throw new Error("`title` and `author_id` are required.") + } - const post = await postService.create(req.body) + const post = await postService.create(req.body) - res.json({ - post, - }) -} -``` + res.json({ + post, + }) + } + ``` - - + + -```ts -import type { - MedusaRequest, - MedusaResponse, -} from "@medusajs/medusa" -import { PostService } from "../../../services/post" + ```ts + import type { + MedusaRequest, + MedusaResponse, + } from "@medusajs/medusa" + import { PostService } from "../../../services/post" -// retrieve a post by its ID -export const GET = async ( - req: MedusaRequest, - res: MedusaResponse -) => { - const postService: PostService = req.scope.resolve( - "postService" - ) + // retrieve a post by its ID + export const GET = async ( + req: MedusaRequest, + res: MedusaResponse + ) => { + const postService: PostService = req.scope.resolve( + "postService" + ) - const post = await postService.retrieve(req.params.id) + const post = await postService.retrieve(req.params.id) - res.json({ - post, - }) -} + res.json({ + post, + }) + } -// update a post by its ID -export const POST = async ( - req: MedusaRequest, - res: MedusaResponse -) => { - const postService: PostService = req.scope.resolve( - "postService" - ) + // update a post by its ID + export const POST = async ( + req: MedusaRequest, + res: MedusaResponse + ) => { + const postService: PostService = req.scope.resolve( + "postService" + ) - // basic validation of request body - if (req.body.id) { - throw new Error("Can't update post ID") - } + // basic validation of request body + if (req.body.id) { + throw new Error("Can't update post ID") + } - const post = await postService.update( - req.params.id, - req.body - ) + const post = await postService.update( + req.params.id, + req.body + ) - res.json({ - post, - }) -} + res.json({ + post, + }) + } -// delete a post by its ID -export const DELETE = async ( - req: MedusaRequest, - res: MedusaResponse -) => { - const postService: PostService = req.scope.resolve( - "postService" - ) + // delete a post by its ID + export const DELETE = async ( + req: MedusaRequest, + res: MedusaResponse + ) => { + const postService: PostService = req.scope.resolve( + "postService" + ) - await postService.delete(req.params.id) + await postService.delete(req.params.id) - res.status(200).end() -} -``` + res.status(200).end() + } + ``` - + --- diff --git a/www/apps/docs/content/development/backend/prepare-environment.mdx b/www/apps/docs/content/development/backend/prepare-environment.mdx index 96e117cc94..f898968c18 100644 --- a/www/apps/docs/content/development/backend/prepare-environment.mdx +++ b/www/apps/docs/content/development/backend/prepare-environment.mdx @@ -25,60 +25,48 @@ node -v ::: - + + You can install the executable directly from [the Node.js website](https://nodejs.org/en/#home-downloadhead). -You can install the executable directly from [the Node.js website](https://nodejs.org/en/#home-downloadhead). + For other approaches, you can check out [Node.js’s guide](https://nodejs.org/en/download/package-manager/#windows-1). + + + You can use the following commands to install Node.js on Ubuntu: -For other approaches, you can check out [Node.js’s guide](https://nodejs.org/en/download/package-manager/#windows-1). + ```bash + #Ubuntu + sudo apt update + sudo apt install nodejs + ``` - - + For other Linux distributions, you can check out [Node.js’s guide](https://nodejs.org/en/download/package-manager/). + + + You can use the following commands to install Node.js on macOS: -You can use the following commands to install Node.js on Ubuntu: + + + ```bash + brew install node + ``` + + + ```bash + curl \ + "https://nodejs.org/dist/latest/node-${VERSION:-$(wget -qO- \ + https://nodejs.org/dist/latest/ | sed -nE \ + 's|.*>node-(.*)\.pkg.*|\1|p')}.pkg" \ + > "$HOME/Downloads/node-latest.pkg" && + sudo installer -store -pkg "$HOME/Downloads/node-latest.pkg" -target "/" + ``` + + -```bash -#Ubuntu -sudo apt update -sudo apt install nodejs -``` + For other approaches, you can check out [Node.js’s guide](https://nodejs.org/en/download/package-manager/#macos). -For other Linux distributions, you can check out [Node.js’s guide](https://nodejs.org/en/download/package-manager/). + Make sure that you have Xcode command line tools installed. If not, run the following command to install it: `xcode-select --install`. - - - -You can use the following commands to install Node.js on macOS: - - - - -```bash -brew install node -``` - - - - -```bash -curl \ - "https://nodejs.org/dist/latest/node-${VERSION:-$(wget -qO- \ - https://nodejs.org/dist/latest/ | sed -nE \ - 's|.*>node-(.*)\.pkg.*|\1|p')}.pkg" \ - > "$HOME/Downloads/node-latest.pkg" && - sudo installer -store -pkg "$HOME/Downloads/node-latest.pkg" -target "/" -``` - - - - -For other approaches, you can check out [Node.js’s guide](https://nodejs.org/en/download/package-manager/#macos). - -:::tip - -Make sure that you have Xcode command line tools installed; if not, run the following command to install it: `xcode-select --install` - -::: - + ## Git @@ -86,35 +74,29 @@ Make sure that you have Xcode command line tools installed; if not, run the fol Medusa uses Git behind the scenes when you create a new project. So, you'll have to install it on your machine to get started. - + + To install Git on Windows, you need to [download the installable package](https://git-scm.com/download/win). + + + For Debian/Ubuntu, you can use the following command: -To install Git on Windows, you need to [download the installable package](https://git-scm.com/download/win). + ```bash + apt-get install git + ``` - - + As for other Linux distributions, please check [git’s guide](https://git-scm.com/download/linux). + + + You should already have Git installed as part of the Xcode command-line tools. -For Debian/Ubuntu, you can use the following command: + However, if for any reason you need to install it manually, you can install it with Homebrew: -```bash -apt-get install git -``` + ```bash + brew install git + ``` -As for other Linux distributions, please check [git’s guide](https://git-scm.com/download/linux). - - - - -You should already have Git installed as part of the Xcode command-line tools. - -However, if for any reason you need to install it manually, you can install it with Homebrew: - -```bash -brew install git -``` - -You can also check out [git’s guide](https://git-scm.com/download/mac) for more installation options. - - + You can also check out [git’s guide](https://git-scm.com/download/mac) for more installation options. + ## PostgreSQL @@ -122,32 +104,26 @@ You can also check out [git’s guide](https://git-scm.com/download/mac) for mor The Medusa backend uses PostgreSQL to store data of your commerce system. - + + You can [download the PostgreSQL Windows installer](https://www.postgresql.org/download/windows/) from their website. + + + If you’re using Ubuntu, you can use the following commands to download and install PostgreSQL: -You can [download the PostgreSQL Windows installer](https://www.postgresql.org/download/windows/) from their website. + ```bash + sudo sh -c \ + 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' + wget --quiet -O - \ + https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - + sudo apt-get update + sudo apt-get -y install postgresql + ``` - - - -If you’re using Ubuntu, you can use the following commands to download and install PostgreSQL: - -```bash -sudo sh -c \ - 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' -wget --quiet -O - \ - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - -sudo apt-get update -sudo apt-get -y install postgresql -``` - -For other distributions, you can check out [PostgreSQL’s website for more guides](https://www.postgresql.org/download/linux/). - - - - -You can download PostgreSQL on your macOS using [the installer on their website](https://www.postgresql.org/download/macosx/). - - + For other distributions, you can check out [PostgreSQL’s website for more guides](https://www.postgresql.org/download/linux/). + + + You can download PostgreSQL on your macOS using [the installer on their website](https://www.postgresql.org/download/macosx/). + ## (Optional) Medusa CLI diff --git a/www/apps/docs/content/development/batch-jobs/create.mdx b/www/apps/docs/content/development/batch-jobs/create.mdx index 20574693b1..c32e682c9a 100644 --- a/www/apps/docs/content/development/batch-jobs/create.mdx +++ b/www/apps/docs/content/development/batch-jobs/create.mdx @@ -293,54 +293,54 @@ The first step is to create a batch job using the [Create Batch Job API Route](h For example, this creates a batch job of the type `publish-products`: - + -```jsx -medusa.admin.batchJobs.create({ - type: "publish-products", - context: { }, - dry_run: true, -}) -.then(( batch_job ) => { - console.log(batch_job.status) -}) -``` + ```jsx + medusa.admin.batchJobs.create({ + type: "publish-products", + context: { }, + dry_run: true, + }) + .then(( batch_job ) => { + console.log(batch_job.status) + }) + ``` - - + + -```jsx -fetch(`/admin/batch-jobs`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - type: "publish-products", - context: { }, - dry_run: true, - }), -}) -.then((response) => response.json()) -.then(({ batch_job }) => { - console.log(batch_job.status) -}) -``` + ```jsx + fetch(`/admin/batch-jobs`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + type: "publish-products", + context: { }, + dry_run: true, + }), + }) + .then((response) => response.json()) + .then(({ batch_job }) => { + console.log(batch_job.status) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/batch-jobs' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "type": "publish-products", - "context": { }, - "dry_run": true -}' -``` + ```bash + curl -L -X POST '/admin/batch-jobs' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "type": "publish-products", + "context": { }, + "dry_run": true + }' + ``` @@ -354,38 +354,38 @@ Make sure to replace `` with the backend URL where applicable. You can retrieve the batch job afterward to get its status and view details about the process in the `result` property: - + -```jsx -medusa.admin.batchJobs.retrieve(batchJobId) -.then(( batch_job ) => { - console.log(batch_job.status, batch_job.result) -}) -``` + ```jsx + medusa.admin.batchJobs.retrieve(batchJobId) + .then(( batch_job ) => { + console.log(batch_job.status, batch_job.result) + }) + ``` - - + + -```jsx -fetch(`/admin/batch-jobs/${batchJobId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ batch_job }) => { - console.log(batch_job.status, batch_job.result) -}) -``` + ```jsx + fetch(`/admin/batch-jobs/${batchJobId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ batch_job }) => { + console.log(batch_job.status, batch_job.result) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/batch-jobs/' \ --H 'Authorization: Bearer ' -# is the ID of the batch job -``` + ```bash + curl -L -X GET '/admin/batch-jobs/' \ + -H 'Authorization: Bearer ' + # is the ID of the batch job + ``` - + Based on the batch job strategy implemented in this documentation, the `result` property could be something like this: @@ -409,39 +409,39 @@ Based on the batch job strategy implemented in this documentation, the `result` To process the batch job, send a request to [confirm the batch job](https://docs.medusajs.com/api/admin#batch-jobs_postbatchjobsbatchjobconfirmprocessing): - + -```jsx -medusa.admin.batchJobs.confirm(batchJobId) -.then(( batch_job ) => { - console.log(batch_job.status) -}) -``` + ```jsx + medusa.admin.batchJobs.confirm(batchJobId) + .then(( batch_job ) => { + console.log(batch_job.status) + }) + ``` - - + + -```jsx -fetch(`/admin/batch-jobs/${batchJobId}/confirm`, { - method: "POST", - credentials: "include", -}) -.then((response) => response.json()) -.then(({ batch_job }) => { - console.log(batch_job.status) -}) -``` + ```jsx + fetch(`/admin/batch-jobs/${batchJobId}/confirm`, { + method: "POST", + credentials: "include", + }) + .then((response) => response.json()) + .then(({ batch_job }) => { + console.log(batch_job.status) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/batch-jobs//confirm' \ --H 'Authorization: Bearer ' -# is the ID of the batch job -``` + ```bash + curl -L -X POST '/admin/batch-jobs//confirm' \ + -H 'Authorization: Bearer ' + # is the ID of the batch job + ``` - + The batch job will start processing afterward. Based on the batch job strategy implemented in this documentation, draft products will be published. diff --git a/www/apps/docs/content/development/entities/create.mdx b/www/apps/docs/content/development/entities/create.mdx index fc4f1c1dad..c80030d9fc 100644 --- a/www/apps/docs/content/development/entities/create.mdx +++ b/www/apps/docs/content/development/entities/create.mdx @@ -70,71 +70,71 @@ Your entity may be related to another entity. You can showcase the relation with For example, you can create another entity `Author` and add a `ManyToOne` relation to it from the `Post`, and a `OneToMany` relation from the `Author` to the `Post`: - + -```ts -import { - BeforeInsert, - Column, - Entity, - JoinColumn, - ManyToOne, -} from "typeorm" -import { BaseEntity } from "@medusajs/medusa" -import { generateEntityId } from "@medusajs/medusa/dist/utils" -import { Author } from "./author" + ```ts + import { + BeforeInsert, + Column, + Entity, + JoinColumn, + ManyToOne, + } from "typeorm" + import { BaseEntity } from "@medusajs/medusa" + import { generateEntityId } from "@medusajs/medusa/dist/utils" + import { Author } from "./author" -@Entity() -export class Post extends BaseEntity { - @Column({ type: "varchar" }) - title: string | null + @Entity() + export class Post extends BaseEntity { + @Column({ type: "varchar" }) + title: string | null - @Column({ type: "varchar" }) - author_id: string + @Column({ type: "varchar" }) + author_id: string - @ManyToOne(() => Author, (author) => author.posts) - @JoinColumn({ name: "author_id" }) - author: Author + @ManyToOne(() => Author, (author) => author.posts) + @JoinColumn({ name: "author_id" }) + author: Author - @BeforeInsert() - private beforeInsert(): void { - this.id = generateEntityId(this.id, "post") - } -} -``` + @BeforeInsert() + private beforeInsert(): void { + this.id = generateEntityId(this.id, "post") + } + } + ``` - - + + -```ts -import { BaseEntity, generateEntityId } from "@medusajs/medusa" -import { - BeforeInsert, - Column, - Entity, - OneToMany, -} from "typeorm" -import { Post } from "./post" + ```ts + import { BaseEntity, generateEntityId } from "@medusajs/medusa" + import { + BeforeInsert, + Column, + Entity, + OneToMany, + } from "typeorm" + import { Post } from "./post" -@Entity() -export class Author extends BaseEntity { - @Column({ type: "varchar" }) - name: string + @Entity() + export class Author extends BaseEntity { + @Column({ type: "varchar" }) + name: string - @Column({ type: "varchar", nullable: true }) - image?: string + @Column({ type: "varchar", nullable: true }) + image?: string - @OneToMany(() => Post, (post) => post.author) - posts: Post[] + @OneToMany(() => Post, (post) => post.author) + posts: Post[] - @BeforeInsert() - private beforeInsert(): void { - this.id = generateEntityId(this.id, "auth") - } -} -``` + @BeforeInsert() + private beforeInsert(): void { + this.id = generateEntityId(this.id, "auth") + } + } + ``` - + Adding these relations allows you to later on expand these relations when retrieving records of this entity with repositories. diff --git a/www/apps/docs/content/development/plugins/create.mdx b/www/apps/docs/content/development/plugins/create.mdx index bd4a7fa402..d0283ffe52 100644 --- a/www/apps/docs/content/development/plugins/create.mdx +++ b/www/apps/docs/content/development/plugins/create.mdx @@ -417,24 +417,21 @@ While you develop your plugin, you’ll need to test it on an actual Medusa back + In the root of your plugin directory, run the `build` command: - In the root of your plugin directory, run the `build` command: - - ```bash - npm run build - ``` + ```bash + npm run build + ``` + In the root of your plugin directory, run the `prepare` command: - In the root of your plugin directory, run the `prepare` command: - - ```bash - npm run prepare - ``` - - If the `prepare` script is not available in your project, you can find it in [this section](#changes-for-admin-plugins). + ```bash + npm run prepare + ``` + If the `prepare` script is not available in your project, you can find it in [this section](#changes-for-admin-plugins). @@ -499,30 +496,30 @@ In the directory of the Medusa backend, start the backend with the `dev` command - ```bash - npm run dev -- -- --preserve-symlinks - ``` + ```bash + npm run dev -- -- --preserve-symlinks + ``` - ```bash - yarn dev -- -- --preserve-symlinks - ``` + ```bash + yarn dev -- -- --preserve-symlinks + ``` - ```bash - yarn dev -- --preserve-symlinks - ``` + ```bash + yarn dev -- --preserve-symlinks + ``` - ```bash - pnpm run dev -- -- --preserve-symlinks - ``` + ```bash + pnpm run dev -- -- --preserve-symlinks + ``` diff --git a/www/apps/docs/content/development/plugins/publish.mdx b/www/apps/docs/content/development/plugins/publish.mdx index 59b760eaac..50dbfce9ce 100644 --- a/www/apps/docs/content/development/plugins/publish.mdx +++ b/www/apps/docs/content/development/plugins/publish.mdx @@ -45,40 +45,36 @@ Before publishing your plugin, make sure you've set the following fields in your + Make sure you add the `publish` script to your `scripts` field: - Make sure you add the `publish` script to your `scripts` field: + ```json title=package.json + "scripts": { + // other scripts... + "build": "cross-env npm run clean && tsc -p tsconfig.json", + "prepare": "cross-env NODE_ENV=production npm run build" + } + ``` - ```json title=package.json - "scripts": { - // other scripts... - "build": "cross-env npm run clean && tsc -p tsconfig.json", - "prepare": "cross-env NODE_ENV=production npm run build" - } - ``` - - The `build` script ensures that the plugin's built files are placed as explained in the [plugin structure](./create.mdx#plugin-structure) section of the Create Plugin documentation. - - The `prepare` script facilitates your publishing process. You would typically run this script before publishing your plugin. + The `build` script ensures that the plugin's built files are placed as explained in the [plugin structure](./create.mdx#plugin-structure) section of the Create Plugin documentation. + The `prepare` script facilitates your publishing process. You would typically run this script before publishing your plugin. + First, make sure to change `tsconfig` files as recommended in the [create guide](./create.mdx#changes-for-admin-plugins). - First, make sure to change `tsconfig` files as recommended in the [create guide](./create.mdx#changes-for-admin-plugins). + Then, add the following `prepare` and `build` scripts to your `scripts` - Then, add the following `prepare` and `build` scripts to your `scripts` - - ```json title=package.json - "scripts": { - // other scripts... - "build:server": "cross-env npm run clean && tsc -p tsconfig.json", - "prepare": "cross-env NODE_ENV=production npm run build:server && medusa-admin bundle" - } - ``` - - The `build:server` script builds the resources of the backend for development and ensures they are placed as explained in the [plugin structure](./create.mdx#plugin-structure) section of the Create Plugin documentation. - - The `prepare` script creates a production build of both backend and admin resources. + ```json title=package.json + "scripts": { + // other scripts... + "build:server": "cross-env npm run clean && tsc -p tsconfig.json", + "prepare": "cross-env NODE_ENV=production npm run build:server && medusa-admin bundle" + } + ``` + The `build:server` script builds the resources of the backend for development and ensures they are placed as explained in the [plugin structure](./create.mdx#plugin-structure) section of the Create Plugin documentation. + + The `prepare` script creates a production build of both backend and admin resources. diff --git a/www/apps/docs/content/development/publishable-api-keys/admin/manage-publishable-api-keys.mdx b/www/apps/docs/content/development/publishable-api-keys/admin/manage-publishable-api-keys.mdx index cf9b9e59d7..08bed97415 100644 --- a/www/apps/docs/content/development/publishable-api-keys/admin/manage-publishable-api-keys.mdx +++ b/www/apps/docs/content/development/publishable-api-keys/admin/manage-publishable-api-keys.mdx @@ -64,73 +64,73 @@ You can learn more about [authenticating as an admin user in the API reference]( You can retrieve a list of publishable API keys by sending a request to the [List Publishable API Keys route](https://docs.medusajs.com/api/admin#publishable-api-keys_getpublishableapikeys): - + -```ts -medusa.admin.publishableApiKeys.list() -.then(({ publishable_api_keys, count, limit, offset }) => { - console.log(publishable_api_keys) -}) -``` + ```ts + medusa.admin.publishableApiKeys.list() + .then(({ publishable_api_keys, count, limit, offset }) => { + console.log(publishable_api_keys) + }) + ``` - - + + -```tsx -import { PublishableApiKey } from "@medusajs/medusa" -import { useAdminPublishableApiKeys } from "medusa-react" + ```tsx + import { PublishableApiKey } from "@medusajs/medusa" + import { useAdminPublishableApiKeys } from "medusa-react" -const PublishabelApiKeys = () => { - const { publishable_api_keys, isLoading } = - useAdminPublishableApiKeys() + const PublishabelApiKeys = () => { + const { publishable_api_keys, isLoading } = + useAdminPublishableApiKeys() - return ( -
- {isLoading && Loading...} - {publishable_api_keys && !publishable_api_keys.length && ( - No Publishable API Keys - )} - {publishable_api_keys && - publishable_api_keys.length > 0 && ( -
    - {publishable_api_keys.map( - (publishableApiKey: PublishableApiKey) => ( -
  • - {publishableApiKey.title} -
  • - ) + return ( +
    + {isLoading && Loading...} + {publishable_api_keys && !publishable_api_keys.length && ( + No Publishable API Keys )} -
- )} -
- ) -} + {publishable_api_keys && + publishable_api_keys.length > 0 && ( +
    + {publishable_api_keys.map( + (publishableApiKey: PublishableApiKey) => ( +
  • + {publishableApiKey.title} +
  • + ) + )} +
+ )} + + ) + } -export default PublishabelApiKeys -``` + export default PublishabelApiKeys + ``` -
- + + -```ts -fetch(`/admin/publishable-api-keys`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ publishable_api_keys, count, limit, offset }) => { - console.log(publishable_api_keys) -}) -``` + ```ts + fetch(`/admin/publishable-api-keys`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ publishable_api_keys, count, limit, offset }) => { + console.log(publishable_api_keys) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/publishable-api-keys' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/publishable-api-keys' \ + -H 'Authorization: Bearer ' + ``` - +
This request does not require any path parameters. You can pass it optional query parameters related to expanding fields and pagination, which you can check out in the [API reference](https://docs.medusajs.com/api/admin#publishable-api-keys_getpublishableapikeys). @@ -155,72 +155,72 @@ You can learn more about pagination in the [API reference](https://docs.medusajs You can create a publishable API key by sending a request to the [Create Publishable API Key route](https://docs.medusajs.com/api/admin#publishable-api-keys_postpublishableapikeys): - + -```ts -medusa.admin.publishableApiKeys.create({ - title: "Web API Key", -}) -.then(({ publishable_api_key }) => { - console.log(publishable_api_key.id) -}) -``` - - - - -```tsx -import { useAdminCreatePublishableApiKey } from "medusa-react" - -const CreatePublishableApiKey = () => { - const createKey = useAdminCreatePublishableApiKey() - // ... - - const handleCreate = (title: string) => { - createKey.mutate({ - title, + ```ts + medusa.admin.publishableApiKeys.create({ + title: "Web API Key", }) - } + .then(({ publishable_api_key }) => { + console.log(publishable_api_key.id) + }) + ``` - // ... -} + + -export default CreatePublishableApiKey -``` + ```tsx + import { useAdminCreatePublishableApiKey } from "medusa-react" - - + const CreatePublishableApiKey = () => { + const createKey = useAdminCreatePublishableApiKey() + // ... -```ts -fetch(`/admin/publishable-api-keys`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - title: "Web API Key", - }), -}) -.then((response) => response.json()) -.then(({ publishable_api_key }) => { - console.log(publishable_api_key.id) -}) -``` + const handleCreate = (title: string) => { + createKey.mutate({ + title, + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/publishable-api-keys' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "title": "Web API Key" -}' -``` + export default CreatePublishableApiKey + ``` - + + + + ```ts + fetch(`/admin/publishable-api-keys`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + title: "Web API Key", + }), + }) + .then((response) => response.json()) + .then(({ publishable_api_key }) => { + console.log(publishable_api_key.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/publishable-api-keys' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "title": "Web API Key" + }' + ``` + + This request requires a body parameter `title`, which is the title of the Publishable API Key. @@ -234,76 +234,76 @@ It returns the created publishable API key in the response. You can update a publishable API key’s details by sending a request to the [Update Publishable API Key route](https://docs.medusajs.com/api/admin#publishable-api-keys_postpublishableapikyspublishableapikey): - + -```ts -medusa.admin.publishableApiKeys.update(publishableApiKeyId, { - title: "Web API Key", -}) -.then(({ publishable_api_key }) => { - console.log(publishable_api_key.id) -}) -``` - - - - -```tsx -import { useAdminUpdatePublishableApiKey } from "medusa-react" - -const UpdatePublishableApiKey = () => { - const updateKey = useAdminUpdatePublishableApiKey( - publishableApiKeyId - ) - // ... - - const handleUpdate = (title: string) => { - updateKey.mutate({ - title, + ```ts + medusa.admin.publishableApiKeys.update(publishableApiKeyId, { + title: "Web API Key", }) - } + .then(({ publishable_api_key }) => { + console.log(publishable_api_key.id) + }) + ``` - // ... -} + + -export default UpdatePublishableApiKey -``` + ```tsx + import { useAdminUpdatePublishableApiKey } from "medusa-react" - - + const UpdatePublishableApiKey = () => { + const updateKey = useAdminUpdatePublishableApiKey( + publishableApiKeyId + ) + // ... + + const handleUpdate = (title: string) => { + updateKey.mutate({ + title, + }) + } + + // ... + } + + export default UpdatePublishableApiKey + ``` + + + -```ts -fetch(`/admin/publishable-api-keys/${publishableApiKeyId}`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - title: "Web API Key", - }), -}) -.then((response) => response.json()) -.then(({ publishable_api_key }) => { - console.log(publishable_api_key.id) -}) -``` + ```ts + fetch(`/admin/publishable-api-keys/${publishableApiKeyId}`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + title: "Web API Key", + }), + }) + .then((response) => response.json()) + .then(({ publishable_api_key }) => { + console.log(publishable_api_key.id) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/publishable-api-keys/' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "title": "Web API Key" -}' -``` + ```bash + curl -L -X POST '/admin/publishable-api-keys/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "title": "Web API Key" + }' + ``` - + This request requires the ID of the publishable API key as a path parameter. In its body, it optionally accepts the new `title` of the publishable API key. @@ -319,65 +319,65 @@ Revoking a publishable API key does not remove it, but does not allow using it i You can revoke a publishable API key by sending a request to the [Revoke Publishable API Key route](https://docs.medusajs.com/api/admin#publishable-api-keys_postpublishableapikeyspublishableapikeyrevoke): - + -```ts -medusa.admin.publishableApiKeys.revoke(publishableApiKeyId) -.then(({ publishable_api_key }) => { - console.log(publishable_api_key.id) -}) -``` + ```ts + medusa.admin.publishableApiKeys.revoke(publishableApiKeyId) + .then(({ publishable_api_key }) => { + console.log(publishable_api_key.id) + }) + ``` - - + + -```tsx -import { useAdminRevokePublishableApiKey } from "medusa-react" + ```tsx + import { useAdminRevokePublishableApiKey } from "medusa-react" -const PublishableApiKey = () => { - const revokeKey = useAdminRevokePublishableApiKey( - publishableApiKeyId - ) - // ... + const PublishableApiKey = () => { + const revokeKey = useAdminRevokePublishableApiKey( + publishableApiKeyId + ) + // ... - const handleRevoke = () => { - revokeKey.mutate() - } + const handleRevoke = () => { + revokeKey.mutate() + } - // ... -} + // ... + } -export default PublishableApiKey -``` + export default PublishableApiKey + ``` - - + + -```ts -fetch( - `/admin/publishable-api-keys/${publishableApiKeyId}/revoke`, - { - method: "POST", - credentials: "include", - } -) -.then((response) => response.json()) -.then(({ publishable_api_key }) => { - console.log(publishable_api_key.id) -}) -``` + ```ts + fetch( + `/admin/publishable-api-keys/${publishableApiKeyId}/revoke`, + { + method: "POST", + credentials: "include", + } + ) + .then((response) => response.json()) + .then(({ publishable_api_key }) => { + console.log(publishable_api_key.id) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/publishable-api-keys//revoke' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X POST '/admin/publishable-api-keys//revoke' \ + -H 'Authorization: Bearer ' + ``` - + This request requires the ID of the publishable API key as a path parameter. It returns the updated publishable API key in the response. @@ -389,62 +389,62 @@ This request requires the ID of the publishable API key as a path parameter. It You can delete a publishable API key by sending a request to the [Delete Publishable API Key route](https://docs.medusajs.com/api/admin#publishable-api-keys_deletepublishableapikeyspublishableapikey): - + -```ts -medusa.admin.publishableApiKeys.delete(publishableApiKeyId) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + medusa.admin.publishableApiKeys.delete(publishableApiKeyId) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```tsx -import { useAdminDeletePublishableApiKey } from "medusa-react" + ```tsx + import { useAdminDeletePublishableApiKey } from "medusa-react" -const PublishableApiKey = () => { - const deleteKey = useAdminDeletePublishableApiKey( - publishableApiKeyId - ) - // ... + const PublishableApiKey = () => { + const deleteKey = useAdminDeletePublishableApiKey( + publishableApiKeyId + ) + // ... - const handleDelete = () => { - deleteKey.mutate() - } + const handleDelete = () => { + deleteKey.mutate() + } - // ... -} + // ... + } -export default PublishableApiKey -``` + export default PublishableApiKey + ``` - - + + -```ts -fetch(`/admin/publishable-api-keys/${publishableApiKeyId}`, { - method: "DELETE", - credentials: "include", -}) -.then((response) => response.json()) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + fetch(`/admin/publishable-api-keys/${publishableApiKeyId}`, { + method: "DELETE", + credentials: "include", + }) + .then((response) => response.json()) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/publishable-api-keys/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/publishable-api-keys/' \ + -H 'Authorization: Bearer ' + ``` - + This request requires the ID of the publishable API key as a path parameter. @@ -466,78 +466,78 @@ This section covers how to manage sales channels in a publishable API key. This You can retrieve the list of sales channels associated with a publishable API key by sending a request to the [List Sales Channels API Route](https://docs.medusajs.com/api/admin#sales-channels_getsaleschannels): - + -```ts -medusa.admin.publishableApiKeys - .listSalesChannels(publishableApiKeyId) -.then(({ sales_channels }) => { - console.log(sales_channels) -}) -``` + ```ts + medusa.admin.publishableApiKeys + .listSalesChannels(publishableApiKeyId) + .then(({ sales_channels }) => { + console.log(sales_channels) + }) + ``` - - + + -```tsx -import { SalesChannel } from "@medusajs/medusa" -import { - useAdminPublishableApiKeySalesChannels, -} from "medusa-react" + ```tsx + import { SalesChannel } from "@medusajs/medusa" + import { + useAdminPublishableApiKeySalesChannels, + } from "medusa-react" -const SalesChannels = () => { - const { sales_channels, isLoading } = - useAdminPublishableApiKeySalesChannels( - publishableApiKeyId - ) + const SalesChannels = () => { + const { sales_channels, isLoading } = + useAdminPublishableApiKeySalesChannels( + publishableApiKeyId + ) - return ( -
- {isLoading && Loading...} - {sales_channels && !sales_channels.length && ( - No Sales Channels - )} - {sales_channels && sales_channels.length > 0 && ( -
    - {sales_channels.map((salesChannel: SalesChannel) => ( -
  • {salesChannel.name}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {sales_channels && !sales_channels.length && ( + No Sales Channels + )} + {sales_channels && sales_channels.length > 0 && ( +
    + {sales_channels.map((salesChannel: SalesChannel) => ( +
  • {salesChannel.name}
  • + ))} +
+ )} +
+ ) + } -export default SalesChannels -``` + export default SalesChannels + ``` -
- + + -```ts -fetch( - `/admin/publishable-api-keys/${publishableApiKeyId}/sales-channels`, - { - credentials: "include", - } -) -.then((response) => response.json()) -.then(({ sales_channels }) => { - console.log(sales_channels) -}) -``` + ```ts + fetch( + `/admin/publishable-api-keys/${publishableApiKeyId}/sales-channels`, + { + credentials: "include", + } + ) + .then((response) => response.json()) + .then(({ sales_channels }) => { + console.log(sales_channels) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/publishable-api-keys//sales-channels' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/publishable-api-keys//sales-channels' \ + -H 'Authorization: Bearer ' + ``` - +
This request requires the ID of the publishable API key as a path parameter. @@ -549,101 +549,101 @@ It returns an array of sales channels associated with the publishable API key in You can add a sales channel to a publishable API key by sending a request to the [Add Sales Channels API Route](https://docs.medusajs.com/api/admin#publishable-api-keys_postpublishableapikeysaleschannelschannelsbatch): - + -```ts -medusa.admin.publishableApiKeys.addSalesChannelsBatch( - publishableApiKeyId, - { - sales_channel_ids: [ + ```ts + medusa.admin.publishableApiKeys.addSalesChannelsBatch( + publishableApiKeyId, { - id: salesChannelId, - }, - ], - } -) -.then(({ publishable_api_key }) => { - console.log(publishable_api_key.id) -}) -``` - - - - -```tsx -import { - useAdminAddPublishableKeySalesChannelsBatch, -} from "medusa-react" - -const PublishableApiKey = () => { - const addSalesChannels = - useAdminAddPublishableKeySalesChannelsBatch( - publishableApiKeyId + sales_channel_ids: [ + { + id: salesChannelId, + }, + ], + } ) - // ... - - const handleAdd = (salesChannelId: string) => { - addSalesChannels.mutate({ - sales_channel_ids: [ - { - id: salesChannelId, - }, - ], + .then(({ publishable_api_key }) => { + console.log(publishable_api_key.id) }) - } + ``` - // ... -} + + -export default PublishableApiKey -``` + ```tsx + import { + useAdminAddPublishableKeySalesChannelsBatch, + } from "medusa-react" - - + const PublishableApiKey = () => { + const addSalesChannels = + useAdminAddPublishableKeySalesChannelsBatch( + publishableApiKeyId + ) + // ... + + const handleAdd = (salesChannelId: string) => { + addSalesChannels.mutate({ + sales_channel_ids: [ + { + id: salesChannelId, + }, + ], + }) + } + + // ... + } + + export default PublishableApiKey + ``` + + + -```ts -fetch( - `/admin/publishable-api-keys/${publishableApiKeyId}/sales-channels/batch`, - { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - sales_channel_ids: [ - { - id: salesChannelId, - }, - ], - }), - } -) -.then((response) => response.json()) -.then(({ publishable_api_key }) => { - console.log(publishable_api_key.id) -}) -``` - - - - -```bash -curl -L -X POST '/admin/publishable-api-keys//sales-channels/batch' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "sales_channel_ids": [ + ```ts + fetch( + `/admin/publishable-api-keys/${publishableApiKeyId}/sales-channels/batch`, { - "id": "" + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + sales_channel_ids: [ + { + id: salesChannelId, + }, + ], + }), } - ] -}' -``` + ) + .then((response) => response.json()) + .then(({ publishable_api_key }) => { + console.log(publishable_api_key.id) + }) + ``` - + + + + ```bash + curl -L -X POST '/admin/publishable-api-keys//sales-channels/batch' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "sales_channel_ids": [ + { + "id": "" + } + ] + }' + ``` + + This request requires passing the ID of the publishable API key as a path parameter. @@ -659,101 +659,101 @@ This request returns the updated publishable API key in the response. You can delete a sales channel from a publishable API key by sending a request to the [Delete Sales Channels API Route](https://docs.medusajs.com/api/admin#publishable-api-keys_deletepublishableapikeysaleschannelschannelsbatch): - + -```ts -medusa.admin.publishableApiKeys.deleteSalesChannelsBatch( - publishableApiKeyId, - { - sales_channel_ids: [ + ```ts + medusa.admin.publishableApiKeys.deleteSalesChannelsBatch( + publishableApiKeyId, { - id: salesChannelId, - }, - ], - } -) -.then(({ publishable_api_key }) => { - console.log(publishable_api_key.id) -}) -``` - - - - -```tsx -import { - useAdminRemovePublishableKeySalesChannelsBatch, -} from "medusa-react" - -const PublishableApiKey = () => { - const deleteSalesChannels = - useAdminRemovePublishableKeySalesChannelsBatch( - publishableApiKeyId + sales_channel_ids: [ + { + id: salesChannelId, + }, + ], + } ) - // ... - - const handleDelete = (salesChannelId: string) => { - deleteSalesChannels.mutate({ - sales_channel_ids: [ - { - id: salesChannelId, - }, - ], + .then(({ publishable_api_key }) => { + console.log(publishable_api_key.id) }) - } + ``` - // ... -} + + -export default PublishableApiKey -``` + ```tsx + import { + useAdminRemovePublishableKeySalesChannelsBatch, + } from "medusa-react" - - + const PublishableApiKey = () => { + const deleteSalesChannels = + useAdminRemovePublishableKeySalesChannelsBatch( + publishableApiKeyId + ) + // ... + + const handleDelete = (salesChannelId: string) => { + deleteSalesChannels.mutate({ + sales_channel_ids: [ + { + id: salesChannelId, + }, + ], + }) + } + + // ... + } + + export default PublishableApiKey + ``` + + + -```ts -fetch( - `/admin/publishable-api-keys/${publishableApiKeyId}/sales-channels/batch`, - { - method: "DELETE", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - sales_channel_ids: [ - { - id: salesChannelId, - }, - ], - }), - } -) -.then((response) => response.json()) -.then(({ publishable_api_key }) => { - console.log(publishable_api_key.id) -}) -``` - - - - -```bash -curl -L -X DELETE '/admin/publishable-api-keys//sales-channels/batch' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "sales_channel_ids": [ + ```ts + fetch( + `/admin/publishable-api-keys/${publishableApiKeyId}/sales-channels/batch`, { - "id": "" + method: "DELETE", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + sales_channel_ids: [ + { + id: salesChannelId, + }, + ], + }), } - ] -}' -``` + ) + .then((response) => response.json()) + .then(({ publishable_api_key }) => { + console.log(publishable_api_key.id) + }) + ``` - + + + + ```bash + curl -L -X DELETE '/admin/publishable-api-keys//sales-channels/batch' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "sales_channel_ids": [ + { + "id": "" + } + ] + }' + ``` + + This request requires the ID of the publishable API key as a path parameter. diff --git a/www/apps/docs/content/development/services/create-service.mdx b/www/apps/docs/content/development/services/create-service.mdx index 4b23dd24e8..2ae0862197 100644 --- a/www/apps/docs/content/development/services/create-service.mdx +++ b/www/apps/docs/content/development/services/create-service.mdx @@ -424,249 +424,249 @@ In this section, you'll find a full example of the `PostService` and `AuthorServ You can refer to the [Entities](../entities/create.mdx#adding-relations) documentation to learn how to create the custom entities used in this example. - + -```ts -import { - FindConfig, - Selector, - TransactionBaseService, - buildQuery, -} from "@medusajs/medusa" -import { PostRepository } from "../repositories/post" -import { Post } from "../models/post" -import { MedusaError } from "@medusajs/utils" + ```ts + import { + FindConfig, + Selector, + TransactionBaseService, + buildQuery, + } from "@medusajs/medusa" + import { PostRepository } from "../repositories/post" + import { Post } from "../models/post" + import { MedusaError } from "@medusajs/utils" -class PostService extends TransactionBaseService { - protected postRepository_: typeof PostRepository + class PostService extends TransactionBaseService { + protected postRepository_: typeof PostRepository - constructor(container) { - super(container) - this.postRepository_ = container.postRepository - } + constructor(container) { + super(container) + this.postRepository_ = container.postRepository + } - async listAndCount( - selector?: Selector, - config: FindConfig = { - skip: 0, - take: 20, - relations: [], - }): Promise<[Post[], number]> { - const postRepo = this.activeManager_.withRepository( - this.postRepository_ - ) + async listAndCount( + selector?: Selector, + config: FindConfig = { + skip: 0, + take: 20, + relations: [], + }): Promise<[Post[], number]> { + const postRepo = this.activeManager_.withRepository( + this.postRepository_ + ) - const query = buildQuery(selector, config) + const query = buildQuery(selector, config) - return postRepo.findAndCount(query) - } - - async list( - selector?: Selector, - config: FindConfig = { - skip: 0, - take: 20, - relations: [], - }): Promise { - const [posts] = await this.listAndCount(selector, config) + return postRepo.findAndCount(query) + } + + async list( + selector?: Selector, + config: FindConfig = { + skip: 0, + take: 20, + relations: [], + }): Promise { + const [posts] = await this.listAndCount(selector, config) - return posts - } + return posts + } - async retrieve( - id: string, - config?: FindConfig - ): Promise { - const postRepo = this.activeManager_.withRepository( - this.postRepository_ - ) + async retrieve( + id: string, + config?: FindConfig + ): Promise { + const postRepo = this.activeManager_.withRepository( + this.postRepository_ + ) - const query = buildQuery({ - id, - }, config) + const query = buildQuery({ + id, + }, config) - const post = await postRepo.findOne(query) + const post = await postRepo.findOne(query) - if (!post) { - throw new MedusaError( - MedusaError.Types.NOT_FOUND, - "Post was not found" - ) + if (!post) { + throw new MedusaError( + MedusaError.Types.NOT_FOUND, + "Post was not found" + ) + } + + return post + } + + async create( + data: Pick + ): Promise { + return this.atomicPhase_(async (manager) => { + const postRepo = manager.withRepository( + this.postRepository_ + ) + const post = postRepo.create() + post.title = data.title + post.author_id = data.author_id + const result = await postRepo.save(post) + + return result + }) + } + + async update( + id: string, + data: Omit, "id"> + ): Promise { + return await this.atomicPhase_(async (manager) => { + const postRepo = manager.withRepository( + this.postRepository_ + ) + const post = await this.retrieve(id) + + Object.assign(post, data) + + return await postRepo.save(post) + }) + } + + async delete(id: string): Promise { + return await this.atomicPhase_(async (manager) => { + const postRepo = manager.withRepository( + this.postRepository_ + ) + const post = await this.retrieve(id) + + await postRepo.remove([post]) + }) + } } - return post - } + export default PostService + ``` - async create( - data: Pick - ): Promise { - return this.atomicPhase_(async (manager) => { - const postRepo = manager.withRepository( - this.postRepository_ - ) - const post = postRepo.create() - post.title = data.title - post.author_id = data.author_id - const result = await postRepo.save(post) + + - return result - }) - } + ```ts + import { + FindConfig, + Selector, + TransactionBaseService, + buildQuery, + } from "@medusajs/medusa" + import { EntityManager } from "typeorm" + import AuthorRepository from "../repositories/author" + import { Author } from "../models/author" + import { MedusaError } from "@medusajs/utils" - async update( - id: string, - data: Omit, "id"> - ): Promise { - return await this.atomicPhase_(async (manager) => { - const postRepo = manager.withRepository( - this.postRepository_ - ) - const post = await this.retrieve(id) + class AuthorService extends TransactionBaseService { + protected manager_: EntityManager + protected transactionManager_: EntityManager + protected authorRepository_: typeof AuthorRepository - Object.assign(post, data) + constructor(container) { + super(container) + this.authorRepository_ = container.authorRepository + } - return await postRepo.save(post) - }) - } + async listAndCount( + selector?: Selector, + config: FindConfig = { + skip: 0, + take: 20, + relations: [], + }): Promise<[Author[], number]> { + const authorRepo = this.activeManager_.withRepository( + this.authorRepository_ + ) - async delete(id: string): Promise { - return await this.atomicPhase_(async (manager) => { - const postRepo = manager.withRepository( - this.postRepository_ - ) - const post = await this.retrieve(id) + const query = buildQuery(selector, config) + + return authorRepo.findAndCount(query) + } - await postRepo.remove([post]) - }) - } -} + async list( + selector?: Selector, + config: FindConfig = { + skip: 0, + take: 20, + relations: [], + }): Promise { + const [authors] = await this.listAndCount(selector, config) -export default PostService -``` + return authors + } - - + async retrieve( + id: string, + config?: FindConfig + ): Promise { + const authorRepo = this.activeManager_.withRepository( + this.authorRepository_ + ) -```ts -import { - FindConfig, - Selector, - TransactionBaseService, - buildQuery, -} from "@medusajs/medusa" -import { EntityManager } from "typeorm" -import AuthorRepository from "../repositories/author" -import { Author } from "../models/author" -import { MedusaError } from "@medusajs/utils" + const query = buildQuery({ + id, + }, config) -class AuthorService extends TransactionBaseService { - protected manager_: EntityManager - protected transactionManager_: EntityManager - protected authorRepository_: typeof AuthorRepository + const author = await authorRepo.findOne(query) - constructor(container) { - super(container) - this.authorRepository_ = container.authorRepository - } + if (!author) { + throw new MedusaError( + MedusaError.Types.NOT_FOUND, + "Author was not found" + ) + } - async listAndCount( - selector?: Selector, - config: FindConfig = { - skip: 0, - take: 20, - relations: [], - }): Promise<[Author[], number]> { - const authorRepo = this.activeManager_.withRepository( - this.authorRepository_ - ) + return + } - const query = buildQuery(selector, config) + async create( + data: Pick + ): Promise { + return this.atomicPhase_(async (manager) => { + const authorRepo = manager.withRepository( + this.authorRepository_ + ) + const post = authorRepo.create(data) + const result = await authorRepo.save(post) - return authorRepo.findAndCount(query) - } - - async list( - selector?: Selector, - config: FindConfig = { - skip: 0, - take: 20, - relations: [], - }): Promise { - const [authors] = await this.listAndCount(selector, config) + return result + }) + } - return authors - } + async update( + id: string, + data: Omit, "id"> + ): Promise { + return await this.atomicPhase_(async (manager) => { + const authorRepo = manager.withRepository( + this.authorRepository_ + ) + const post = await this.retrieve(id) + + Object.assign(post, data) - async retrieve( - id: string, - config?: FindConfig - ): Promise { - const authorRepo = this.activeManager_.withRepository( - this.authorRepository_ - ) + return await authorRepo.save(post) + }) + } - const query = buildQuery({ - id, - }, config) - - const author = await authorRepo.findOne(query) - - if (!author) { - throw new MedusaError( - MedusaError.Types.NOT_FOUND, - "Author was not found" - ) + async delete(id: string): Promise { + return await this.atomicPhase_(async (manager) => { + const authorRepo = manager.withRepository( + this.authorRepository_ + ) + const post = await this.retrieve(id) + + await authorRepo.remove([post]) + }) + } } - return - } + export default AuthorService + ``` - async create( - data: Pick - ): Promise { - return this.atomicPhase_(async (manager) => { - const authorRepo = manager.withRepository( - this.authorRepository_ - ) - const post = authorRepo.create(data) - const result = await authorRepo.save(post) - - return result - }) - } - - async update( - id: string, - data: Omit, "id"> - ): Promise { - return await this.atomicPhase_(async (manager) => { - const authorRepo = manager.withRepository( - this.authorRepository_ - ) - const post = await this.retrieve(id) - - Object.assign(post, data) - - return await authorRepo.save(post) - }) - } - - async delete(id: string): Promise { - return await this.atomicPhase_(async (manager) => { - const authorRepo = manager.withRepository( - this.authorRepository_ - ) - const post = await this.retrieve(id) - - await authorRepo.remove([post]) - }) - } -} - -export default AuthorService -``` - - + --- diff --git a/www/apps/docs/content/js-client/overview.mdx b/www/apps/docs/content/js-client/overview.mdx index 83492a6b2b..1cbaa8254e 100644 --- a/www/apps/docs/content/js-client/overview.mdx +++ b/www/apps/docs/content/js-client/overview.mdx @@ -2,8 +2,8 @@ description: 'Learn how to install the Medusa JS Client in a storefront. Medusa JS Client provides easy access to the Medusa API from a client written in TypeScript.' --- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; +import Tabs from '@theme/Tabs' +import TabItem from '@theme/TabItem' # Medusa JS Client @@ -39,30 +39,28 @@ Where `MEDUSA_BACKEND_URL` is the URL to your Medusa backend. If the `baseUrl` o After initialization, you can use the client's properties and methods to send requests to the Medusa backend. -
- -Troubleshooting: Could not find a declaration file for module '@medusajs/medusa-js' - +
+ Troubleshooting: Could not find a declaration file for module '@medusajs/medusa-js' -If you import `@medusajs/medusa-js` in your code and see the following TypeScript error: + If you import `@medusajs/medusa-js` in your code and see the following TypeScript error: -```bash -Could not find a declaration file for module '@medusajs/medusa-js' -``` + ```bash + Could not find a declaration file for module '@medusajs/medusa-js' + ``` -Make sure to set `moduleResolution` in your `tsconfig.json` to `nodenext` or `node`: + Make sure to set `moduleResolution` in your `tsconfig.json` to `nodenext` or `node`: -```json title=tsconfig.json -{ - "compilerOptions": { - "moduleResolution": "nodenext", + ```json title=tsconfig.json + { + "compilerOptions": { + "moduleResolution": "nodenext", + // ... + }, // ... - }, - // ... -} -``` + } + ``` -
+
## How to Use this Reference @@ -128,38 +126,38 @@ Once the user or customer is authenticated successfully, the Medusa client autom For example: - + -```ts -import Medusa from "@medusajs/medusa-js" -const medusa = new Medusa({ - baseUrl: MEDUSA_BACKEND_URL, - maxRetries: 3, -}) -await medusa.admin.auth.getToken({ - email: "user@example.com", - password: "supersecret", -}) -// send authenticated requests now -``` + ```ts + import Medusa from "@medusajs/medusa-js" + const medusa = new Medusa({ + baseUrl: MEDUSA_BACKEND_URL, + maxRetries: 3, + }) + await medusa.admin.auth.getToken({ + email: "user@example.com", + password: "supersecret", + }) + // send authenticated requests now + ``` - - + + -```ts -import Medusa from "@medusajs/medusa-js" -const medusa = new Medusa({ - baseUrl: MEDUSA_BACKEND_URL, - maxRetries: 3, -}) -await medusa.auth.getToken({ - email: "user@example.com", - password: "supersecret", -}) -// send authenticated requests now -``` + ```ts + import Medusa from "@medusajs/medusa-js" + const medusa = new Medusa({ + baseUrl: MEDUSA_BACKEND_URL, + maxRetries: 3, + }) + await medusa.auth.getToken({ + email: "user@example.com", + password: "supersecret", + }) + // send authenticated requests now + ``` - + ### Cookie Session ID @@ -173,38 +171,38 @@ Once the user or customer is authenticated successfully, the Medusa client sets For example: - + -```ts -import Medusa from "@medusajs/medusa-js" -const medusa = new Medusa({ - baseUrl: MEDUSA_BACKEND_URL, - maxRetries: 3, -}) -await medusa.admin.AdminAuthResource.createSession({ - email: "user@example.com", - password: "supersecret", -}) -// send authenticated requests now -``` + ```ts + import Medusa from "@medusajs/medusa-js" + const medusa = new Medusa({ + baseUrl: MEDUSA_BACKEND_URL, + maxRetries: 3, + }) + await medusa.admin.AdminAuthResource.createSession({ + email: "user@example.com", + password: "supersecret", + }) + // send authenticated requests now + ``` - - + + -```ts -import Medusa from "@medusajs/medusa-js" -const medusa = new Medusa({ - baseUrl: MEDUSA_BACKEND_URL, - maxRetries: 3, -}) -await medusa.auth.authenticate({ - email: "user@example.com", - password: "user@example.com", -}) -// send authenticated requests now -``` + ```ts + import Medusa from "@medusajs/medusa-js" + const medusa = new Medusa({ + baseUrl: MEDUSA_BACKEND_URL, + maxRetries: 3, + }) + await medusa.auth.authenticate({ + email: "user@example.com", + password: "user@example.com", + }) + // send authenticated requests now + ``` - + ### API Key @@ -214,36 +212,36 @@ You can authenticate admin users with a personal API Token. If a user doesn't have a personal API token, create one with the [admin.users.update](../references/js-client/classes/AdminUsersResource.mdx#update) method: - + -```ts -import Medusa from "@medusajs/medusa-js" -const medusa = new Medusa({ - baseUrl: MEDUSA_BACKEND_URL, - maxRetries: 3, -}) -// must be previously logged in or use api token -medusa.admin.users.update(userId, { - api_token, -}) -.then(({ user }) => { - console.log(user.api_token) -}) -``` + ```ts + import Medusa from "@medusajs/medusa-js" + const medusa = new Medusa({ + baseUrl: MEDUSA_BACKEND_URL, + maxRetries: 3, + }) + // must be previously logged in or use api token + medusa.admin.users.update(userId, { + api_token, + }) + .then(({ user }) => { + console.log(user.api_token) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/users/' \\ --H 'Cookie: connect.sid={sid}' \\ --H 'Content-Type: application/json' \\ ---data-raw '{ - "api_token": "{api_token}" -}' -``` + ```bash + curl -L -X POST '/admin/users/' \\ + -H 'Cookie: connect.sid={sid}' \\ + -H 'Content-Type: application/json' \\ + --data-raw '{ + "api_token": "{api_token}" + }' + ``` - + Then, initialize the Medusa client passing it the `apiKey` option: diff --git a/www/apps/docs/content/medusa-react/overview.mdx b/www/apps/docs/content/medusa-react/overview.mdx index cca6839366..22c527f423 100644 --- a/www/apps/docs/content/medusa-react/overview.mdx +++ b/www/apps/docs/content/medusa-react/overview.mdx @@ -235,110 +235,110 @@ The request returns an object containing keys like `data` which is an object tha For example: - + -```tsx -import { useAdminCustomQuery } from "medusa-react" -import { useParams } from "react-router-dom" + ```tsx + import { useAdminCustomQuery } from "medusa-react" + import { useParams } from "react-router-dom" -type BlogPost = { - title: string, - content: string, - author_id: string, -} - -// Single post -type AdminBlogPostQuery = { - expand?: string, - fields?: string -} - -type AdminBlogPostRes = { - post: BlogPost, -} - -const BlogPost = () => { - const { id } = useParams() - - const { data, isLoading } = useAdminCustomQuery< - AdminBlogPostQuery, - AdminBlogPostRes - >( - `/blog/posts/${id}`, // path - ["blog-post", id], // queryKey - { - expand: "author", // query + type BlogPost = { + title: string, + content: string, + author_id: string, } - ) - return ( - <> - {isLoading && Loading...} - {data && data.post && {data.post.title}} - - ) -} - -export default BlogPost -``` - - - - -```tsx -import { useAdminCustomQuery } from "medusa-react" -import { useParams } from "react-router-dom" - -type BlogPost = { - title: string, - content: string, - author_id: string, -} - -type AdminBlogPostsRes = { - posts: BlogPost[], - count: number -} - -type AdminBlogPostsQuery = { - author_id: string, - created_at?: string, - expand?: string, - fields?: string -} - -const AuthorsBlogPosts = () => { - const { id } = useParams() - - const { data, isLoading } = useAdminCustomQuery< - AdminBlogPostsQuery, AdminBlogPostsRes - >( - `/blog/posts`, // path - ["blog-posts", "list", id], // queryKey - { - expand: "author", // query - author_id: "auth_123", + // Single post + type AdminBlogPostQuery = { + expand?: string, + fields?: string } - ) - return ( - <> - {isLoading && Loading...} - {data && data.posts && ( - - {data.posts.map((post, index) => ( - {post.title} - ))} - - )} - - ) -} + type AdminBlogPostRes = { + post: BlogPost, + } -export default AuthorsBlogPosts -``` + const BlogPost = () => { + const { id } = useParams() - + const { data, isLoading } = useAdminCustomQuery< + AdminBlogPostQuery, + AdminBlogPostRes + >( + `/blog/posts/${id}`, // path + ["blog-post", id], // queryKey + { + expand: "author", // query + } + ) + + return ( + <> + {isLoading && Loading...} + {data && data.post && {data.post.title}} + + ) + } + + export default BlogPost + ``` + + + + + ```tsx + import { useAdminCustomQuery } from "medusa-react" + import { useParams } from "react-router-dom" + + type BlogPost = { + title: string, + content: string, + author_id: string, + } + + type AdminBlogPostsRes = { + posts: BlogPost[], + count: number + } + + type AdminBlogPostsQuery = { + author_id: string, + created_at?: string, + expand?: string, + fields?: string + } + + const AuthorsBlogPosts = () => { + const { id } = useParams() + + const { data, isLoading } = useAdminCustomQuery< + AdminBlogPostsQuery, AdminBlogPostsRes + >( + `/blog/posts`, // path + ["blog-posts", "list", id], // queryKey + { + expand: "author", // query + author_id: "auth_123", + } + ) + + return ( + <> + {isLoading && Loading...} + {data && data.posts && ( + + {data.posts.map((post, index) => ( + {post.title} + ))} + + )} + + ) + } + + export default AuthorsBlogPosts + ``` + + #### useAdminCustomPost diff --git a/www/apps/docs/content/modules/carts-and-checkout/storefront/implement-cart.mdx b/www/apps/docs/content/modules/carts-and-checkout/storefront/implement-cart.mdx index 72c9d935e8..54bbabeb91 100644 --- a/www/apps/docs/content/modules/carts-and-checkout/storefront/implement-cart.mdx +++ b/www/apps/docs/content/modules/carts-and-checkout/storefront/implement-cart.mdx @@ -53,60 +53,60 @@ It's also assumed you already have [used CartProvider higher in your component t You can create a cart with the following code snippet: - + -```ts -medusa.carts.create() -.then(({ cart }) => { - localStorage.setItem("cart_id", cart.id) - // assuming you have a state variable to store the cart - setCart(cart) -}) -``` + ```ts + medusa.carts.create() + .then(({ cart }) => { + localStorage.setItem("cart_id", cart.id) + // assuming you have a state variable to store the cart + setCart(cart) + }) + ``` - - + + -```tsx -import { useCart } from "medusa-react" + ```tsx + import { useCart } from "medusa-react" -const Cart = () => { - const { cart, createCart } = useCart() + const Cart = () => { + const { cart, createCart } = useCart() - const handleCreateCart = () => { - createCart.mutate( - {}, // create an empty cart - { - onSuccess: ({ cart }) => { - localStorage.setItem("cart_id", cart.id) - }, + const handleCreateCart = () => { + createCart.mutate( + {}, // create an empty cart + { + onSuccess: ({ cart }) => { + localStorage.setItem("cart_id", cart.id) + }, + } + ) } - ) - } - - // ... -} + + // ... + } -export default Cart -``` + export default Cart + ``` - - + + -```ts -fetch(`/store/carts`, { - method: "POST", - credentials: "include", -}) -.then((response) => response.json()) -.then(({ cart }) => { - localStorage.setItem("cart_id", cart.id) - // assuming you have a state variable to store the cart - setCart(cart) -}) -``` + ```ts + fetch(`/store/carts`, { + method: "POST", + credentials: "include", + }) + .then((response) => response.json()) + .then(({ cart }) => { + localStorage.setItem("cart_id", cart.id) + // assuming you have a state variable to store the cart + setCart(cart) + }) + ``` - + This request does not require any parameters. It returns the created cart in the response. @@ -116,70 +116,70 @@ The cart by default will have a random region assigned to it. You can specify th Otherwise, you can assign it a specific region during creation: - + -```jsx -medusa.carts.create({ - region_id, -}) -.then(({ cart }) => { - localStorage.setItem("cart_id", cart.id) - // assuming you have a state variable to store the cart - setCart(cart) -}) -``` + ```jsx + medusa.carts.create({ + region_id, + }) + .then(({ cart }) => { + localStorage.setItem("cart_id", cart.id) + // assuming you have a state variable to store the cart + setCart(cart) + }) + ``` - - + + -```tsx -import { useCart } from "medusa-react" + ```tsx + import { useCart } from "medusa-react" -const Cart = () => { - const { cart, createCart } = useCart() + const Cart = () => { + const { cart, createCart } = useCart() - const handleCreateCart = () => { - createCart.mutate( - { - region_id, - }, - { - onSuccess: ({ cart }) => { - localStorage.setItem("cart_id", cart.id) - }, + const handleCreateCart = () => { + createCart.mutate( + { + region_id, + }, + { + onSuccess: ({ cart }) => { + localStorage.setItem("cart_id", cart.id) + }, + } + ) } - ) - } - - // ... -} + + // ... + } -export default Cart -``` + export default Cart + ``` - - + + -```jsx -fetch(`/store/carts`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - region_id, - }), -}) -.then((response) => response.json()) -.then(({ cart }) => { - localStorage.setItem("cart_id", cart.id) - // assuming you have a state variable to store the cart - setCart(cart) -}) -``` + ```jsx + fetch(`/store/carts`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + region_id, + }), + }) + .then((response) => response.json()) + .then(({ cart }) => { + localStorage.setItem("cart_id", cart.id) + // assuming you have a state variable to store the cart + setCart(cart) + }) + ``` - + Check out the [API Reference](https://docs.medusajs.com/api/store#carts_postcart) for a full list of available request body parameters. @@ -199,52 +199,52 @@ Notice that in the previous code snippets, you set the cart’s ID in the local You can retrieve the cart at any given point using its ID with the following code snippet: - + -```ts -const id = localStorage.getItem("cart_id") + ```ts + const id = localStorage.getItem("cart_id") -if (id) { - medusa.carts.retrieve(id) - .then(({ cart }) => setCart(cart)) -} -``` + if (id) { + medusa.carts.retrieve(id) + .then(({ cart }) => setCart(cart)) + } + ``` - - + + -```tsx -import { useCart } from "medusa-react" + ```tsx + import { useCart } from "medusa-react" -const Cart = () => { - const { cart } = useCart() + const Cart = () => { + const { cart } = useCart() - return ( -
- Items in Cart: {cart?.items.length || 0} -
- ) -} + return ( +
+ Items in Cart: {cart?.items.length || 0} +
+ ) + } -export default Cart -``` + export default Cart + ``` -
- + + -```ts -const id = localStorage.getItem("cart_id") + ```ts + const id = localStorage.getItem("cart_id") -if (id) { - fetch(`/store/carts/${id}`, { - credentials: "include", - }) - .then((response) => response.json()) - .then(({ cart }) => setCart(cart)) -} -``` + if (id) { + fetch(`/store/carts/${id}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ cart }) => setCart(cart)) + } + ``` - +
This request accepts the ID of the cart as a path parameter and returns the cart of that ID. @@ -266,57 +266,57 @@ A cart has different data associated with it including the region, email, addres You can use the following snippet to update any of the cart’s data: - + -```ts -medusa.carts.update(cartId, { - region_id, -}) -.then(({ cart }) => setCart(cart)) -``` - - - - -```tsx -import { useCart } from "medusa-react" - -const Cart = () => { - // ... - - const { updateCart } = useCart() - - const changeRegionId = (region_id: string) => { - updateCart.mutate({ + ```ts + medusa.carts.update(cartId, { region_id, }) - } + .then(({ cart }) => setCart(cart)) + ``` - // ... -} + + -export default Cart -``` + ```tsx + import { useCart } from "medusa-react" - - + const Cart = () => { + // ... -```ts -fetch(`/store/carts/${cartId}`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - region_id, - }), -}) -.then((response) => response.json()) -.then(({ cart }) => setCart(cart)) -``` + const { updateCart } = useCart() - + const changeRegionId = (region_id: string) => { + updateCart.mutate({ + region_id, + }) + } + + // ... + } + + export default Cart + ``` + + + + + ```ts + fetch(`/store/carts/${cartId}`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + region_id, + }), + }) + .then((response) => response.json()) + .then(({ cart }) => setCart(cart)) + ``` + + This request accepts the ID of the cart as a path parameter. In its body, you can pass any data you want to update in the cart such as the region. @@ -332,57 +332,57 @@ A customer might add items to their cart, then creates an account or log in. In You can do that using the same update operation: - + -```ts -medusa.carts.update(cartId, { - customer_id, -}) -.then(({ cart }) => setCart(cart)) -``` - - - - -```tsx -import { useCart } from "medusa-react" - -const Cart = () => { - // ... - - const { updateCart } = useCart() - - const changeCustomerId = (customer_id: string) => { - updateCart.mutate({ + ```ts + medusa.carts.update(cartId, { customer_id, }) - } + .then(({ cart }) => setCart(cart)) + ``` - // ... -} + + -export default Cart -``` + ```tsx + import { useCart } from "medusa-react" - - + const Cart = () => { + // ... -```ts -fetch(`/store/carts/${cartId}`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - customer_id, - }), -}) -.then((response) => response.json()) -.then(({ cart }) => setCart(cart)) -``` + const { updateCart } = useCart() - + const changeCustomerId = (customer_id: string) => { + updateCart.mutate({ + customer_id, + }) + } + + // ... + } + + export default Cart + ``` + + + + + ```ts + fetch(`/store/carts/${cartId}`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + customer_id, + }), + }) + .then((response) => response.json()) + .then(({ cart }) => setCart(cart)) + ``` + + This updates the `customer_id` associated with the cart to make sure it belongs to a specific customer. @@ -394,57 +394,57 @@ In case the customer doesn't want to use their own account, you must at least as You can do that using the same update operation: - + -```ts -medusa.carts.update(cartId, { - email: "user@example.com", -}) -.then(({ cart }) => setCart(cart)) -``` - - - - -```tsx -import { useCart } from "medusa-react" - -const Cart = () => { - // ... - - const { updateCart } = useCart() - - const changeEmail = (email: string) => { - updateCart.mutate({ - email, + ```ts + medusa.carts.update(cartId, { + email: "user@example.com", }) - } + .then(({ cart }) => setCart(cart)) + ``` - // ... -} + + -export default Cart -``` + ```tsx + import { useCart } from "medusa-react" - - + const Cart = () => { + // ... -```ts -fetch(`/store/carts/${cartId}`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email: "user@example.com", - }), -}) -.then((response) => response.json()) -.then(({ cart }) => setCart(cart)) -``` + const { updateCart } = useCart() - + const changeEmail = (email: string) => { + updateCart.mutate({ + email, + }) + } + + // ... + } + + export default Cart + ``` + + + + + ```ts + fetch(`/store/carts/${cartId}`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + email: "user@example.com", + }), + }) + .then((response) => response.json()) + .then(({ cart }) => setCart(cart)) + ``` + + --- @@ -454,60 +454,60 @@ fetch(`/store/carts/${cartId}`, { To create a line item of a product and add it to a cart, you can use the following code snippet: - + -```jsx -medusa.carts.lineItems.create(cartId, { - variant_id, - quantity: 1, -}) -.then(({ cart }) => setCart(cart)) -``` - - - - -```tsx -import { useCreateLineItem } from "medusa-react" - -const Cart = () => { - // ... - - const createLineItem = useCreateLineItem(cart_id) - - const handleAddItem = () => { - createLineItem.mutate({ + ```jsx + medusa.carts.lineItems.create(cartId, { variant_id, - quantity, + quantity: 1, }) - } + .then(({ cart }) => setCart(cart)) + ``` - // ... -} + + -export default Cart -``` + ```tsx + import { useCreateLineItem } from "medusa-react" - - + const Cart = () => { + // ... -```jsx -fetch(`/store/carts/${cartId}/line-items`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - variant_id, - quantity: 1, - }), -}) -.then((response) => response.json()) -.then(({ cart }) => setCart(cart)) -``` + const createLineItem = useCreateLineItem(cart_id) - + const handleAddItem = () => { + createLineItem.mutate({ + variant_id, + quantity, + }) + } + + // ... + } + + export default Cart + ``` + + + + + ```jsx + fetch(`/store/carts/${cartId}/line-items`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + variant_id, + quantity: 1, + }), + }) + .then((response) => response.json()) + .then(({ cart }) => setCart(cart)) + ``` + + This request accepts the ID of the cart as a path parameter. In the body, it's required to send the ID of the product variant you want to add to the cart and its quantity. @@ -529,60 +529,60 @@ If you’re using Sales Channels, make sure that the cart and the product belong To update a line item's quantity in the cart, you can use the following code snippet: - + -```ts -medusa.carts.lineItems.update(cartId, lineItemId, { - quantity: 3, -}) -.then(({ cart }) => setCart(cart)) -``` - - - - -```tsx -import { useUpdateLineItem } from "medusa-react" - -const Cart = () => { - // ... - - const updateLineItem = useUpdateLineItem(cart_id) - - const handleUpdateItem = () => { - updateLineItem.mutate({ - lineId, + ```ts + medusa.carts.lineItems.update(cartId, lineItemId, { quantity: 3, }) - } + .then(({ cart }) => setCart(cart)) + ``` - // ... -} + + -export default Cart -``` + ```tsx + import { useUpdateLineItem } from "medusa-react" - - + const Cart = () => { + // ... + + const updateLineItem = useUpdateLineItem(cart_id) + + const handleUpdateItem = () => { + updateLineItem.mutate({ + lineId, + quantity: 3, + }) + } + + // ... + } + + export default Cart + ``` + + + -```ts -fetch(`/store/carts/${cartId}/line-items/${lineItemId}`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - quantity: 3, - }), -}) -.then((response) => response.json()) -.then(({ cart }) => setCart(cart)) -``` + ```ts + fetch(`/store/carts/${cartId}/line-items/${lineItemId}`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + quantity: 3, + }), + }) + .then((response) => response.json()) + .then(({ cart }) => setCart(cart)) + ``` - + This request accepts the ID of the cart and the ID of the line item as path parameters. In the body, it accepts the quantity of the line item. @@ -596,51 +596,51 @@ It returns the updated cart. To delete a line item from the cart, you can use the following code snippet: - + -```ts -medusa.carts.lineItems.delete(cartId, lineItemId) -.then(({ cart }) => setCart(cart)) -``` + ```ts + medusa.carts.lineItems.delete(cartId, lineItemId) + .then(({ cart }) => setCart(cart)) + ``` - - + + -```tsx -import { useDeleteLineItem } from "medusa-react" + ```tsx + import { useDeleteLineItem } from "medusa-react" -const Cart = () => { - // ... + const Cart = () => { + // ... - const deleteLineItem = useDeleteLineItem(cart_id) + const deleteLineItem = useDeleteLineItem(cart_id) - const handleDeleteItem = () => { - deleteLineItem.mutate({ - lineId, - }) - } + const handleDeleteItem = () => { + deleteLineItem.mutate({ + lineId, + }) + } - // ... -} + // ... + } -export default Cart -``` + export default Cart + ``` - - + + -```ts -fetch(`/store/carts/${cartId}/line-items/${lineItemId}`, { - method: "DELETE", - credentials: "include", -}) -.then((response) => response.json()) -.then(({ cart }) => setCart(cart)) -``` + ```ts + fetch(`/store/carts/${cartId}/line-items/${lineItemId}`, { + method: "DELETE", + credentials: "include", + }) + .then((response) => response.json()) + .then(({ cart }) => setCart(cart)) + ``` - + This request accepts the ID of the cart and the ID of the line item as path parameters. diff --git a/www/apps/docs/content/modules/carts-and-checkout/storefront/implement-checkout-flow.mdx b/www/apps/docs/content/modules/carts-and-checkout/storefront/implement-checkout-flow.mdx index d429ffe512..8751c378bc 100644 --- a/www/apps/docs/content/modules/carts-and-checkout/storefront/implement-checkout-flow.mdx +++ b/www/apps/docs/content/modules/carts-and-checkout/storefront/implement-checkout-flow.mdx @@ -63,95 +63,95 @@ In this step, the customer generally enters their shipping info, then chooses th After the customer enters their shipping address information, you must send a `POST` request to the [Update a Cart API Route](https://docs.medusajs.com/api/store#carts_postcartscart): - + -```ts -medusa.carts.update(cartId, { - shipping_address: { - company, - first_name, - last_name, - address_1, - address_2, - city, - country_code, - province, - postal_code, - phone, - }, -}) -.then(({ cart }) => { - console.log(cart.shipping_address) -}) -``` + ```ts + medusa.carts.update(cartId, { + shipping_address: { + company, + first_name, + last_name, + address_1, + address_2, + city, + country_code, + province, + postal_code, + phone, + }, + }) + .then(({ cart }) => { + console.log(cart.shipping_address) + }) + ``` - - + + -```tsx -import { useCart } from "medusa-react" + ```tsx + import { useCart } from "medusa-react" -const Cart = () => { - // ... + const Cart = () => { + // ... - const { updateCart } = useCart() + const { updateCart } = useCart() - const addShippingAddress = - (address: Record) => { - updateCart.mutate({ - shipping_address: { - company: address.company, - first_name: address.first_name, - last_name: address.last_name, - address_1: address.address_1, - address_2: address.address_2, - city: address.city, - country_code: address.country_code, - province: address.province, - postal_code: address.postal_code, - phone: address.phone, - }, - }) + const addShippingAddress = + (address: Record) => { + updateCart.mutate({ + shipping_address: { + company: address.company, + first_name: address.first_name, + last_name: address.last_name, + address_1: address.address_1, + address_2: address.address_2, + city: address.city, + country_code: address.country_code, + province: address.province, + postal_code: address.postal_code, + phone: address.phone, + }, + }) + } + + // ... } - // ... -} + export default Cart + ``` -export default Cart -``` + + - - + ```ts + fetch(`/store/carts/${cartId}`, { + method: "POST", + credentials: "include", + body: JSON.stringify({ + shipping_address: { + company, + first_name, + last_name, + address_1, + address_2, + city, + country_code, + province, + postal_code, + phone, + }, + }), + headers: { + "Content-Type": "application/json", + }, + }) + .then((response) => response.json()) + .then(({ cart }) => { + console.log(cart.shipping_address) + }) + ``` -```ts -fetch(`/store/carts/${cartId}`, { - method: "POST", - credentials: "include", - body: JSON.stringify({ - shipping_address: { - company, - first_name, - last_name, - address_1, - address_2, - city, - country_code, - province, - postal_code, - phone, - }, - }), - headers: { - "Content-Type": "application/json", - }, -}) -.then((response) => response.json()) -.then(({ cart }) => { - console.log(cart.shipping_address) -}) -``` - - + This request accepts the ID of the cart as a path parameter and the new shipping address in the request body. @@ -167,67 +167,67 @@ After updating the cart with the customer’s address, the list of available [sh You can retrieve the list of shipping options by sending a `GET` request to the [Retrieve Shipping Options for Cart API Route](https://docs.medusajs.com/api/store#shipping-options_getshippingoptionscartid): - + -```ts -medusa.shippingOptions.listCartOptions(cartId) -.then(({ shipping_options }) => { - console.log(shipping_options.length) -}) -``` + ```ts + medusa.shippingOptions.listCartOptions(cartId) + .then(({ shipping_options }) => { + console.log(shipping_options.length) + }) + ``` - - + + -```tsx -import { useCartShippingOptions } from "medusa-react" + ```tsx + import { useCartShippingOptions } from "medusa-react" -type Props = { - cartId: string -} + type Props = { + cartId: string + } -const ShippingOptions = ({ cartId }: Props) => { - const { shipping_options, isLoading } = - useCartShippingOptions(cartId) + const ShippingOptions = ({ cartId }: Props) => { + const { shipping_options, isLoading } = + useCartShippingOptions(cartId) - return ( -
- {isLoading && Loading...} - {shipping_options && !shipping_options.length && ( - No shipping options - )} - {shipping_options && ( -
    - {shipping_options.map( - (shipping_option) => ( -
  • - {shipping_option.name} -
  • - ) + return ( +
    + {isLoading && Loading...} + {shipping_options && !shipping_options.length && ( + No shipping options )} -
- )} -
- ) -} + {shipping_options && ( +
    + {shipping_options.map( + (shipping_option) => ( +
  • + {shipping_option.name} +
  • + ) + )} +
+ )} + + ) + } -export default ShippingOptions -``` + export default ShippingOptions + ``` -
- + + -```ts -fetch(`/store/shipping-options/${cartId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ shipping_options }) => { - console.log(shipping_options.length) -}) -``` + ```ts + fetch(`/store/shipping-options/${cartId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ shipping_options }) => { + console.log(shipping_options.length) + }) + ``` - +
The request accepts the ID of the cart as a path parameter. It returns the array of [shipping options](https://docs.medusajs.com/api/store#shipping-options_getshippingoptions). Typically you would display those options to the customer to choose from. @@ -237,61 +237,61 @@ The request accepts the ID of the cart as a path parameter. It returns the array Once the customer chooses one of the available shipping options, send a `POST` request to the [Add a Shipping Method API Route](https://docs.medusajs.com/api/store#carts_postcartscartshippingmethod). This will create a [shipping method](../shipping.md#shipping-method) based on the shipping option chosen and will associate it with the customer’s cart: - + -```ts -medusa.carts.addShippingMethod(cartId, { - option_id: shippingOptionId, // the ID of the selected option -}) -.then(({ cart }) => { - console.log(cart.shipping_methods) -}) -``` - - - - -```tsx -import { useAddShippingMethodToCart } from "medusa-react" -// ... - -const ShippingOptions = ({ cartId }: Props) => { - // ... - const addShippingMethod = useAddShippingMethodToCart(cartId) - - const handleAddShippingMethod = (option_id: string) => { - addShippingMethod.mutate({ - option_id, + ```ts + medusa.carts.addShippingMethod(cartId, { + option_id: shippingOptionId, // the ID of the selected option }) - } + .then(({ cart }) => { + console.log(cart.shipping_methods) + }) + ``` - // ... -} + + -export default ShippingOptions -``` + ```tsx + import { useAddShippingMethodToCart } from "medusa-react" + // ... - - + const ShippingOptions = ({ cartId }: Props) => { + // ... + const addShippingMethod = useAddShippingMethodToCart(cartId) -```ts -fetch(`/store/carts/${cartId}/shipping-methods`, { - method: "POST", - credentials: "include", - body: JSON.stringify({ - option_id: shippingOptionId, // ID of the selected option - }), - headers: { - "Content-Type": "application/json", - }, -}) -.then((response) => response.json()) -.then(({ cart }) => { - console.log(cart.shipping_methods) -}) -``` + const handleAddShippingMethod = (option_id: string) => { + addShippingMethod.mutate({ + option_id, + }) + } - + // ... + } + + export default ShippingOptions + ``` + + + + + ```ts + fetch(`/store/carts/${cartId}/shipping-methods`, { + method: "POST", + credentials: "include", + body: JSON.stringify({ + option_id: shippingOptionId, // ID of the selected option + }), + headers: { + "Content-Type": "application/json", + }, + }) + .then((response) => response.json()) + .then(({ cart }) => { + console.log(cart.shipping_methods) + }) + ``` + + The request accepts the ID of the cart as a path parameter and its body the ID of the selected shipping option. @@ -311,65 +311,65 @@ When the page opens and before the payment providers are displayed to the custom To initialize the payment sessions, send a `POST` request to the [Initialize Payment Sessions API Route](https://docs.medusajs.com/api/store#carts_postcartscartpaymentsession): - + -```ts -medusa.carts.createPaymentSessions(cartId) -.then(({ cart }) => { - console.log(cart.payment_sessions) -}) -``` + ```ts + medusa.carts.createPaymentSessions(cartId) + .then(({ cart }) => { + console.log(cart.payment_sessions) + }) + ``` - - + + -```tsx -import { useCart } from "medusa-react" -import { useEffect } from "react" + ```tsx + import { useCart } from "medusa-react" + import { useEffect } from "react" -const PaymentProviders = () => { - const { cart, startCheckout } = useCart() + const PaymentProviders = () => { + const { cart, startCheckout } = useCart() - useEffect(() => { - startCheckout.mutate() - }, []) + useEffect(() => { + startCheckout.mutate() + }, []) - return ( -
- {!cart?.payment_sessions.length && ( - No payment processors - )} -
    - {cart?.payment_sessions.map( - (paymentSession) => ( -
  • - {paymentSession.provider_id} -
  • - ) - )} -
-
- ) -} + return ( +
+ {!cart?.payment_sessions.length && ( + No payment processors + )} +
    + {cart?.payment_sessions.map( + (paymentSession) => ( +
  • + {paymentSession.provider_id} +
  • + ) + )} +
+
+ ) + } -export default PaymentProviders -``` + export default PaymentProviders + ``` -
- + + -```ts -fetch(`/store/carts/${cartId}/payment-sessions`, { - method: "POST", - credentials: "include", -}) -.then((response) => response.json()) -.then(({ cart }) => { - console.log(cart.payment_sessions) -}) -``` + ```ts + fetch(`/store/carts/${cartId}/payment-sessions`, { + method: "POST", + credentials: "include", + }) + .then((response) => response.json()) + .then(({ cart }) => { + console.log(cart.payment_sessions) + }) + ``` - +
This API Route accepts the ID of the cart as a path parameter. It returns the updated cart with the initialized payment sessions available on `cart.payment_sessions`. @@ -379,62 +379,62 @@ This API Route accepts the ID of the cart as a path parameter. It returns the up When the customer chooses the payment processor they want to complete purchase with, you should select the payment session associated with that payment processor. To do that, send a `POST` request to the [Select a Payment Session API Route](https://docs.medusajs.comapi/store#carts_postcartscartpaymentsession): - + -```ts -medusa.carts.setPaymentSession(cartId, { - // retrieved from the payment session selected by the customer - provider_id: paymentProviderId, -}) -.then(({ cart }) => { - console.log(cart.payment_session) -}) -``` - - - - -```tsx -import { useCart } from "medusa-react" - -const PaymentProviders = () => { - const { cart, startCheckout, pay } = useCart() - // ... - - const handleSetPaymentSession = (provider_id: string) => { - pay.mutate({ - provider_id, + ```ts + medusa.carts.setPaymentSession(cartId, { + // retrieved from the payment session selected by the customer + provider_id: paymentProviderId, }) - } - - // ... -} + .then(({ cart }) => { + console.log(cart.payment_session) + }) + ``` -export default PaymentProviders -``` + + - - + ```tsx + import { useCart } from "medusa-react" -```ts -fetch(`/store/carts/${cartId}/payment-session`, { - method: "POST", - credentials: "include", - body: JSON.stringify({ - // the payment session selected by the customer - provider_id: paymentProviderId, - }), - headers: { - "Content-Type": "application/json", - }, -}) -.then((response) => response.json()) -.then(({ cart }) => { - console.log(cart.payment_session) -}) -``` + const PaymentProviders = () => { + const { cart, startCheckout, pay } = useCart() + // ... - + const handleSetPaymentSession = (provider_id: string) => { + pay.mutate({ + provider_id, + }) + } + + // ... + } + + export default PaymentProviders + ``` + + + + + ```ts + fetch(`/store/carts/${cartId}/payment-session`, { + method: "POST", + credentials: "include", + body: JSON.stringify({ + // the payment session selected by the customer + provider_id: paymentProviderId, + }), + headers: { + "Content-Type": "application/json", + }, + }) + .then((response) => response.json()) + .then(({ cart }) => { + console.log(cart.payment_session) + }) + ``` + + The request accepts the ID of the cart as a path parameter, and the ID of the payment processor in the request's body. @@ -454,79 +454,79 @@ This step is optional and is only necessary for some payment processors. As ment If you need to update that data at any point before the purchase is made, send a request to [Update a Payment Session API Route](https://docs.medusajs.com/api/store#carts_postcartscartpaymentsessionupdate): - + -```ts -medusa.carts.updatePaymentSession(cartId, paymentProviderId, { - data: { - // pass any data you want to add in the `data` attribute - // for example: - "test": true, - }, -}) -.then(({ cart }) => { - console.log(cart.payment_session.data) -}) -``` - - - - -```tsx -import { useUpdatePaymentSession, useCart } from "medusa-react" -// ... - -const PaymentProviders = () => { - const { cart } = useCart() - const updatePaymentSession = useUpdatePaymentSession(cart.id) - // ... - - const handleUpdatePaymentSession = ( - provider_id: string, - data: Record - ) => { - updatePaymentSession.mutate({ - provider_id, - data, - }) - } - - // ... -} - -export default PaymentProviders -``` - - - - - - -```ts -fetch( - `/store/carts/${cartId}/payment-sessions/${paymentProviderId}`, - { - method: "POST", - credentials: "include", - body: JSON.stringify({ + ```ts + medusa.carts.updatePaymentSession(cartId, paymentProviderId, { data: { // pass any data you want to add in the `data` attribute // for example: "test": true, }, - }), - headers: { - "Content-Type": "application/json", - }, - } -) -.then((response) => response.json()) -.then(({ cart }) => { - console.log(cart.payment_session.data) -}) -``` + }) + .then(({ cart }) => { + console.log(cart.payment_session.data) + }) + ``` - + + + + ```tsx + import { useUpdatePaymentSession, useCart } from "medusa-react" + // ... + + const PaymentProviders = () => { + const { cart } = useCart() + const updatePaymentSession = useUpdatePaymentSession(cart.id) + // ... + + const handleUpdatePaymentSession = ( + provider_id: string, + data: Record + ) => { + updatePaymentSession.mutate({ + provider_id, + data, + }) + } + + // ... + } + + export default PaymentProviders + ``` + + + + + + + ```ts + fetch( + `/store/carts/${cartId}/payment-sessions/${paymentProviderId}`, + { + method: "POST", + credentials: "include", + body: JSON.stringify({ + data: { + // pass any data you want to add in the `data` attribute + // for example: + "test": true, + }, + }), + headers: { + "Content-Type": "application/json", + }, + } + ) + .then((response) => response.json()) + .then(({ cart }) => { + console.log(cart.payment_session.data) + }) + ``` + + This request accepts the ID of the cart and the ID of the payment session's payment processor as path parameters. In the request's body, it accepts a `data` object where you can pass any data relevant for the payment processor. @@ -540,54 +540,54 @@ The last step is to place the order by completing the cart. When you complete th To complete a cart, send a `POST` request to the [Complete a Cart API Route](https://docs.medusajs.com/api/store#carts_postcartscartcomplete): - + -```ts -medusa.carts.complete(cartId) -.then(({ type, data }) => { - console.log(type, data) -}) -``` + ```ts + medusa.carts.complete(cartId) + .then(({ type, data }) => { + console.log(type, data) + }) + ``` - - + + -```tsx -import { useCart } from "medusa-react" -// ... + ```tsx + import { useCart } from "medusa-react" + // ... -const Cart = () => { - const { completeCheckout } = useCart() - // ... + const Cart = () => { + const { completeCheckout } = useCart() + // ... - const handleCompleteCheckout = () => { - completeCheckout.mutate() - } + const handleCompleteCheckout = () => { + completeCheckout.mutate() + } - // ... -} + // ... + } -export default Cart -``` + export default Cart + ``` - - + + -```ts -fetch(`/store/carts/${cartId}/complete`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, -}) -.then((response) => response.json()) -.then(({ type, data }) => { - console.log(type, data) -}) -``` + ```ts + fetch(`/store/carts/${cartId}/complete`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + }) + .then((response) => response.json()) + .then(({ type, data }) => { + console.log(type, data) + }) + ``` - + This request accepts the ID of the cart as a path parameter. diff --git a/www/apps/docs/content/modules/customers/admin/manage-customer-groups.mdx b/www/apps/docs/content/modules/customers/admin/manage-customer-groups.mdx index 0906a1925b..dca59c0a3d 100644 --- a/www/apps/docs/content/modules/customers/admin/manage-customer-groups.mdx +++ b/www/apps/docs/content/modules/customers/admin/manage-customer-groups.mdx @@ -51,78 +51,78 @@ You can learn more about [authenticating as an admin user in the API reference]( You can create a customer group by sending a request to the Create Customer Group API Route: - + -```ts -medusa.admin.customerGroups.create({ - name: "VIP", -}) -.then(({ customer_group }) => { - console.log(customer_group.id) -}) -``` - - - - -```tsx -import { useAdminCreateCustomerGroup } from "medusa-react" - -const CreateCustomerGroup = () => { - const createCustomerGroup = useAdminCreateCustomerGroup() - // ... - - const handleCreate = () => { - createCustomerGroup.mutate({ - name, + ```ts + medusa.admin.customerGroups.create({ + name: "VIP", }) - } + .then(({ customer_group }) => { + console.log(customer_group.id) + }) + ``` - // ... - - return ( -
- {/* Render form */} -
- ) -} +
+ -export default CreateCustomerGroup -``` + ```tsx + import { useAdminCreateCustomerGroup } from "medusa-react" - - + const CreateCustomerGroup = () => { + const createCustomerGroup = useAdminCreateCustomerGroup() + // ... -```ts -fetch(`/admin/customer-groups`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - name: "VIP", - }), -}) -.then((response) => response.json()) -.then(({ customer_group }) => { - console.log(customer_group.id) -}) -``` + const handleCreate = () => { + createCustomerGroup.mutate({ + name, + }) + } - - + // ... + + return ( +
+ {/* Render form */} +
+ ) + } -```bash -curl -L -X POST '/admin/customer-groups' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "name": "VIP" -}' -``` + export default CreateCustomerGroup + ``` -
+
+ + + ```ts + fetch(`/admin/customer-groups`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + name: "VIP", + }), + }) + .then((response) => response.json()) + .then(({ customer_group }) => { + console.log(customer_group.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/customer-groups' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "name": "VIP" + }' + ``` + +
This request requires the `name` parameter and optionally accepts the `metadata` object parameter to be passed in the body. It returns the created customer group. @@ -134,74 +134,74 @@ This request requires the `name` parameter and optionally accepts the `metadata` You can get a list of all customer groups by sending a request to the List Customer Groups API Route: - + -```ts -medusa.admin.customerGroups.list() -.then(({ customer_groups, limit, offset, count }) => { - console.log(customer_groups.length) -}) -``` + ```ts + medusa.admin.customerGroups.list() + .then(({ customer_groups, limit, offset, count }) => { + console.log(customer_groups.length) + }) + ``` - - + + -```tsx -import { CustomerGroup } from "@medusajs/medusa" -import { useAdminCustomerGroups } from "medusa-react" + ```tsx + import { CustomerGroup } from "@medusajs/medusa" + import { useAdminCustomerGroups } from "medusa-react" -const CustomerGroups = () => { - const { - customer_groups, - isLoading, - } = useAdminCustomerGroups() + const CustomerGroups = () => { + const { + customer_groups, + isLoading, + } = useAdminCustomerGroups() - return ( -
- {isLoading && Loading...} - {customer_groups && !customer_groups.length && ( - No Customer Groups - )} - {customer_groups && customer_groups.length > 0 && ( -
    - {customer_groups.map( - (customerGroup: CustomerGroup) => ( -
  • - {customerGroup.name} -
  • - ) + return ( +
    + {isLoading && Loading...} + {customer_groups && !customer_groups.length && ( + No Customer Groups )} -
- )} -
- ) -} + {customer_groups && customer_groups.length > 0 && ( +
    + {customer_groups.map( + (customerGroup: CustomerGroup) => ( +
  • + {customerGroup.name} +
  • + ) + )} +
+ )} + + ) + } -export default CustomerGroups -``` + export default CustomerGroups + ``` -
- + + -```ts -fetch(`/admin/customer-groups`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ customer_groups, limit, offset, count }) => { - console.log(customer_groups.length) -}) -``` + ```ts + fetch(`/admin/customer-groups`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ customer_groups, limit, offset, count }) => { + console.log(customer_groups.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/customer-groups' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/customer-groups' \ + -H 'Authorization: Bearer ' + ``` - +
This request returns an array of customer groups, as well as pagination fields. @@ -215,62 +215,62 @@ You can also pass filters and other selection query parameters to the request. C You can retrieve a single customer group by sending a request to the Get a Customer Group API Route: - + -```ts -medusa.admin.customerGroups.retrieve(customerGroupId) -.then(({ customer_group }) => { - console.log(customer_group.id) -}) -``` + ```ts + medusa.admin.customerGroups.retrieve(customerGroupId) + .then(({ customer_group }) => { + console.log(customer_group.id) + }) + ``` - - + + -```tsx -import { useAdminCustomerGroup } from "medusa-react" + ```tsx + import { useAdminCustomerGroup } from "medusa-react" -const CustomerGroup = () => { - const { customer_group, isLoading } = useAdminCustomerGroup( - customerGroupId - ) + const CustomerGroup = () => { + const { customer_group, isLoading } = useAdminCustomerGroup( + customerGroupId + ) - return ( -
- {isLoading && Loading...} - {customer_group && {customer_group.name}} -
- ) -} + return ( +
+ {isLoading && Loading...} + {customer_group && {customer_group.name}} +
+ ) + } -export default CustomerGroup -``` + export default CustomerGroup + ``` -
- + + -```ts -fetch( - `/admin/customer-groups/${customerGroupId}`, - { - credentials: "include", - } -) -.then((response) => response.json()) -.then(({ customer_group }) => { - console.log(customer_group.id) -}) -``` + ```ts + fetch( + `/admin/customer-groups/${customerGroupId}`, + { + credentials: "include", + } + ) + .then((response) => response.json()) + .then(({ customer_group }) => { + console.log(customer_group.id) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/customer-groups/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/customer-groups/' \ + -H 'Authorization: Bearer ' + ``` - +
This request accepts the ID of the customer group to retrieve as a path parameter. It returns the customer group of that ID. @@ -282,89 +282,89 @@ This request accepts the ID of the customer group to retrieve as a path paramete You can update a customer group’s data by sending a request to the Update Customer Group API Route: - + -```ts -medusa.admin.customerGroups.update(customerGroupId, { - metadata: { - is_seller: true, - }, -}) -.then(({ customer_group }) => { - console.log(customer_group.id) -}) -``` - - - - -```tsx -import { useAdminUpdateCustomerGroup } from "medusa-react" - -const UpdateCustomerGroup = () => { - const updateCustomerGroup = useAdminUpdateCustomerGroup( - customerGroupId - ) - // .. - - const handleUpdate = () => { - updateCustomerGroup.mutate({ - name, - }) - } - - // ... - - return ( -
- {/* Render form */} -
- ) -} - -export default UpdateCustomerGroup -``` - -
- - -```ts -fetch( - `/admin/customer-groups/${customerGroupId}`, - { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ + ```ts + medusa.admin.customerGroups.update(customerGroupId, { metadata: { is_seller: true, }, - }), - } -) -.then((response) => response.json()) -.then(({ customer_group }) => { - console.log(customer_group.id) -}) -``` + }) + .then(({ customer_group }) => { + console.log(customer_group.id) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/customer-groups/' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "metadata": { - "is_seller": true - } -}' -``` + ```tsx + import { useAdminUpdateCustomerGroup } from "medusa-react" - + const UpdateCustomerGroup = () => { + const updateCustomerGroup = useAdminUpdateCustomerGroup( + customerGroupId + ) + // .. + + const handleUpdate = () => { + updateCustomerGroup.mutate({ + name, + }) + } + + // ... + + return ( +
+ {/* Render form */} +
+ ) + } + + export default UpdateCustomerGroup + ``` + +
+ + + ```ts + fetch( + `/admin/customer-groups/${customerGroupId}`, + { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + metadata: { + is_seller: true, + }, + }), + } + ) + .then((response) => response.json()) + .then(({ customer_group }) => { + console.log(customer_group.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/customer-groups/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "metadata": { + "is_seller": true + } + }' + ``` + +
This request accepts the ID of the customer group as a path parameter, and optionally accepts the `name` or `metadata` fields as body parameters. It returns the updated customer group. @@ -376,63 +376,63 @@ This request accepts the ID of the customer group as a path parameter, and optio You can delete a customer group by sending a request to the Delete a Customer Group API Route: - + -```ts -medusa.admin.customerGroups.delete(customerGroupId) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + medusa.admin.customerGroups.delete(customerGroupId) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```tsx -import { useAdminDeleteCustomerGroup } from "medusa-react" + ```tsx + import { useAdminDeleteCustomerGroup } from "medusa-react" -const CustomerGroup = () => { - const deleteCustomerGroup = useAdminDeleteCustomerGroup( - customerGroupId - ) - // ... + const CustomerGroup = () => { + const deleteCustomerGroup = useAdminDeleteCustomerGroup( + customerGroupId + ) + // ... - const handleDeleteCustomerGroup = () => { - deleteCustomerGroup.mutate() - } + const handleDeleteCustomerGroup = () => { + deleteCustomerGroup.mutate() + } - // ... -} + // ... + } -export default CustomerGroup -``` + export default CustomerGroup + ``` - - + + -```ts -fetch( - `/admin/customer-groups/${customerGroupId}`, - { - method: "DELETE", - credentials: "include", - } -) -.then((response) => response.json()) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + fetch( + `/admin/customer-groups/${customerGroupId}`, + { + method: "DELETE", + credentials: "include", + } + ) + .then((response) => response.json()) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/customer-groups/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/customer-groups/' \ + -H 'Authorization: Bearer ' + ``` - + This request accepts the ID of the customer group to delete as a path parameter. It returns the ID of the deleted entity. @@ -446,97 +446,97 @@ This request accepts the ID of the customer group to delete as a path parameter. You can add a customer to a group by sending a request to the Customer Group’s Add Customer API Route: - + -```ts -medusa.admin.customerGroups.addCustomers(customerGroupId, { - customer_ids: [ - { - id: customerId, - }, - ], -}) -.then(({ customer_group }) => { - console.log(customer_group.id) -}) -``` - - - - -```tsx -import { - useAdminAddCustomersToCustomerGroup, -} from "medusa-react" - -const CustomerGroup = () => { - const addCustomers = useAdminAddCustomersToCustomerGroup( - customerGroupId - ) - // ... - - const handleAddCustomers= (customerId: string) => { - addCustomers.mutate({ + ```ts + medusa.admin.customerGroups.addCustomers(customerGroupId, { customer_ids: [ { id: customerId, }, ], }) - } + .then(({ customer_group }) => { + console.log(customer_group.id) + }) + ``` - // ... -} + + -export default CustomerGroup -``` + ```tsx + import { + useAdminAddCustomersToCustomerGroup, + } from "medusa-react" - - + const CustomerGroup = () => { + const addCustomers = useAdminAddCustomersToCustomerGroup( + customerGroupId + ) + // ... + + const handleAddCustomers= (customerId: string) => { + addCustomers.mutate({ + customer_ids: [ + { + id: customerId, + }, + ], + }) + } + + // ... + } + + export default CustomerGroup + ``` + + + -```ts -fetch( - `/admin/customer-groups/${customerGroupId}/customers/batch`, - { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - customer_ids: [ - { - id: customerId, + ```ts + fetch( + `/admin/customer-groups/${customerGroupId}/customers/batch`, + { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", }, - ], - }), - } -) -.then((response) => response.json()) -.then(({ customer_group }) => { - console.log(customer_group.id) -}) -``` + body: JSON.stringify({ + customer_ids: [ + { + id: customerId, + }, + ], + }), + } + ) + .then((response) => response.json()) + .then(({ customer_group }) => { + console.log(customer_group.id) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/customer-groups//customers/batch' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "customer_ids": [ - { - "id": "" - } - ] -}' -``` + ```bash + curl -L -X POST '/admin/customer-groups//customers/batch' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "customer_ids": [ + { + "id": "" + } + ] + }' + ``` - + This request accepts the ID of the customer group as a path parameter. In its body, it accepts a `customer_ids` array of objects. Each object in the array must have the `id` property with its value being the ID of the customer you want to add. @@ -546,74 +546,74 @@ This request accepts the ID of the customer group as a path parameter. In its bo You can retrieve a list of all customers in a customer group using the List Customers API Route: - + -```ts -medusa.admin.customerGroups.listCustomers(customerGroupId) -.then(({ customers, count, offset, limit }) => { - console.log(customers.length) -}) -``` + ```ts + medusa.admin.customerGroups.listCustomers(customerGroupId) + .then(({ customers, count, offset, limit }) => { + console.log(customers.length) + }) + ``` - - + + -```tsx -import { Customer } from "@medusajs/medusa" -import { useAdminCustomerGroupCustomers } from "medusa-react" + ```tsx + import { Customer } from "@medusajs/medusa" + import { useAdminCustomerGroupCustomers } from "medusa-react" -const CustomerGroup = () => { - const { - customers, - isLoading, - } = useAdminCustomerGroupCustomers( - customerGroupId - ) + const CustomerGroup = () => { + const { + customers, + isLoading, + } = useAdminCustomerGroupCustomers( + customerGroupId + ) - return ( -
- {isLoading && Loading...} - {customers && !customers.length && ( - No customers - )} - {customers && customers.length > 0 && ( -
    - {customers.map((customer: Customer) => ( -
  • {customer.first_name}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {customers && !customers.length && ( + No customers + )} + {customers && customers.length > 0 && ( +
    + {customers.map((customer: Customer) => ( +
  • {customer.first_name}
  • + ))} +
+ )} +
+ ) + } -export default CustomerGroup -``` + export default CustomerGroup + ``` -
- + + -```ts -fetch(`/admin/customer-groups/${customerGroupId}/customers`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ customers, count, offset, limit }) => { - console.log(customers.length) -}) -``` + ```ts + fetch(`/admin/customer-groups/${customerGroupId}/customers`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ customers, count, offset, limit }) => { + console.log(customers.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/customer-groups//customers' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/customer-groups//customers' \ + -H 'Authorization: Bearer ' + ``` - +
This request accepts the ID of the customer group as a path parameter. It returns an array of customers along with pagination fields. @@ -629,102 +629,102 @@ Removing customers from a group does not remove them entirely. They’ll still b You can remove customers from a customer group by sending a request to the Remove Customers API Route: - + -```ts -medusa.admin.customerGroups.removeCustomers( - customer_group_id, - { - customer_ids: [ + ```ts + medusa.admin.customerGroups.removeCustomers( + customer_group_id, { - id: customer_id, - }, - ], - } -) -.then(({ customer_group }) => { - console.log(customer_group.id) -}) -``` - - - - -```tsx -import { Customer } from "@medusajs/medusa" -import { - useAdminRemoveCustomersFromCustomerGroup, -} from "medusa-react" - -const CustomerGroup = () => { - const removeCustomers = - useAdminRemoveCustomersFromCustomerGroup( - customerGroupId + customer_ids: [ + { + id: customer_id, + }, + ], + } ) - // ... - - const handleRemoveCustomer = (customer_id: string) => { - removeCustomers.mutate({ - customer_ids: [ - { - id: customer_id, - }, - ], + .then(({ customer_group }) => { + console.log(customer_group.id) }) - } + ``` - // ... -} + + -export default CustomerGroup -``` + ```tsx + import { Customer } from "@medusajs/medusa" + import { + useAdminRemoveCustomersFromCustomerGroup, + } from "medusa-react" - - + const CustomerGroup = () => { + const removeCustomers = + useAdminRemoveCustomersFromCustomerGroup( + customerGroupId + ) + // ... + + const handleRemoveCustomer = (customer_id: string) => { + removeCustomers.mutate({ + customer_ids: [ + { + id: customer_id, + }, + ], + }) + } + + // ... + } + + export default CustomerGroup + ``` + + + -```ts -fetch( - `/admin/customer-groups/${customerGroupId}/customers/batch`, - { - method: "DELETE", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - customer_ids: [ - { - id: customerId, + ```ts + fetch( + `/admin/customer-groups/${customerGroupId}/customers/batch`, + { + method: "DELETE", + credentials: "include", + headers: { + "Content-Type": "application/json", }, - ], - }), - } -) -.then((response) => response.json()) -.then(({ customer_group }) => { - console.log(customer_group.id) -}) -``` + body: JSON.stringify({ + customer_ids: [ + { + id: customerId, + }, + ], + }), + } + ) + .then((response) => response.json()) + .then(({ customer_group }) => { + console.log(customer_group.id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/customer-groups//customers/batch' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "customer_ids": [ - { - "id": "" - } - ] -}' -``` + ```bash + curl -L -X DELETE '/admin/customer-groups//customers/batch' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "customer_ids": [ + { + "id": "" + } + ] + }' + ``` - + This request accepts as a path parameter the ID of the customer group to remove customers from. In its body, it accepts a `customer_ids` array of objects. Each object in the array must have the `id` property with the value being the ID of the customer to remove from the group. diff --git a/www/apps/docs/content/modules/customers/admin/manage-customers.mdx b/www/apps/docs/content/modules/customers/admin/manage-customers.mdx index 35fba53dac..e16be036d9 100644 --- a/www/apps/docs/content/modules/customers/admin/manage-customers.mdx +++ b/www/apps/docs/content/modules/customers/admin/manage-customers.mdx @@ -55,67 +55,67 @@ You can learn more about [authenticating as an admin user in the API reference]( You can show a list of customers by sending a request to the [List Customers API Route](https://docs.medusajs.com/api/admin#customers_getcustomers): - + -```ts -medusa.admin.customers.list() -.then(({ customers, limit, offset, count }) => { - console.log(customers.length) -}) -``` + ```ts + medusa.admin.customers.list() + .then(({ customers, limit, offset, count }) => { + console.log(customers.length) + }) + ``` - - + + -```tsx -import { Customer } from "@medusajs/medusa" -import { useAdminCustomers } from "medusa-react" + ```tsx + import { Customer } from "@medusajs/medusa" + import { useAdminCustomers } from "medusa-react" -const Customers = () => { - const { customers, isLoading } = useAdminCustomers() + const Customers = () => { + const { customers, isLoading } = useAdminCustomers() - return ( -
- {isLoading && Loading...} - {customers && !customers.length && ( - No customers - )} - {customers && customers.length > 0 && ( -
    - {customers.map((customer: Customer) => ( -
  • {customer.first_name}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {customers && !customers.length && ( + No customers + )} + {customers && customers.length > 0 && ( +
    + {customers.map((customer: Customer) => ( +
  • {customer.first_name}
  • + ))} +
+ )} +
+ ) + } -export default Customers -``` + export default Customers + ``` -
- + + -```ts -fetch(`/admin/customers`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ customers, limit, offset, count }) => { - console.log(customers.length) -}) -``` + ```ts + fetch(`/admin/customers`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ customers, limit, offset, count }) => { + console.log(customers.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/customers' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/customers' \ + -H 'Authorization: Bearer ' + ``` - +
This request doesn’t require any path or query parameters. You can pass it optional parameters used for filtering and pagination. Check out the [API reference](https://docs.medusajs.com/api/admin#customers_getcustomers) to learn more. @@ -142,91 +142,91 @@ Admins can create customer accounts. They have to supply the customer’s creden You can create a customer account by sending a request to the [Create a Customer API Route](https://docs.medusajs.com/api/admin#customers_postcustomers): - + -```ts -medusa.admin.customers.create({ - email, - password, - first_name, - last_name, -}) -.then(({ customer }) => { - console.log(customer.id) -}) -``` - - - - -```tsx -import { useAdminCreateCustomer } from "medusa-react" - -const CreateCustomer = () => { - const createCustomer = useAdminCreateCustomer() - // ... - - const handleCreate = () => { - // ... - createCustomer.mutate({ - first_name, - last_name, + ```ts + medusa.admin.customers.create({ email, password, + first_name, + last_name, }) - } + .then(({ customer }) => { + console.log(customer.id) + }) + ``` - // ... - - return ( -
- {/* Render form */} -
- ) -} +
+ -export default CreateCustomer -``` + ```tsx + import { useAdminCreateCustomer } from "medusa-react" - - + const CreateCustomer = () => { + const createCustomer = useAdminCreateCustomer() + // ... -```ts -fetch(`/admin/customers`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email, - password, - first_name, - last_name, - }), -}) -.then((response) => response.json()) -.then(({ customer }) => { - console.log(customer.id) -}) -``` + const handleCreate = () => { + // ... + createCustomer.mutate({ + first_name, + last_name, + email, + password, + }) + } - - + // ... + + return ( +
+ {/* Render form */} +
+ ) + } -```bash -curl -L -X POST '/admin/customers' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "email": "", - "first_name": "", - "last_name": "", - "password": "" -}' -``` + export default CreateCustomer + ``` -
+
+ + + ```ts + fetch(`/admin/customers`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + email, + password, + first_name, + last_name, + }), + }) + .then((response) => response.json()) + .then(({ customer }) => { + console.log(customer.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/customers' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "email": "", + "first_name": "", + "last_name": "", + "password": "" + }' + ``` + +
This request requires the following body parameters: @@ -249,82 +249,82 @@ An admin can edit a customer’s basic information and credentials. You can edit a customer’s information by sending a request to the [Update a Customer API Route](https://docs.medusajs.com/api/admin#customers_postcustomerscustomer): - + -```ts -medusa.admin.customers.update(customerId, { - first_name, -}) -.then(({ customer }) => { - console.log(customer.id) -}) -``` - - - - -```tsx -import { useAdminUpdateCustomer } from "medusa-react" - -const UpdateCustomer = () => { - const updateCustomer = useAdminUpdateCustomer(customerId) - // ... - - const handleUpdate = () => { - // ... - updateCustomer.mutate({ - email, - password, + ```ts + medusa.admin.customers.update(customerId, { first_name, - last_name, }) - } + .then(({ customer }) => { + console.log(customer.id) + }) + ``` - // ... - - return ( -
- {/* Render form */} -
- ) -} +
+ -export default UpdateCustomer -``` + ```tsx + import { useAdminUpdateCustomer } from "medusa-react" - - + const UpdateCustomer = () => { + const updateCustomer = useAdminUpdateCustomer(customerId) + // ... -```ts -fetch(`/admin/customers/${customerId}`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - first_name, - }), -}) -.then((response) => response.json()) -.then(({ customer }) => { - console.log(customer.id) -}) -``` + const handleUpdate = () => { + // ... + updateCustomer.mutate({ + email, + password, + first_name, + last_name, + }) + } - - + // ... + + return ( +
+ {/* Render form */} +
+ ) + } -```bash -curl -L -X POST '/admin/customers/' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "first_name": "" -}' -``` + export default UpdateCustomer + ``` -
+
+ + + ```ts + fetch(`/admin/customers/${customerId}`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + first_name, + }), + }) + .then((response) => response.json()) + .then(({ customer }) => { + console.log(customer.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/customers/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "first_name": "" + }' + ``` + +
This request accepts any of the customer’s fields as body parameters. In this example, you update the customer’s first name. You can learn more about accepted body parameters in the [API reference](https://docs.medusajs.com/api/admin#customers_postcustomerscustomer). diff --git a/www/apps/docs/content/modules/customers/storefront/implement-customer-profiles.mdx b/www/apps/docs/content/modules/customers/storefront/implement-customer-profiles.mdx index 1401cb3840..476bea9065 100644 --- a/www/apps/docs/content/modules/customers/storefront/implement-customer-profiles.mdx +++ b/www/apps/docs/content/modules/customers/storefront/implement-customer-profiles.mdx @@ -61,76 +61,76 @@ A customer can register with an email and a password to store and manage their d You can register a new customer by sending a request to the [Create a Customer API Route](https://docs.medusajs.com/api/store#customers_postcustomers): - + -```ts -medusa.customers.create({ - email, - password, - first_name, - last_name, -}) -.then(({ customer }) => { - console.log(customer.id) -}) -``` - - - - -```tsx -import { useCreateCustomer } from "medusa-react" - -const RegisterCustomer = () => { - const createCustomer = useCreateCustomer() - // ... - - const handleCreate = () => { - // ... - createCustomer.mutate({ - first_name, - last_name, + ```ts + medusa.customers.create({ email, password, + first_name, + last_name, }) - } + .then(({ customer }) => { + console.log(customer.id) + }) + ``` - // ... - - return ( -
- {/* Render form */} -
- ) -} +
+ -export default RegisterCustomer -``` + ```tsx + import { useCreateCustomer } from "medusa-react" - - + const RegisterCustomer = () => { + const createCustomer = useCreateCustomer() + // ... -```ts -fetch(`/store/customers`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email, - password, - first_name, - last_name, - }), -}) -.then((response) => response.json()) -.then(({ customer }) => { - console.log(customer.id) -}) -``` + const handleCreate = () => { + // ... + createCustomer.mutate({ + first_name, + last_name, + email, + password, + }) + } - + // ... + + return ( +
+ {/* Render form */} +
+ ) + } + + export default RegisterCustomer + ``` + +
+ + + ```ts + fetch(`/store/customers`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + email, + password, + first_name, + last_name, + }), + }) + .then((response) => response.json()) + .then(({ customer }) => { + console.log(customer.id) + }) + ``` + +
This request requires the following body parameters: @@ -153,40 +153,40 @@ A customer can log in to your store to manage their data and make purchases usin You can log in a customer into your store by sending a request to the [Customer Login API Route](https://docs.medusajs.com/api/store#auth_postauth): - + -```ts -medusa.auth.authenticate({ - email, - password, -}) -.then(({ customer }) => { - console.log(customer.id) -}) -``` + ```ts + medusa.auth.authenticate({ + email, + password, + }) + .then(({ customer }) => { + console.log(customer.id) + }) + ``` - - + + -```ts -fetch(`/store/auth`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email, - password, - }), -}) -.then((response) => response.json()) -.then(({ customer }) => { - console.log(customer.id) -}) -``` + ```ts + fetch(`/store/auth`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + email, + password, + }), + }) + .then((response) => response.json()) + .then(({ customer }) => { + console.log(customer.id) + }) + ``` - + This request requires the body parameters `email` and `password`. It returns the customer object in the response. @@ -202,29 +202,29 @@ However, if you’re using the Fetch API, you must include the option `credentia You can log out a customer by sending a request to the [Customer Logout API Route](https://docs.medusajs.com/api/store#auth_deleteauth): - + -```ts -medusa.auth.deleteSession() -.then(() => { - // success -}) -``` + ```ts + medusa.auth.deleteSession() + .then(() => { + // success + }) + ``` - - + + -```ts -fetch(`/store/auth`, { - method: "DELETE", - credentials: "include", -}) -.then(() => { - // success -}) -``` + ```ts + fetch(`/store/auth`, { + method: "DELETE", + credentials: "include", + }) + .then(() => { + // success + }) + ``` - + If this request is successful, the customer’s session will be deleted and they’ll be logged out. @@ -242,43 +242,43 @@ The customer must first enter their account’s email. Then, if an account with You can request to reset a customer’s password by sending a request to the [Request Password Reset API Route](https://docs.medusajs.com/api/store#customers_postcustomerscustomerpasswordtoken): - + -```ts -medusa.customers.generatePasswordToken({ - email, -}) -.then(() => { - // successful -}) -.catch(() => { - // failed -}) -``` + ```ts + medusa.customers.generatePasswordToken({ + email, + }) + .then(() => { + // successful + }) + .catch(() => { + // failed + }) + ``` - - + + -```ts -fetch(`/store/customers/password-token`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email, - }), -}) -.then(() => { - // successful -}) -.catch(() => { - // failed -}) -``` + ```ts + fetch(`/store/customers/password-token`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + email, + }), + }) + .then(() => { + // successful + }) + .catch(() => { + // failed + }) + ``` - + This request requires the body parameter `email`. Its value must be the email associated with the customer’s account. @@ -298,42 +298,42 @@ After the first step, the customer should receive an email with a link to a page You can then reset the customer’s password to the new password they enter by sending a request to the [Reset Password API Route](https://docs.medusajs.com/api/store#customers_postcustomersresetpassword): - + -```ts -medusa.customers.resetPassword({ - email, - password, - token, -}) -.then(({ customer }) => { - console.log(customer.id) -}) -``` + ```ts + medusa.customers.resetPassword({ + email, + password, + token, + }) + .then(({ customer }) => { + console.log(customer.id) + }) + ``` - - + + -```ts -fetch(`/store/customers/password-reset`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email, - password, - token, - }), -}) -.then((response) => response.json()) -.then(({ customer }) => { - console.log(customer.id) -}) -``` + ```ts + fetch(`/store/customers/password-reset`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + email, + password, + token, + }), + }) + .then((response) => response.json()) + .then(({ customer }) => { + console.log(customer.id) + }) + ``` - + This request requires the following body parameters: @@ -353,68 +353,68 @@ A logged-in customer can edit their info, such as their first name or email addr You can edit a customer’s info using the [Update Customer API Route](https://docs.medusajs.com/api/store#customers_postcustomerscustomer): - + -```ts -medusa.customers.update({ - first_name, -}) -.then(({ customer }) => { - console.log(customer.id) -}) -``` - - - - -```tsx -import { useUpdateMe } from "medusa-react" - -const UpdateCustomer = () => { - const updateCustomer = useUpdateMe() - // ... - - const handleUpdate = () => { - // ... - updateCustomer.mutate({ - id: customer_id, + ```ts + medusa.customers.update({ first_name, }) - } + .then(({ customer }) => { + console.log(customer.id) + }) + ``` - // ... - - return ( -
- {/* Render form */} -
- ) -} +
+ -export default UpdateCustomer -``` + ```tsx + import { useUpdateMe } from "medusa-react" - - + const UpdateCustomer = () => { + const updateCustomer = useUpdateMe() + // ... -```ts -fetch(`/store/customers/me`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - first_name, - }), -}) -.then((response) => response.json()) -.then(({ customer }) => { - console.log(customer.id) -}) -``` + const handleUpdate = () => { + // ... + updateCustomer.mutate({ + id: customer_id, + first_name, + }) + } - + // ... + + return ( +
+ {/* Render form */} +
+ ) + } + + export default UpdateCustomer + ``` + +
+ + + ```ts + fetch(`/store/customers/me`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + first_name, + }), + }) + .then((response) => response.json()) + .then(({ customer }) => { + console.log(customer.id) + }) + ``` + +
This request accepts any of the customer’s details that should be updated as body parameters. In the example above, the `first_name` of the customer is updated. You can check out the [API reference](https://docs.medusajs.com/api/api/store#customers_postcustomerscustomer) for a full list of accepted body parameters. @@ -438,62 +438,62 @@ The customer object returned in the requests mentioned in this document include You can add a shipping address to a customer’s account by sending a request to the [Add a Shipping Address API Route](https://docs.medusajs.com/api/store#customers_postcustomerscustomeraddresses): - + -```ts -medusa.customers.addresses.addAddress({ - address: { - first_name, - last_name, - address_1, - city, - country_code, - postal_code, - phone, - company, - address_2, - province, - metadata, - }, -}) -.then(({ customer }) => { - console.log(customer.id) -}) -``` + ```ts + medusa.customers.addresses.addAddress({ + address: { + first_name, + last_name, + address_1, + city, + country_code, + postal_code, + phone, + company, + address_2, + province, + metadata, + }, + }) + .then(({ customer }) => { + console.log(customer.id) + }) + ``` - - + + -```ts -fetch(`/store/customers/me/addresses`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - address: { - first_name, - last_name, - address_1, - city, - country_code, - postal_code, - phone, - company, - address_2, - province, - metadata, - }, - }), -}) -.then((response) => response.json()) -.then(({ customer }) => { - console.log(customer.id) -}) -``` + ```ts + fetch(`/store/customers/me/addresses`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + address: { + first_name, + last_name, + address_1, + city, + country_code, + postal_code, + phone, + company, + address_2, + province, + metadata, + }, + }), + }) + .then((response) => response.json()) + .then(({ customer }) => { + console.log(customer.id) + }) + ``` - + This request requires an `address` object as a body parameter. The `address` object must have the following properties: @@ -514,40 +514,40 @@ This request returns the updated customer object in the response. You can edit a customer’s shipping address using the [Update a Shipping Address API Route](https://docs.medusajs.com/api/store#customers_postcustomerscustomeraddressesaddress): - + -```ts -medusa.customers.addresses.updateAddress(addressId, { - first_name, -}) -.then(({ customer }) => { - console.log(customer.id) -}) -``` - - - - -```ts -fetch(`/store/customers/me/addresses/${addressId}`, - { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ + ```ts + medusa.customers.addresses.updateAddress(addressId, { first_name, - }), - } -) -.then((response) => response.json()) -.then(({ customer }) => { - console.log(customer.id) -}) -``` + }) + .then(({ customer }) => { + console.log(customer.id) + }) + ``` - + + + + ```ts + fetch(`/store/customers/me/addresses/${addressId}`, + { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + first_name, + }), + } + ) + .then((response) => response.json()) + .then(({ customer }) => { + console.log(customer.id) + }) + ``` + + This request requires the address’s ID as a path parameter. It accepts as a body parameter any of the address’s properties. In the example above, the `first_name` of the shipping address is updated. You can check the [API reference](https://docs.medusajs.com/api/store#customers_postcustomerscustomeraddressesaddress) for all the available body parameters. @@ -559,32 +559,32 @@ This request returns the updated customer object in the response. You can delete a shipping address by sending a request to the [Delete an Address API Route](https://docs.medusajs.com/api/store#customers_deletecustomerscustomeraddressesaddress): - + -```ts -medusa.customers.addresses.deleteAddress(addressId) -.then(({ customer }) => { - console.log(customer.id) -}) -``` + ```ts + medusa.customers.addresses.deleteAddress(addressId) + .then(({ customer }) => { + console.log(customer.id) + }) + ``` - - + + -```ts -fetch(`/store/customers/me/addresses/${addressId}`, - { - method: "DELETE", - credentials: "include", - } -) -.then((response) => response.json()) -.then(({ customer }) => { - console.log(customer.id) -}) -``` + ```ts + fetch(`/store/customers/me/addresses/${addressId}`, + { + method: "DELETE", + credentials: "include", + } + ) + .then((response) => response.json()) + .then(({ customer }) => { + console.log(customer.id) + }) + ``` - + This request requires the address’s ID as a path parameter. It returns in the response the updated customer object. @@ -598,58 +598,58 @@ Logged-in customers can see their orders along with the orders’ details. You can retrieve a customer’s orders by sending a request to the [List Orders API Route](https://docs.medusajs.com/api/store#customers_getcustomerscustomerorders): - + -```ts -medusa.customers.listOrders() -.then(({ orders, limit, offset, count }) => { - console.log(orders) -}) -``` + ```ts + medusa.customers.listOrders() + .then(({ orders, limit, offset, count }) => { + console.log(orders) + }) + ``` - - + + -```tsx -import { useCustomerOrders } from "medusa-react" -import { Order } from "@medusajs/medusa" + ```tsx + import { useCustomerOrders } from "medusa-react" + import { Order } from "@medusajs/medusa" -const Orders = () => { - // refetch a function that can be used to - // re-retrieve orders after the customer logs in - const { orders, isLoading, refetch } = useCustomerOrders() + const Orders = () => { + // refetch a function that can be used to + // re-retrieve orders after the customer logs in + const { orders, isLoading, refetch } = useCustomerOrders() - return ( -
- {isLoading && Loading orders...} - {orders?.length && ( -
    - {orders.map((order: Order) => ( -
  • {order.display_id}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading orders...} + {orders?.length && ( +
    + {orders.map((order: Order) => ( +
  • {order.display_id}
  • + ))} +
+ )} +
+ ) + } -export default Orders -``` + export default Orders + ``` -
- + + -```ts -fetch(`/store/customers/me/orders`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ orders, limit, offset, count }) => { - console.log(orders) -}) -``` + ```ts + fetch(`/store/customers/me/orders`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ orders, limit, offset, count }) => { + console.log(orders) + }) + ``` - +
This request doesn’t require any path or query parameters. You can, however, send optional query parameters used for filters, pagination, and sorting. You can learn more in the [API reference](https://docs.medusajs.com/api/store#customers_getcustomerscustomerorders). diff --git a/www/apps/docs/content/modules/discounts/admin/manage-discounts.mdx b/www/apps/docs/content/modules/discounts/admin/manage-discounts.mdx index 45974a9296..983b10f28a 100644 --- a/www/apps/docs/content/modules/discounts/admin/manage-discounts.mdx +++ b/www/apps/docs/content/modules/discounts/admin/manage-discounts.mdx @@ -67,51 +67,15 @@ You can learn more about [authenticating as an admin user in the API reference]( You can create a discount by sending a request to the [Create Discount API Route](https://docs.medusajs.com/api/admin#discounts_postdiscounts): - + -```ts -import { - AllocationType, - DiscountRuleType, -} from "@medusajs/medusa" -// ... -medusa.admin.discounts.create({ - code, - rule: { - type: DiscountRuleType.FIXED, - value: 10, - allocation: AllocationType.ITEM, - }, - regions: [ - regionId, - ], - is_dynamic: false, - is_disabled: false, -}) -.then(({ discount }) => { - console.log(discount.id) -}) -``` - - - - -```tsx -import { - useAdminCreateDiscount, -} from "medusa-react" -import { - AllocationType, - DiscountRuleType, -} from "@medusajs/medusa" - -const CreateDiscount = () => { - const createDiscount = useAdminCreateDiscount() - // ... - - const handleCreate = () => { + ```ts + import { + AllocationType, + DiscountRuleType, + } from "@medusajs/medusa" // ... - createDiscount.mutate({ + medusa.admin.discounts.create({ code, rule: { type: DiscountRuleType.FIXED, @@ -119,72 +83,108 @@ const CreateDiscount = () => { allocation: AllocationType.ITEM, }, regions: [ - regionId, + regionId, ], is_dynamic: false, is_disabled: false, }) - } + .then(({ discount }) => { + console.log(discount.id) + }) + ``` - // ... -} + + -export default CreateDiscount -``` + ```tsx + import { + useAdminCreateDiscount, + } from "medusa-react" + import { + AllocationType, + DiscountRuleType, + } from "@medusajs/medusa" - - + const CreateDiscount = () => { + const createDiscount = useAdminCreateDiscount() + // ... -```ts -fetch(`/admin/discounts`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - code, - rule: { - type: "fixed", - value: 10, - allocation: "item", - }, - regions: [ - regionId, - ], - is_dynamic: false, - is_disabled: false, - }), -}) -.then((response) => response.json()) -.then(({ discount }) => { - console.log(discount.id) -}) -``` + const handleCreate = () => { + // ... + createDiscount.mutate({ + code, + rule: { + type: DiscountRuleType.FIXED, + value: 10, + allocation: AllocationType.ITEM, + }, + regions: [ + regionId, + ], + is_dynamic: false, + is_disabled: false, + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/discounts' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "code": "", - "rule": { - "type": "fixed", - "value": 10, - "allocation": "item" - }, - "regions": [ - "" - ], - "is_dynamic": false, - "is_disabled": false -}' -``` + export default CreateDiscount + ``` - + + + + ```ts + fetch(`/admin/discounts`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + code, + rule: { + type: "fixed", + value: 10, + allocation: "item", + }, + regions: [ + regionId, + ], + is_dynamic: false, + is_disabled: false, + }), + }) + .then((response) => response.json()) + .then(({ discount }) => { + console.log(discount.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/discounts' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "code": "", + "rule": { + "type": "fixed", + "value": 10, + "allocation": "item" + }, + "regions": [ + "" + ], + "is_dynamic": false, + "is_disabled": false + }' + ``` + + This request accepts [many request-body parameters](https://docs.medusajs.com/api/admin#discounts_postdiscounts) including: @@ -207,73 +207,73 @@ You can update any of the discount’s information, configurations, and conditio For example, you can update the discount’s description and status by sending the following request: - + -```ts -medusa.admin.discounts.update(discountId, { - is_disabled: true, -}) -.then(({ discount }) => { - console.log(discount.id) -}) -``` - - - - -```tsx -import { useAdminUpdateDiscount } from "medusa-react" - -const UpdateDiscount = () => { - const updateDiscount = useAdminUpdateDiscount(discount_id) - // ... - - const handleUpdate = () => { - // ... - updateDiscount.mutate({ + ```ts + medusa.admin.discounts.update(discountId, { is_disabled: true, }) - } + .then(({ discount }) => { + console.log(discount.id) + }) + ``` - // ... -} + + -export default UpdateDiscount -``` + ```tsx + import { useAdminUpdateDiscount } from "medusa-react" - - + const UpdateDiscount = () => { + const updateDiscount = useAdminUpdateDiscount(discount_id) + // ... -```ts -fetch(`/admin/discounts/${discountId}`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - is_disabled: true, - }), -}) -.then((response) => response.json()) -.then(({ discount }) => { - console.log(discount.id) -}) -``` + const handleUpdate = () => { + // ... + updateDiscount.mutate({ + is_disabled: true, + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/discounts/' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "is_disabled": true -}' -``` + export default UpdateDiscount + ``` - + + + + ```ts + fetch(`/admin/discounts/${discountId}`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + is_disabled: true, + }), + }) + .then((response) => response.json()) + .then(({ discount }) => { + console.log(discount.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/discounts/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "is_disabled": true + }' + ``` + + This request accepts the discount ID as a path parameter. You can pass the parameters you want to update in the request body. In the example above, is_disabled` parameter to update it. @@ -297,95 +297,95 @@ You can learn more about conditions and conditions types in the [Discount Archit You can send a request to the [Create Condition API Route](https://docs.medusajs.com/api/admin#discounts_postdiscountsdiscountconditions) to create a condition in a discount: - + -```ts -import { DiscountConditionOperator } from "@medusajs/medusa" -// ... -medusa.admin.discounts.createCondition(discount_id, { - operator: DiscountConditionOperator.IN, - products: [ - productId, - ], -}) -.then(({ discount }) => { - console.log(discount.id) -}) -``` - - - - -```tsx -import { useAdminDiscountCreateCondition } from "medusa-react" -import { DiscountConditionOperator } from "@medusajs/medusa" - -const Discount = () => { - const createCondition = useAdminDiscountCreateCondition( - discount_id - ) - // ... - - const handleCreateCondition = ( - operator: DiscountConditionOperator, - productId: string - ) => { + ```ts + import { DiscountConditionOperator } from "@medusajs/medusa" // ... - createCondition.mutate({ - operator, + medusa.admin.discounts.createCondition(discount_id, { + operator: DiscountConditionOperator.IN, products: [ productId, ], }) - } + .then(({ discount }) => { + console.log(discount.id) + }) + ``` - // ... -} + + -export default Discount -``` + ```tsx + import { useAdminDiscountCreateCondition } from "medusa-react" + import { DiscountConditionOperator } from "@medusajs/medusa" - - + const Discount = () => { + const createCondition = useAdminDiscountCreateCondition( + discount_id + ) + // ... -```ts -fetch(`/admin/discounts/${discountId}/conditions`, - { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - operator: "in", - products: [ - productId, - ], - }), - } -) -.then((response) => response.json()) -.then(({ discount }) => { - console.log(discount.id) -}) -``` + const handleCreateCondition = ( + operator: DiscountConditionOperator, + productId: string + ) => { + // ... + createCondition.mutate({ + operator, + products: [ + productId, + ], + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/discounts//conditions' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "operator": "in", - "products": [ - "" - ] -}' -``` + export default Discount + ``` - + + + + ```ts + fetch(`/admin/discounts/${discountId}/conditions`, + { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + operator: "in", + products: [ + productId, + ], + }), + } + ) + .then((response) => response.json()) + .then(({ discount }) => { + console.log(discount.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/discounts//conditions' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "operator": "in", + "products": [ + "" + ] + }' + ``` + + This request accepts the discount ID as a path parameter. @@ -410,92 +410,92 @@ This request returns the full `discount` object in the response which includes a You can retrieve a condition and its resources by sending a request to the [Get Condition API Route](https://docs.medusajs.com/api/admin#discounts_getdiscountsdiscountconditionscondition): - + -```ts -medusa.admin.discounts.getCondition( - discountId, - conditionId, - { - expand: "products", - } -) -.then(({ discount_condition }) => { - console.log( - discount_condition.id, - discount_condition.products - ) -}) -``` + ```ts + medusa.admin.discounts.getCondition( + discountId, + conditionId, + { + expand: "products", + } + ) + .then(({ discount_condition }) => { + console.log( + discount_condition.id, + discount_condition.products + ) + }) + ``` - - + + -```tsx -import { useAdminGetDiscountCondition } from "medusa-react" -import { Product } from "@medusajs/medusa" + ```tsx + import { useAdminGetDiscountCondition } from "medusa-react" + import { Product } from "@medusajs/medusa" -const DiscountCondition = () => { - const { - discount_condition, - isLoading, - } = useAdminGetDiscountCondition( - discount_id, - conditionId - ) - // ... + const DiscountCondition = () => { + const { + discount_condition, + isLoading, + } = useAdminGetDiscountCondition( + discount_id, + conditionId + ) + // ... - return ( -
- {isLoading && Loading} - {discount_condition && ( - <> - {discount_condition.id} -
    - {discount_condition.products.map( - (product: Product) => ( -
  • {product.title}
  • - ) - )} -
- - )} -
- ) -} + return ( +
+ {isLoading && Loading} + {discount_condition && ( + <> + {discount_condition.id} +
    + {discount_condition.products.map( + (product: Product) => ( +
  • {product.title}
  • + ) + )} +
+ + )} +
+ ) + } -export default DiscountCondition -``` + export default DiscountCondition + ``` -
- + + -```ts -fetch( - `/admin/discounts/${discountId}` + - `/conditions/${conditionId}&expand=products`, - { - credentials: "include", - } -) -.then((response) => response.json()) -.then(({ discount_condition }) => { - console.log( - discount_condition.id, - discount_condition.products - ) -}) -``` + ```ts + fetch( + `/admin/discounts/${discountId}` + + `/conditions/${conditionId}&expand=products`, + { + credentials: "include", + } + ) + .then((response) => response.json()) + .then(({ discount_condition }) => { + console.log( + discount_condition.id, + discount_condition.products + ) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/discounts//conditions/&expand=products' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/discounts//conditions/&expand=products' \ + -H 'Authorization: Bearer ' + ``` - +
This request accepts as path parameters the discount ID and the condition ID. You can optionally pass a query parameter `expand` which specifies which relations to include in the returned object. @@ -511,93 +511,93 @@ You can update a condition’s resources using the [Update Condition API Route]( For example, to update the products in a condition: - + -```ts -medusa.admin.discounts.updateCondition( - discountId, - conditionId, { - products: [ - productId1, - productId2, - ], - } -) -.then(({ discount }) => { - console.log(discount.id) -}) -``` - - - - -```tsx -import { useAdminDiscountUpdateCondition } from "medusa-react" -import { Product } from "@medusajs/medusa" - -const DiscountCondition = () => { - const updateCondition = useAdminDiscountUpdateCondition( - discount_id, - conditionId - ) - // ... - - const handleUpdateCondition = (productIds: string[]) => { - updateCondition.mutate({ - products: productIds, + ```ts + medusa.admin.discounts.updateCondition( + discountId, + conditionId, { + products: [ + productId1, + productId2, + ], + } + ) + .then(({ discount }) => { + console.log(discount.id) }) - } + ``` - // ... -} + + -export default DiscountCondition -``` + ```tsx + import { useAdminDiscountUpdateCondition } from "medusa-react" + import { Product } from "@medusajs/medusa" - - + const DiscountCondition = () => { + const updateCondition = useAdminDiscountUpdateCondition( + discount_id, + conditionId + ) + // ... + + const handleUpdateCondition = (productIds: string[]) => { + updateCondition.mutate({ + products: productIds, + }) + } + + // ... + } + + export default DiscountCondition + ``` + + + -```ts -fetch( - `/admin/discounts/${discountId}/conditions/${conditionId}`, - { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - products: [ - productId1, - productId2, - ], - }), - } -) -.then((response) => response.json()) -.then(({ discount }) => { - console.log(discount.id) -}) -``` + ```ts + fetch( + `/admin/discounts/${discountId}/conditions/${conditionId}`, + { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + products: [ + productId1, + productId2, + ], + }), + } + ) + .then((response) => response.json()) + .then(({ discount }) => { + console.log(discount.id) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/discounts//conditions/' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "products": [ - "", - "" - ] -}' -``` + ```bash + curl -L -X POST '/admin/discounts//conditions/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "products": [ + "", + "" + ] + }' + ``` - + This request accepts as a path parameter the discount ID and the condition ID. In its body, it accepts the resources of the same type that were used when the condition was created. @@ -611,68 +611,68 @@ This request returns the full `discount` object with the updated condition in th You can delete a condition by sending a request to the [Delete Condition API Route](https://docs.medusajs.com/api/admin#discounts_deletediscountsdiscountconditionscondition): - + -```ts -medusa.admin.discounts.deleteCondition( - discountId, - conditionId -) -.then(({ discount }) => { - console.log(discount) -}) -``` + ```ts + medusa.admin.discounts.deleteCondition( + discountId, + conditionId + ) + .then(({ discount }) => { + console.log(discount) + }) + ``` - - + + -```tsx -import { useAdminDiscountRemoveCondition } from "medusa-react" + ```tsx + import { useAdminDiscountRemoveCondition } from "medusa-react" -const Discount = () => { - const deleteCondition = useAdminDiscountRemoveCondition( - discount_id - ) - // ... + const Discount = () => { + const deleteCondition = useAdminDiscountRemoveCondition( + discount_id + ) + // ... - const handleUpdateCondition = (conditionId: string) => { - deleteCondition.mutate(conditionId) - } + const handleUpdateCondition = (conditionId: string) => { + deleteCondition.mutate(conditionId) + } - // ... -} + // ... + } -export default Discount -``` + export default Discount + ``` - - + + -```ts -fetch( - `/admin/discounts/${discountId}/conditions/${conditionId}`, - { - method: "DELETE", - credentials: "include", - } -) -.then((response) => response.json()) -.then(({ discount }) => { - console.log(discount.id) -}) -``` + ```ts + fetch( + `/admin/discounts/${discountId}/conditions/${conditionId}`, + { + method: "DELETE", + credentials: "include", + } + ) + .then((response) => response.json()) + .then(({ discount }) => { + console.log(discount.id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/discounts//conditions/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/discounts//conditions/' \ + -H 'Authorization: Bearer ' + ``` - + This request accepts as a path parameter the discount ID and the condition ID. @@ -686,58 +686,58 @@ It returns the `discount` object in the response. You can delete a discount by sending a request to the [Delete Discount API Route](https://docs.medusajs.com/api/admin#discounts_deletediscountsdiscount): - + -```ts -medusa.admin.discounts.delete(discount_id) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + medusa.admin.discounts.delete(discount_id) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```tsx -import { useAdminDeleteDiscount } from "medusa-react" + ```tsx + import { useAdminDeleteDiscount } from "medusa-react" -const Discount = () => { - const deleteDiscount = useAdminDeleteDiscount(discount_id) - // ... + const Discount = () => { + const deleteDiscount = useAdminDeleteDiscount(discount_id) + // ... - const handleDelete = () => { - deleteDiscount.mutate() - } + const handleDelete = () => { + deleteDiscount.mutate() + } - // ... -} + // ... + } -export default Discount -``` + export default Discount + ``` - - + + -```ts -fetch(`/admin/discounts/${discountId}`, { - method: "DELETE", - credentials: "include", -}) -.then((response) => response.json()) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + fetch(`/admin/discounts/${discountId}`, { + method: "DELETE", + credentials: "include", + }) + .then((response) => response.json()) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/discounts/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/discounts/' \ + -H 'Authorization: Bearer ' + ``` - + This request accepts the discount ID as a path parameter. diff --git a/www/apps/docs/content/modules/discounts/storefront/use-discounts-in-checkout.mdx b/www/apps/docs/content/modules/discounts/storefront/use-discounts-in-checkout.mdx index d446bb200a..92f52a33d0 100644 --- a/www/apps/docs/content/modules/discounts/storefront/use-discounts-in-checkout.mdx +++ b/www/apps/docs/content/modules/discounts/storefront/use-discounts-in-checkout.mdx @@ -65,81 +65,81 @@ The customer can enter a discount code during the checkout flow to benefit from You can add a discount to a customer’s cart by sending the [Update Cart request](https://docs.medusajs.com/api/store#carts_postcartscart): - + -```ts -medusa.carts.update(cartId, { - discounts: [ - { - code, - }, - ], -}) -.then(({ cart }) => { - console.log(cart.discounts) -}) -.catch((e) => { - // display an error to the customer - alert("Discount is invalid") -}) -``` - - - - -```tsx -import { useCart } from "medusa-react" - -const Cart = () => { - // ... - - const { updateCart } = useCart() - - const addDiscount = (code: string) => { - updateCart.mutate({ + ```ts + medusa.carts.update(cartId, { discounts: [ { code, }, ], }) - } + .then(({ cart }) => { + console.log(cart.discounts) + }) + .catch((e) => { + // display an error to the customer + alert("Discount is invalid") + }) + ``` - // ... -} + + -export default Cart -``` + ```tsx + import { useCart } from "medusa-react" - - + const Cart = () => { + // ... -```ts -fetch(`/store/carts/${cartId}`, { - method: "POST", - credentials: "include", - body: JSON.stringify({ - discounts: [ - { - code, + const { updateCart } = useCart() + + const addDiscount = (code: string) => { + updateCart.mutate({ + discounts: [ + { + code, + }, + ], + }) + } + + // ... + } + + export default Cart + ``` + + + + + ```ts + fetch(`/store/carts/${cartId}`, { + method: "POST", + credentials: "include", + body: JSON.stringify({ + discounts: [ + { + code, + }, + ], + }), + headers: { + "Content-Type": "application/json", }, - ], - }), - headers: { - "Content-Type": "application/json", - }, -}) -.then((response) => response.json()) -.then(({ cart }) => { - console.log(cart.discounts) -}) -.catch((e) => { - // display an error to the customer - alert("Discount is invalid") -}) -``` + }) + .then((response) => response.json()) + .then(({ cart }) => { + console.log(cart.discounts) + }) + .catch((e) => { + // display an error to the customer + alert("Discount is invalid") + }) + ``` - + This request requires the customer’s cart ID as a path parameter. In the body of the request, you can update many cart-related details, including adding discounts by passing the `discounts` field. It is an array of objects, with each object having a property `code` with its value being the discount’s unique code. @@ -256,30 +256,30 @@ The customer can choose to remove a discount from their cart. You can remove a discount from a customer’s cart using the [Remove Discount request](https://docs.medusajs.com/api/store#carts_deletecartscartdiscountsdiscount): - + -```ts -medusa.carts.deleteDiscount(cartId, code) -.then(({ cart }) => { - console.log(cart.discounts) -}) -``` + ```ts + medusa.carts.deleteDiscount(cartId, code) + .then(({ cart }) => { + console.log(cart.discounts) + }) + ``` - - + + -```ts -fetch(`/store/carts/${cartId}/discounts/${code}`, { - method: "DELETE", - credentials: "include", -}) -.then((response) => response.json()) -.then(({ cart }) => { - console.log(cart.discounts) -}) -``` + ```ts + fetch(`/store/carts/${cartId}/discounts/${code}`, { + method: "DELETE", + credentials: "include", + }) + .then((response) => response.json()) + .then(({ cart }) => { + console.log(cart.discounts) + }) + ``` - + This request accepts the cart ID and the code of the discount to remove. If the discount is removed successfully, the request returns the updated cart object, where you won’t find the discount in the `discounts` array anymore. diff --git a/www/apps/docs/content/modules/gift-cards/admin/manage-gift-cards.mdx b/www/apps/docs/content/modules/gift-cards/admin/manage-gift-cards.mdx index c76105a20d..1d104fa2a7 100644 --- a/www/apps/docs/content/modules/gift-cards/admin/manage-gift-cards.mdx +++ b/www/apps/docs/content/modules/gift-cards/admin/manage-gift-cards.mdx @@ -66,84 +66,84 @@ As gift cards are, before purchase, essentially products, you’ll be using prod You can retrieve the gift card products by sending a request to the [List Products API Route](https://docs.medusajs.com/api/admin#products_getproducts), but filtering the products with the `is_giftcard` flag: - + -```ts -medusa.admin.products.list({ - is_giftcard: true, -}) -.then(({ products, limit, offset, count }) => { - if (products.length) { - // gift card products exist - } else { - // no gift card products are created - } -}) -``` + ```ts + medusa.admin.products.list({ + is_giftcard: true, + }) + .then(({ products, limit, offset, count }) => { + if (products.length) { + // gift card products exist + } else { + // no gift card products are created + } + }) + ``` - - + + -```tsx -import { Product } from "@medusajs/medusa" -import { - PricedProduct, -} from "@medusajs/medusa/dist/types/pricing" -import { useAdminProducts } from "medusa-react" + ```tsx + import { Product } from "@medusajs/medusa" + import { + PricedProduct, + } from "@medusajs/medusa/dist/types/pricing" + import { useAdminProducts } from "medusa-react" -const GiftCard = () => { - const { products, isLoading } = useAdminProducts({ - is_giftcard: true, - }) + const GiftCard = () => { + const { products, isLoading } = useAdminProducts({ + is_giftcard: true, + }) - return ( -
- {isLoading && Loading...} - {products && products.length > 0 && ( -
    - {products.map( - (product: (Product | PricedProduct)) => ( -
  • {product.title}
  • - ) + return ( +
    + {isLoading && Loading...} + {products && products.length > 0 && ( +
      + {products.map( + (product: (Product | PricedProduct)) => ( +
    • {product.title}
    • + ) + )} +
    )} -
- )} - {products && !products.length && ( - No Gift Cards - )} -
- ) -} + {products && !products.length && ( + No Gift Cards + )} + + ) + } -export default GiftCard -``` + export default GiftCard + ``` -
- + + -```ts -fetch(`/admin/products?is_giftcard=true`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ products, limit, offset, count }) => { - if (products.length) { - // gift card products exist - } else { - // no gift card products are created - } -}) -``` + ```ts + fetch(`/admin/products?is_giftcard=true`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ products, limit, offset, count }) => { + if (products.length) { + // gift card products exist + } else { + // no gift card products are created + } + }) + ``` - - + + -```bash -curl -L -X GET '/admin/products?is_giftcard=true' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/products?is_giftcard=true' \ + -H 'Authorization: Bearer ' + ``` - +
The List Products API Route accepts a variety of query parameters that can be used to filter the products. One of them is `is_giftcard`. When set to `true`, it will only retrieve the gift card products. @@ -155,59 +155,13 @@ The request returns the `products` array in the response which holds the gift ca You can create a gift card product by sending a request to the [Create a Product API Route](https://docs.medusajs.com/api/admin#products_postproducts): - + -```ts -import { ProductStatus } from "@medusajs/medusa" -// ... + ```ts + import { ProductStatus } from "@medusajs/medusa" + // ... -medusa.admin.products.create({ - title: "My Gift Card", - is_giftcard: true, - discountable: false, - status: ProductStatus.PUBLISHED, - options: [ - { - title: "Denomination", - }, - ], - variants: [ - { - title: "1", - inventory_quantity: 0, - manage_inventory: false, - prices: [ - { - amount: 2000, - currency_code: "usd", - }, - ], - options: [ - { - value: "2000", - }, - ], - }, - ], -}) -.then(({ product }) => { - console.log(product.id) -}) -``` - - - - -```tsx -import { useAdminCreateProduct } from "medusa-react" -import { ProductStatus } from "@medusajs/medusa" - -const CreateGiftCard = () => { - const createGiftCard = useAdminCreateProduct() - // ... - - const handleCreate = () => { - createGiftCard.mutate({ + medusa.admin.products.create({ title: "My Gift Card", is_giftcard: true, discountable: false, @@ -236,99 +190,145 @@ const CreateGiftCard = () => { }, ], }) - } + .then(({ product }) => { + console.log(product.id) + }) + ``` - // ... -} + + -export default CreateGiftCard -``` + ```tsx + import { useAdminCreateProduct } from "medusa-react" + import { ProductStatus } from "@medusajs/medusa" - - + const CreateGiftCard = () => { + const createGiftCard = useAdminCreateProduct() + // ... -```ts -fetch(`/admin/products`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - title: "My Gift Card", - is_giftcard: true, - discountable: false, - status: "published", - options: [ - { - title: "Denomination", - }, - ], - variants: [ - { - title: "1", - inventory_quantity: 0, - manage_inventory: false, - prices: [ + const handleCreate = () => { + createGiftCard.mutate({ + title: "My Gift Card", + is_giftcard: true, + discountable: false, + status: ProductStatus.PUBLISHED, + options: [ { - amount: 2000, - currency_code: "usd", + title: "Denomination", }, - ], + ], + variants: [ + { + title: "1", + inventory_quantity: 0, + manage_inventory: false, + prices: [ + { + amount: 2000, + currency_code: "usd", + }, + ], + options: [ + { + value: "2000", + }, + ], + }, + ], + }) + } + + // ... + } + + export default CreateGiftCard + ``` + + + + + ```ts + fetch(`/admin/products`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + title: "My Gift Card", + is_giftcard: true, + discountable: false, + status: "published", options: [ - { - value: "2000", - }, + { + title: "Denomination", + }, ], - }, - ], - }), -}) -.then((response) => response.json()) -.then(({ product }) => { - console.log(product.id) -}) -``` - - - - -```bash -curl -L -X POST '/admin/products' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "title": "My Gift Card", - "is_giftcard": true, - "discountable": false, - "status": "published", - "options": [ - { - "title": "Denomination" - } - ], - "variants": [ - { - "title": "1", - "inventory_quantity": 0, - "manage_inventory": false, - "prices": [ - { - "amount": 2000, - "currency_code": "usd" - } + variants: [ + { + title: "1", + inventory_quantity: 0, + manage_inventory: false, + prices: [ + { + amount: 2000, + currency_code: "usd", + }, + ], + options: [ + { + value: "2000", + }, + ], + }, ], + }), + }) + .then((response) => response.json()) + .then(({ product }) => { + console.log(product.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/products' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "title": "My Gift Card", + "is_giftcard": true, + "discountable": false, + "status": "published", "options": [ - { - "value": "2000" - } + { + "title": "Denomination" + } + ], + "variants": [ + { + "title": "1", + "inventory_quantity": 0, + "manage_inventory": false, + "prices": [ + { + "amount": 2000, + "currency_code": "usd" + } + ], + "options": [ + { + "value": "2000" + } + ] + } ] - } - ] -}' -``` + }' + ``` - + This request requires the `title` body parameter, which is the name given to the gift card. To add the gift card product, you need to supply the following parameters: @@ -356,72 +356,72 @@ After creating a gift card, merchants can update it or its denomination. You can update a gift card product’s details by sending a request to the [Update a Product API Route](https://docs.medusajs.com/api/admin#products_postproductsproduct): - + -```ts -medusa.admin.products.update(giftCardId, { - description: "The best gift card", -}) -.then(({ product }) => { - console.log(product.id) -}) -``` - - - - -```tsx -import { useAdminUpdateProduct } from "medusa-react" - -const UpdateGiftCard = () => { - const createGiftCard = useAdminUpdateProduct(giftCardId) - // ... - - const handleUpdate = () => { - createGiftCard.mutate({ + ```ts + medusa.admin.products.update(giftCardId, { description: "The best gift card", }) - } + .then(({ product }) => { + console.log(product.id) + }) + ``` - // ... -} + + -export default UpdateGiftCard -``` + ```tsx + import { useAdminUpdateProduct } from "medusa-react" - - + const UpdateGiftCard = () => { + const createGiftCard = useAdminUpdateProduct(giftCardId) + // ... -```ts -fetch(`/admin/products/${giftCardId}`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - description: "The best gift card", - }), -}) -.then((response) => response.json()) -.then(({ product }) => { - console.log(product.id) -}) -``` + const handleUpdate = () => { + createGiftCard.mutate({ + description: "The best gift card", + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/products/' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "description": "The best gift card" -}' -``` + export default UpdateGiftCard + ``` - + + + + ```ts + fetch(`/admin/products/${giftCardId}`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + description: "The best gift card", + }), + }) + .then((response) => response.json()) + .then(({ product }) => { + console.log(product.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/products/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "description": "The best gift card" + }' + ``` + + This request requires the ID of the gift card product as a path parameter. You can pass in its body parameters, any of the gift card’s properties to update. @@ -435,58 +435,58 @@ This request returns the updated gift card product in the response. You can delete a gift card product by sending a request to the [Delete a Product API Route](https://docs.medusajs.com/api/admin#products_deleteproductsproduct): - + -```ts -medusa.admin.products.delete(giftCardId) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + medusa.admin.products.delete(giftCardId) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```tsx -import { useAdminDeleteProduct } from "medusa-react" + ```tsx + import { useAdminDeleteProduct } from "medusa-react" -const GiftCard = () => { - const deleteGiftCard = useAdminDeleteProduct(giftCardId) - // ... + const GiftCard = () => { + const deleteGiftCard = useAdminDeleteProduct(giftCardId) + // ... - const handleDelete = () => { - deleteGiftCard.mutate() - } + const handleDelete = () => { + deleteGiftCard.mutate() + } - // ... -} + // ... + } -export default GiftCard -``` + export default GiftCard + ``` - - + + -```ts -fetch(`/admin/products/${giftCardId}`, { - method: "DELETE", - credentials: "include", -}) -.then((response) => response.json()) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + fetch(`/admin/products/${giftCardId}`, { + method: "DELETE", + credentials: "include", + }) + .then((response) => response.json()) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/products/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/products/' \ + -H 'Authorization: Bearer ' + ``` - + This request requires the ID of the gift card product as a path parameter. @@ -508,67 +508,67 @@ This section covers how to manage custom gift cards. You can create an unlimited You can retrieve all custom gift cards by sending a request to the [List Gift Cards API Route](https://docs.medusajs.com/api/admin#gift-cards_getgiftcards): - + -```ts -medusa.admin.giftCards.list() -.then(({ gift_cards, limit, offset, count }) => { - console.log(gift_cards.length) -}) -``` + ```ts + medusa.admin.giftCards.list() + .then(({ gift_cards, limit, offset, count }) => { + console.log(gift_cards.length) + }) + ``` - - + + -```tsx -import { GiftCard } from "@medusajs/medusa" -import { useAdminGiftCards } from "medusa-react" + ```tsx + import { GiftCard } from "@medusajs/medusa" + import { useAdminGiftCards } from "medusa-react" -const CustomGiftCards = () => { - const { gift_cards, isLoading } = useAdminGiftCards() - - return ( -
- {isLoading && Loading...} - {gift_cards && !gift_cards.length && ( - No custom gift cards... - )} - {gift_cards && gift_cards.length > 0 && ( -
    - {gift_cards.map((giftCard: GiftCard) => ( -
  • {giftCard.code}
  • - ))} -
- )} -
- ) -} + const CustomGiftCards = () => { + const { gift_cards, isLoading } = useAdminGiftCards() + + return ( +
+ {isLoading && Loading...} + {gift_cards && !gift_cards.length && ( + No custom gift cards... + )} + {gift_cards && gift_cards.length > 0 && ( +
    + {gift_cards.map((giftCard: GiftCard) => ( +
  • {giftCard.code}
  • + ))} +
+ )} +
+ ) + } -export default CustomGiftCards -``` + export default CustomGiftCards + ``` -
- + + -```ts -fetch(`/admin/gift-cards`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ gift_cards, limit, offset, count }) => { - console.log(gift_cards.length) -}) -``` + ```ts + fetch(`/admin/gift-cards`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ gift_cards, limit, offset, count }) => { + console.log(gift_cards.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/gift-cards' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/gift-cards' \ + -H 'Authorization: Bearer ' + ``` - +
This request doesn't require any parameters. It accepts parameters related to pagination, which you can check out in the [API reference](https://docs.medusajs.com/api/admin#gift-cards_getgiftcards). @@ -582,76 +582,76 @@ Merchants can create custom gift cards to send a reward or gift to the customer. You can create a custom gift card by sending a request to the [Create a Gift Card API Route](https://docs.medusajs.com/api/admin#gift-cards_postgiftcards): - + -```ts -medusa.admin.giftCards.create({ - region_id, - value, -}) -.then(({ gift_card }) => { - console.log(gift_card.id) -}) -``` - - - - -```tsx -import { useAdminCreateGiftCard } from "medusa-react" - -const CreateCustomGiftCards = () => { - const createGiftCard = useAdminCreateGiftCard() - // ... - - const handleCreate = (regionId: string, value: number) => { - createGiftCard.mutate({ - region_id: regionId, + ```ts + medusa.admin.giftCards.create({ + region_id, value, }) - } + .then(({ gift_card }) => { + console.log(gift_card.id) + }) + ``` - // ... -} + + -export default CreateCustomGiftCards -``` + ```tsx + import { useAdminCreateGiftCard } from "medusa-react" - - + const CreateCustomGiftCards = () => { + const createGiftCard = useAdminCreateGiftCard() + // ... + + const handleCreate = (regionId: string, value: number) => { + createGiftCard.mutate({ + region_id: regionId, + value, + }) + } -```ts -fetch(`/admin/gift-cards`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - region_id, - value, - }), -}) -.then((response) => response.json()) -.then(({ gift_card }) => { - console.log(gift_card.id) -}) -``` + // ... + } - - + export default CreateCustomGiftCards + ``` -```bash -curl -L -X POST '/admin/gift-cards' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "region_id": "", - "value": 2000 -}' -``` + + - + ```ts + fetch(`/admin/gift-cards`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + region_id, + value, + }), + }) + .then((response) => response.json()) + .then(({ gift_card }) => { + console.log(gift_card.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/gift-cards' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "region_id": "", + "value": 2000 + }' + ``` + + This request requires the `region_id` body parameter. Its value should be the ID of the region that this gift card can be used in. @@ -667,74 +667,74 @@ Merchants can update any of the gift card’s properties, except for the value o You can update a gift card by sending a request to the [Update a Gift Card API Route](https://docs.medusajs.com/api/admin#gift-cards_postgiftcardsgiftcard): - + -```ts -medusa.admin.giftCards.update(giftCardId, { - balance, -}) -.then(({ gift_card }) => { - console.log(gift_card.id) -}) -``` - - - - -```tsx -import { useAdminUpdateGiftCard } from "medusa-react" - -const UpdateCustomGiftCards = () => { - const updateGiftCard = useAdminUpdateGiftCard( - customGiftCardId - ) - // ... - - const handleUpdate = (regionId: string) => { - updateGiftCard.mutate({ - region_id: regionId, + ```ts + medusa.admin.giftCards.update(giftCardId, { + balance, }) - } + .then(({ gift_card }) => { + console.log(gift_card.id) + }) + ``` - // ... -} + + -export default UpdateCustomGiftCards -``` + ```tsx + import { useAdminUpdateGiftCard } from "medusa-react" - - + const UpdateCustomGiftCards = () => { + const updateGiftCard = useAdminUpdateGiftCard( + customGiftCardId + ) + // ... + + const handleUpdate = (regionId: string) => { + updateGiftCard.mutate({ + region_id: regionId, + }) + } -```ts -fetch(`/admin/gift-cards/${giftCardId}`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - balance, - }), -}) -.then((response) => response.json()) -.then(({ gift_card }) => { - console.log(gift_card.id) -}) -``` + // ... + } - - + export default UpdateCustomGiftCards + ``` -```bash -curl -L -X POST '/admin/gift-cards/' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "balance": 2000 -}' -``` + + - + ```ts + fetch(`/admin/gift-cards/${giftCardId}`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + balance, + }), + }) + .then((response) => response.json()) + .then(({ gift_card }) => { + console.log(gift_card.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/gift-cards/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "balance": 2000 + }' + ``` + + This request requires the ID of the gift card as a path parameter. It accepts in its body parameters the gift card’s properties that you want to update. @@ -748,60 +748,60 @@ This request returns the updated gift card object in the response. You can delete a custom gift card by sending a request to the [Delete a Gift Card API Route](https://docs.medusajs.com/api/admin#gift-cards_deletegiftcardsgiftcard): - + -```ts -medusa.admin.giftCards.delete(giftCardId) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + medusa.admin.giftCards.delete(giftCardId) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```tsx -import { useAdminDeleteGiftCard } from "medusa-react" + ```tsx + import { useAdminDeleteGiftCard } from "medusa-react" -const CustomGiftCard = () => { - const deleteGiftCard = useAdminDeleteGiftCard( - customGiftCardId - ) - // ... - - const handleDelete = () => { - deleteGiftCard.mutate() - } + const CustomGiftCard = () => { + const deleteGiftCard = useAdminDeleteGiftCard( + customGiftCardId + ) + // ... + + const handleDelete = () => { + deleteGiftCard.mutate() + } - // ... -} + // ... + } -export default CustomGiftCard -``` + export default CustomGiftCard + ``` - - + + -```ts -fetch(`/admin/gift-cards/${giftCardId}`, { - method: "DELETE", - credentials: "include", -}) -.then((response) => response.json()) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + fetch(`/admin/gift-cards/${giftCardId}`, { + method: "DELETE", + credentials: "include", + }) + .then((response) => response.json()) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/gift-card/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/gift-card/' \ + -H 'Authorization: Bearer ' + ``` - + This request requires the ID of the gift card as a path parameter. diff --git a/www/apps/docs/content/modules/gift-cards/storefront/use-gift-cards.mdx b/www/apps/docs/content/modules/gift-cards/storefront/use-gift-cards.mdx index 6882845236..5021b9c411 100644 --- a/www/apps/docs/content/modules/gift-cards/storefront/use-gift-cards.mdx +++ b/www/apps/docs/content/modules/gift-cards/storefront/use-gift-cards.mdx @@ -61,72 +61,72 @@ Customers should be able to view gift cards before they make the purchase. Gift You can retrieve the gift card product using the [List Products API Route](https://docs.medusajs.com/api/store#products_getproducts), but passing it the `is_giftcard` query parameter: - + -```ts -medusa.products.list({ - is_giftcard: true, -}) -.then(({ products, limit, offset, count }) => { - if (products.length) { - // gift card products exist - - } else { - // no gift card products are created - } -}) -``` + ```ts + medusa.products.list({ + is_giftcard: true, + }) + .then(({ products, limit, offset, count }) => { + if (products.length) { + // gift card products exist + + } else { + // no gift card products are created + } + }) + ``` - - + + -```tsx -import { Product } from "@medusajs/medusa" -import { useProducts } from "medusa-react" + ```tsx + import { Product } from "@medusajs/medusa" + import { useProducts } from "medusa-react" -const GiftCards = () => { - const { products, isLoading } = useProducts({ - is_giftcard: true, - }) + const GiftCards = () => { + const { products, isLoading } = useProducts({ + is_giftcard: true, + }) - return ( -
- {isLoading && Loading...} - {products && products.length > 0 && ( -
    - {products.map((product: Product) => ( -
  • {product.title}
  • - ))} -
- )} - {products && !products.length && ( - No Gift Cards - )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {products && products.length > 0 && ( +
    + {products.map((product: Product) => ( +
  • {product.title}
  • + ))} +
+ )} + {products && !products.length && ( + No Gift Cards + )} +
+ ) + } -export default GiftCards -``` + export default GiftCards + ``` -
- + + -```ts -fetch(`/store/products?is_giftcard=true`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ products, limit, offset, count }) => { - if (products.length) { - // gift card products exist - } else { - // no gift card products are created - } -}) -``` + ```ts + fetch(`/store/products?is_giftcard=true`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ products, limit, offset, count }) => { + if (products.length) { + // gift card products exist + } else { + // no gift card products are created + } + }) + ``` - +
The request does not require any parameters. You can pass query parameters to filter the returned products. @@ -150,56 +150,56 @@ After the customer purchases the gift card, they’ll receive a code to redeem t You can retrieve the details of a gift card by sending a request to the [Get Gift Card by Code API Route](https://docs.medusajs.com/api/store#gift-cards_getgiftcardscode): - + -```ts -medusa.giftCards.retrieve(code) -.then(({ gift_card }) => { - console.log(gift_card.id) -}) -.catch((e) => { - // gift card doesn't exist or is disabled -}) -``` + ```ts + medusa.giftCards.retrieve(code) + .then(({ gift_card }) => { + console.log(gift_card.id) + }) + .catch((e) => { + // gift card doesn't exist or is disabled + }) + ``` - - + + -```tsx -import { useGiftCard } from "medusa-react" + ```tsx + import { useGiftCard } from "medusa-react" -const GiftCard = () => { - const { gift_card, isLoading, isError } = useGiftCard("code") + const GiftCard = () => { + const { gift_card, isLoading, isError } = useGiftCard("code") - return ( -
- {isLoading && Loading...} - {gift_card && {gift_card.value}} - {isError && Gift Card does not exist} -
- ) -} + return ( +
+ {isLoading && Loading...} + {gift_card && {gift_card.value}} + {isError && Gift Card does not exist} +
+ ) + } -export default GiftCard -``` + export default GiftCard + ``` -
- + + -```ts -fetch(`/store/gift-cards/${code}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ gift_card }) => { - console.log(gift_card.id) -}) -.catch((e) => { - // gift card doesn't exist or is disabled -}) -``` + ```ts + fetch(`/store/gift-cards/${code}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ gift_card }) => { + console.log(gift_card.id) + }) + .catch((e) => { + // gift card doesn't exist or is disabled + }) + ``` - +
This request requires the code of the gift card passed as a path parameter. @@ -225,79 +225,79 @@ A customer can redeem more than one gift card during checkout. The cart’s tota You can redeem a gift card during checkout by sending a request to the [Update Cart API Route](https://docs.medusajs.com/api/store#carts_postcartscart): - + -```ts -medusa.carts.update(cartId, { - gift_cards: [ - { - code, - }, - ], -}) -.then(({ cart }) => { - console.log(cart.gift_cards.length) -}) -.catch((e) => { - // gift card doesn't exist or is disabled -}) -``` - - - - -```tsx -import { useCart } from "medusa-react" - -const Cart = () => { - // ... - - const { updateCart } = useCart() - - const setGiftCard = (code: string) => { - updateCart.mutate({ + ```ts + medusa.carts.update(cartId, { gift_cards: [ { code, }, ], }) - } + .then(({ cart }) => { + console.log(cart.gift_cards.length) + }) + .catch((e) => { + // gift card doesn't exist or is disabled + }) + ``` - // ... -} + + -export default Cart -``` + ```tsx + import { useCart } from "medusa-react" - - + const Cart = () => { + // ... -```ts -fetch(`/store/cart/${cartId}`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - gift_cards: [ - { - code, + const { updateCart } = useCart() + + const setGiftCard = (code: string) => { + updateCart.mutate({ + gift_cards: [ + { + code, + }, + ], + }) + } + + // ... + } + + export default Cart + ``` + + + + + ```ts + fetch(`/store/cart/${cartId}`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", }, - ], - }), -}) -.then((response) => response.json()) -.then(({ cart }) => { - console.log(cart.gift_cards.length) -}) -.catch((e) => { - // gift card doesn't exist or is disabled -}) -``` + body: JSON.stringify({ + gift_cards: [ + { + code, + }, + ], + }), + }) + .then((response) => response.json()) + .then(({ cart }) => { + console.log(cart.gift_cards.length) + }) + .catch((e) => { + // gift card doesn't exist or is disabled + }) + ``` - + This request requires the ID of the cart as a path parameter. It allows passing any cart property you want to update in its body parameters. diff --git a/www/apps/docs/content/modules/multiwarehouse/admin/manage-inventory-items.mdx b/www/apps/docs/content/modules/multiwarehouse/admin/manage-inventory-items.mdx index ef2436417f..2e07035328 100644 --- a/www/apps/docs/content/modules/multiwarehouse/admin/manage-inventory-items.mdx +++ b/www/apps/docs/content/modules/multiwarehouse/admin/manage-inventory-items.mdx @@ -60,70 +60,70 @@ You can learn more about [authenticating as an admin user in the API reference]( You can list inventory items by sending a request to the [List Inventory Items API Route](https://docs.medusajs.com/api/admin#inventory-items_getinventoryitems): - + -```ts -medusa.admin.inventoryItems.list() -.then(({ inventory_items }) => { - console.log(inventory_items.length) -}) -``` + ```ts + medusa.admin.inventoryItems.list() + .then(({ inventory_items }) => { + console.log(inventory_items.length) + }) + ``` - - + + -```tsx -import { useAdminInventoryItems } from "medusa-react" + ```tsx + import { useAdminInventoryItems } from "medusa-react" -function InventoryItems() { - const { - inventory_items, - isLoading } = useAdminInventoryItems() + function InventoryItems() { + const { + inventory_items, + isLoading } = useAdminInventoryItems() - return ( -
- {isLoading && Loading...} - {inventory_items && !inventory_items.length && ( - No Items - )} - {inventory_items && inventory_items.length > 0 && ( -
    - {inventory_items.map( - (item) => ( -
  • {item.id}
  • - ) + return ( +
    + {isLoading && Loading...} + {inventory_items && !inventory_items.length && ( + No Items )} -
- )} -
- ) -} + {inventory_items && inventory_items.length > 0 && ( +
    + {inventory_items.map( + (item) => ( +
  • {item.id}
  • + ) + )} +
+ )} + + ) + } -export default InventoryItems -``` + export default InventoryItems + ``` -
- + + -```ts -fetch(`/admin/inventory-items`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ inventory_items }) => { - console.log(inventory_items.length) -}) -``` + ```ts + fetch(`/admin/inventory-items`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ inventory_items }) => { + console.log(inventory_items.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/inventory-items' \ - -H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/inventory-items' \ + -H 'Authorization: Bearer ' + ``` - +
This API Route doesn't require any path or query parameters. You can, however, pass path parameters to search or filter inventory items. For example, you can get inventory items in a specific location by passing the `location_id` query parameter. You can learn more about available query parameters in the [API reference](https://docs.medusajs.com/api/admin#inventory-items_getinventoryitems). @@ -143,72 +143,72 @@ Inventory items are automatically created when a variant is created with `manage You can create an inventory item by sending a request to the [Create Inventory Item API Route](https://docs.medusajs.com/api/admin#inventory-items_postinventoryitems): - + -```ts -medusa.admin.inventoryItems.create({ - variant_id, -}) -.then(({ inventory_item }) => { - console.log(inventory_item.id) -}) -``` - - - - -```tsx -import { useAdminCreateInventoryItem } from "medusa-react" - -const CreateInventoryItem = () => { - const createInventoryItem = useAdminCreateInventoryItem() - // ... - - const handleCreate = () => { - createInventoryItem.mutate({ + ```ts + medusa.admin.inventoryItems.create({ variant_id, }) - } + .then(({ inventory_item }) => { + console.log(inventory_item.id) + }) + ``` - // ... -} + + -export default CreateInventoryItem -``` + ```tsx + import { useAdminCreateInventoryItem } from "medusa-react" - - + const CreateInventoryItem = () => { + const createInventoryItem = useAdminCreateInventoryItem() + // ... -```ts -fetch(`/admin/inventory-items`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - variant_id, - }), -}) -.then((response) => response.json()) -.then(({ inventory_item }) => { - console.log(inventory_item.id) -}) -``` + const handleCreate = () => { + createInventoryItem.mutate({ + variant_id, + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/inventory-items' \ - -H 'Authorization: Bearer ' \ - -H 'Content-Type: application/json' \ - --data-raw '{ - "variant_id": "variant_123" - }' -``` + export default CreateInventoryItem + ``` - + + + + ```ts + fetch(`/admin/inventory-items`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + variant_id, + }), + }) + .then((response) => response.json()) + .then(({ inventory_item }) => { + console.log(inventory_item.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/inventory-items' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "variant_id": "variant_123" + }' + ``` + + This API Route requires in the body parameter the `variant_id` parameter, which is the ID of the variant to create this inventory item for. You can also pass other inventory-related parameters, such as `sku`. You can learn more about other available parameters in the [API reference](https://docs.medusajs.com/api/admin#inventory-items_postinventoryitems). @@ -222,63 +222,63 @@ This request returns the created inventory item as an object. You can retrieve an inventory item by sending a request to the [Get Inventory Item API Route](https://docs.medusajs.com/api/admin#inventory-items_getinventoryitemsinventoryitem): - + -```ts -medusa.admin.inventoryItems.retrieve(inventoryItemId) -.then(({ inventory_item }) => { - console.log(inventory_item.id) -}) -``` + ```ts + medusa.admin.inventoryItems.retrieve(inventoryItemId) + .then(({ inventory_item }) => { + console.log(inventory_item.id) + }) + ``` - - + + -```tsx -import { useAdminInventoryItem } from "medusa-react" + ```tsx + import { useAdminInventoryItem } from "medusa-react" -function InventoryItem() { - const { - inventory_item, - isLoading } = useAdminInventoryItem(inventoryItemId) + function InventoryItem() { + const { + inventory_item, + isLoading } = useAdminInventoryItem(inventoryItemId) - return ( -
- {isLoading && Loading...} - {inventory_item && ( - {inventory_item.sku} - )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {inventory_item && ( + {inventory_item.sku} + )} +
+ ) + } -export default InventoryItem -``` + export default InventoryItem + ``` -
- + + -```ts -fetch(`/admin/inventory-items/${inventoryItemId}`, - { - credentials: "include", - } -) -.then((response) => response.json()) -.then(({ inventory_item }) => { - console.log(inventory_item.id) -}) -``` + ```ts + fetch(`/admin/inventory-items/${inventoryItemId}`, + { + credentials: "include", + } + ) + .then((response) => response.json()) + .then(({ inventory_item }) => { + console.log(inventory_item.id) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/inventory-items/' \ - -H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/inventory-items/' \ + -H 'Authorization: Bearer ' + ``` - +
This API Route accepts the ID of the inventory item as a path parameter. You can also path query parameters such as [expand](https://docs.medusajs.com/api/admin#expanding-fields) and [fields](https://docs.medusajs.com/api/admin#selecting-fields). @@ -292,76 +292,76 @@ The request returns the inventory item as an object. You can update an inventory item by sending a request to the [Update Inventory Item API Route](https://docs.medusajs.com/api/admin#inventory-items_postinventoryitemsinventoryitem): - + -```ts -medusa.admin.inventoryItems.update(inventoryItemId, { - origin_country: "US", -}) -.then(({ inventory_item }) => { - console.log(inventory_item.id) -}) -``` - - - - -```tsx -import { useAdminUpdateInventoryItem } from "medusa-react" - -const UpdateInventoryItem = () => { - const updateInventoryItem = useAdminUpdateInventoryItem( - inventoryItemId - ) - // ... - - const handleUpdate = () => { - updateInventoryItem.mutate({ + ```ts + medusa.admin.inventoryItems.update(inventoryItemId, { origin_country: "US", }) - } + .then(({ inventory_item }) => { + console.log(inventory_item.id) + }) + ``` - // ... -} + + -export default UpdateInventoryItem -``` + ```tsx + import { useAdminUpdateInventoryItem } from "medusa-react" - - + const UpdateInventoryItem = () => { + const updateInventoryItem = useAdminUpdateInventoryItem( + inventoryItemId + ) + // ... -```ts -fetch(`/admin/inventory-items/${inventoryItemId}`, - { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - origin_country: "US", - }), - } -) -.then((response) => response.json()) -.then(({ inventory_item }) => { - console.log(inventory_item.id) -}) -``` + const handleUpdate = () => { + updateInventoryItem.mutate({ + origin_country: "US", + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/inventory-items/' \ - -H 'Authorization: Bearer ' \ - -H 'Content-Type: application/json' \ - --data-raw '{ - "origin_country": "US" - }' -``` + export default UpdateInventoryItem + ``` - + + + + ```ts + fetch(`/admin/inventory-items/${inventoryItemId}`, + { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + origin_country: "US", + }), + } + ) + .then((response) => response.json()) + .then(({ inventory_item }) => { + console.log(inventory_item.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/inventory-items/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "origin_country": "US" + }' + ``` + + This API Route requires the inventory item’s ID as a path parameter. You can pass any of the inventory item’s attributes that you want to update in its body parameter. The example above updates the value of the `origin_country` attribute. You can learn more about available body parameters in the [API reference](https://docs.medusajs.com/api/admin#inventory-items_postinventoryitemsinventoryitem). @@ -379,70 +379,70 @@ This section shows you the different ways you can manage inventory levels. Each You can list inventory levels of an inventory item by sending a request to the [List inventory levels API Route](https://docs.medusajs.com/api/admin#inventory-items_getinventoryitemsinventoryitemlocationlevels): - + -```ts -medusa.admin.inventoryItems.listLocationLevels(inventoryItemId) -.then(({ inventory_item }) => { - console.log(inventory_item.location_levels) -}) -``` + ```ts + medusa.admin.inventoryItems.listLocationLevels(inventoryItemId) + .then(({ inventory_item }) => { + console.log(inventory_item.location_levels) + }) + ``` - - + + -```tsx -import { - useAdminInventoryItemLocationLevels, -} from "medusa-react" + ```tsx + import { + useAdminInventoryItemLocationLevels, + } from "medusa-react" -function InventoryItem() { - const { - inventory_item, - isLoading, - } = useAdminInventoryItemLocationLevels(inventoryItemId) + function InventoryItem() { + const { + inventory_item, + isLoading, + } = useAdminInventoryItemLocationLevels(inventoryItemId) - return ( -
- {isLoading && Loading...} - {inventory_item && ( -
    - {inventory_item.location_levels.map((level) => ( - {level.stocked_quantity} - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {inventory_item && ( +
    + {inventory_item.location_levels.map((level) => ( + {level.stocked_quantity} + ))} +
+ )} +
+ ) + } -export default InventoryItem -``` + export default InventoryItem + ``` -
- + + -```ts -fetch(`/admin/inventory-items/${inventoryItemId}/location-levels`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ inventory_item }) => { - console.log(inventory_item.location_levels) -}) -``` + ```ts + fetch(`/admin/inventory-items/${inventoryItemId}/location-levels`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ inventory_item }) => { + console.log(inventory_item.location_levels) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/inventory-items//location-levels' \ - -H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/inventory-items//location-levels' \ + -H 'Authorization: Bearer ' + ``` - +
This API Route requires the ID of the inventory item as a path parameter. You can also pass [expand](https://docs.medusajs.com/api/admin#expanding-fields) and [fields](https://docs.medusajs.com/api/admin#selecting-fields) query parameters. @@ -454,83 +454,83 @@ The request returns the inventory item as an object. In that object, the list of You can create a location level by sending a request to the [Create Inventory Level API Route](https://docs.medusajs.com/api/admin#inventory-items_postinventoryitemsinventoryitemlocationlevels): - + -```ts -medusa.admin.inventoryItems.createLocationLevel( - inventoryItemId, - { - location_id, - stocked_quantity: 10, - } -) -.then(({ inventory_item }) => { - console.log(inventory_item.id) -}) -``` - - - - -```tsx -import { useAdminCreateLocationLevel } from "medusa-react" - -const CreateLocationLevel = () => { - const createLocationLevel = useAdminCreateLocationLevel( - inventoryItemId - ) - // ... - - const handleCreate = () => { - createLocationLevel.mutate({ - location_id, - stocked_quantity: 10, + ```ts + medusa.admin.inventoryItems.createLocationLevel( + inventoryItemId, + { + location_id, + stocked_quantity: 10, + } + ) + .then(({ inventory_item }) => { + console.log(inventory_item.id) }) - } + ``` - // ... -} + + -export default CreateLocationLevel -``` + ```tsx + import { useAdminCreateLocationLevel } from "medusa-react" - - + const CreateLocationLevel = () => { + const createLocationLevel = useAdminCreateLocationLevel( + inventoryItemId + ) + // ... + + const handleCreate = () => { + createLocationLevel.mutate({ + location_id, + stocked_quantity: 10, + }) + } + + // ... + } + + export default CreateLocationLevel + ``` + + + -```ts -fetch(`/admin/inventory-items/${inventoryItemId}/location-levels`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - location_id, - stocked_quantity: 10, - }), -}) -.then((response) => response.json()) -.then(({ inventory_item }) => { - console.log(inventory_item.id) -}) -``` + ```ts + fetch(`/admin/inventory-items/${inventoryItemId}/location-levels`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + location_id, + stocked_quantity: 10, + }), + }) + .then((response) => response.json()) + .then(({ inventory_item }) => { + console.log(inventory_item.id) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/inventory-items//location-levels' \ - -H 'Authorization: Bearer ' \ - -H 'Content-Type: application/json' \ - --data-raw '{ - "location_id": "", - "stocked_quantity": 10 - }' -``` + ```bash + curl -L -X POST '/admin/inventory-items//location-levels' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "location_id": "", + "stocked_quantity": 10 + }' + ``` - + This API Route requires the inventory item ID as a path parameter. In the request body, it requires the following parameters: @@ -547,81 +547,81 @@ This request returns the inventory item associated with the created location lev You can update a location level by sending a request to the [Update Location Level API Route](https://docs.medusajs.com/api/admin#inventory-items_postinventoryitemsinventoryitemlocationlevelslocationlevel): - + -```ts -medusa.admin.inventoryItems.updateLocationLevel( - inventoryItemId, - locationId, - { - stocked_quantity: 15, - } -) -.then(({ inventory_item }) => { - console.log(inventory_item.id) -}) -``` - - - - -```tsx -import { useAdminUpdateLocationLevel } from "medusa-react" - -const UpdateLocationLevel = () => { - const updateLocationLevel = useAdminUpdateLocationLevel( - inventoryItemId - ) - // ... - - const handleUpdate = () => { - updateLocationLevel.mutate({ - stockLocationId, - stocked_quantity: 10, + ```ts + medusa.admin.inventoryItems.updateLocationLevel( + inventoryItemId, + locationId, + { + stocked_quantity: 15, + } + ) + .then(({ inventory_item }) => { + console.log(inventory_item.id) }) - } + ``` - // ... -} + + -export default UpdateLocationLevel -``` + ```tsx + import { useAdminUpdateLocationLevel } from "medusa-react" - - + const UpdateLocationLevel = () => { + const updateLocationLevel = useAdminUpdateLocationLevel( + inventoryItemId + ) + // ... + + const handleUpdate = () => { + updateLocationLevel.mutate({ + stockLocationId, + stocked_quantity: 10, + }) + } + + // ... + } + + export default UpdateLocationLevel + ``` + + + -```ts -fetch(`/admin/inventory-items/${inventoryItemId}/location-levels/${locationId}`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - stocked_quantity: 10, - }), -}) -.then((response) => response.json()) -.then(({ inventory_item }) => { - console.log(inventory_item.id) -}) -``` + ```ts + fetch(`/admin/inventory-items/${inventoryItemId}/location-levels/${locationId}`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + stocked_quantity: 10, + }), + }) + .then((response) => response.json()) + .then(({ inventory_item }) => { + console.log(inventory_item.id) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/inventory-items//location-levels/' \ - -H 'Authorization: Bearer ' \ - -H 'Content-Type: application/json' \ - --data-raw '{ - "stocked_quantity": 10 - }' -``` + ```bash + curl -L -X POST '/admin/inventory-items//location-levels/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "stocked_quantity": 10 + }' + ``` - + This API Route requires two path parameters: the first one being the ID of the inventory item, and the second one being the ID of the location. @@ -635,65 +635,65 @@ The request returns the inventory item associated with the location level as an You can delete a location level of an inventory item by sending a request to the [Delete Location Level API Route](https://docs.medusajs.com/api/admin#inventory-items_deleteinventoryitemsinventoryitelocationlevelslocation): - + -```ts -medusa.admin.inventoryItems.deleteLocationLevel( - inventoryItemId, - locationId -) -.then(({ inventory_item }) => { - console.log(inventory_item.id) -}) -``` + ```ts + medusa.admin.inventoryItems.deleteLocationLevel( + inventoryItemId, + locationId + ) + .then(({ inventory_item }) => { + console.log(inventory_item.id) + }) + ``` - - + + -```tsx -import { useAdminDeleteLocationLevel } from "medusa-react" + ```tsx + import { useAdminDeleteLocationLevel } from "medusa-react" -const DeleteLocationLevel = () => { - const deleteLocationLevel = useAdminDeleteLocationLevel( - inventoryItemId - ) - // ... + const DeleteLocationLevel = () => { + const deleteLocationLevel = useAdminDeleteLocationLevel( + inventoryItemId + ) + // ... - const handleDelete = () => { - deleteLocationLevel.mutate(locationId) - } + const handleDelete = () => { + deleteLocationLevel.mutate(locationId) + } - // ... -} + // ... + } -export default DeleteLocationLevel -``` + export default DeleteLocationLevel + ``` - - + + -```ts -fetch(`/admin/inventory-items/${inventoryItemId}/location-levels/${locationId}`, { - credentials: "include", - method: "DELETE", -}) -.then((response) => response.json()) -.then(({ inventory_item }) => { - console.log(inventory_item.id) -}) -``` + ```ts + fetch(`/admin/inventory-items/${inventoryItemId}/location-levels/${locationId}`, { + credentials: "include", + method: "DELETE", + }) + .then((response) => response.json()) + .then(({ inventory_item }) => { + console.log(inventory_item.id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/inventory-items//location-levels/' \ - -H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/inventory-items//location-levels/' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires two path parameters: the first one being the inventory item’s ID and the second one being the location level’s ID. @@ -707,62 +707,62 @@ The request returns the inventory item as an object. You can delete an inventory item by sending a request to the [Delete Inventory Item API Route](https://docs.medusajs.com/api/admin#inventory-items_deleteinventoryitemsinventoryitem): - + -```ts -medusa.admin.inventoryItems.delete(inventoryItemId) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + medusa.admin.inventoryItems.delete(inventoryItemId) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```tsx -import { useAdminDeleteInventoryItem } from "medusa-react" + ```tsx + import { useAdminDeleteInventoryItem } from "medusa-react" -const DeleteInventoryItem = () => { - const deleteInventoryItem = useAdminDeleteInventoryItem( - inventoryItemId - ) - // ... + const DeleteInventoryItem = () => { + const deleteInventoryItem = useAdminDeleteInventoryItem( + inventoryItemId + ) + // ... - const handleDelete = () => { - deleteInventoryItem.mutate() - } + const handleDelete = () => { + deleteInventoryItem.mutate() + } - // ... -} + // ... + } -export default DeleteInventoryItem -``` + export default DeleteInventoryItem + ``` - - + + -```ts -fetch(`/admin/inventory-items/${inventoryItemId}`, - { - credentials: "include", - method: "DELETE", - } -) -.then((response) => response.json()) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + fetch(`/admin/inventory-items/${inventoryItemId}`, + { + credentials: "include", + method: "DELETE", + } + ) + .then((response) => response.json()) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/inventory-items/' \ - -H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/inventory-items/' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the inventory item’s ID be passed as a path parameter. diff --git a/www/apps/docs/content/modules/multiwarehouse/admin/manage-item-allocations-in-orders.mdx b/www/apps/docs/content/modules/multiwarehouse/admin/manage-item-allocations-in-orders.mdx index 320f7f241e..1905c9c0b8 100644 --- a/www/apps/docs/content/modules/multiwarehouse/admin/manage-item-allocations-in-orders.mdx +++ b/www/apps/docs/content/modules/multiwarehouse/admin/manage-item-allocations-in-orders.mdx @@ -79,84 +79,84 @@ Item allocations are created automatically for items that are associated with pr You can create an item allocation by sending a request to the [Create a Reservation API Route](https://docs.medusajs.com/api/admin#reservations_postreservations): - + -```ts -medusa.admin.reservations.create({ - line_item_id, - location_id, - inventory_item_id, - quantity, -}) -.then(({ reservation }) => { - console.log(reservation.id) -}) -``` - - - - -```tsx -import { useAdminCreateReservation } from "medusa-react" - -const CreateReservation = () => { - const createReservation = useAdminCreateReservation() - // ... - - const handleCreate = () => { - createReservation.mutate({ + ```ts + medusa.admin.reservations.create({ line_item_id, location_id, inventory_item_id, quantity, }) - } + .then(({ reservation }) => { + console.log(reservation.id) + }) + ``` - // ... -} + + -export default CreateReservation -``` + ```tsx + import { useAdminCreateReservation } from "medusa-react" - - + const CreateReservation = () => { + const createReservation = useAdminCreateReservation() + // ... -```ts -fetch(`/admin/reservations`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - line_item_id, - location_id, - inventory_item_id, - quantity, - }), -}) -.then((response) => response.json()) -.then(({ reservation }) => { - console.log(reservation.id) -}) -``` + const handleCreate = () => { + createReservation.mutate({ + line_item_id, + location_id, + inventory_item_id, + quantity, + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/reservations' \ - -H 'Authorization: Bearer ' \ - -H 'Content-Type: application/json' \ - --data-raw '{ - "line_item_id": "", - "location_id": "", - "inventory_item_id": "", - "quantity": 1 - }' -``` + export default CreateReservation + ``` - + + + + ```ts + fetch(`/admin/reservations`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + line_item_id, + location_id, + inventory_item_id, + quantity, + }), + }) + .then((response) => response.json()) + .then(({ reservation }) => { + console.log(reservation.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/reservations' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "line_item_id": "", + "location_id": "", + "inventory_item_id": "", + "quantity": 1 + }' + ``` + + This API Route requires the following body parameters: @@ -175,72 +175,72 @@ When listing item allocations, by default, you’ll be retrieving all item alloc You can retrieve the item allocations of a line item in an order using the [List Reservations API Route](https://docs.medusajs.com/api/admin#reservations_getreservations): - + -```ts -medusa.admin.reservations.list({ - line_item_id, -}) -.then(({ reservations, count, limit, offset }) => { - console.log(reservations.length) -}) -``` + ```ts + medusa.admin.reservations.list({ + line_item_id, + }) + .then(({ reservations, count, limit, offset }) => { + console.log(reservations.length) + }) + ``` - - + + -```tsx -import { useAdminReservations } from "medusa-react" + ```tsx + import { useAdminReservations } from "medusa-react" -function Reservations() { - const { reservations, isLoading } = useAdminReservations({ - line_item_id, - }) + function Reservations() { + const { reservations, isLoading } = useAdminReservations({ + line_item_id, + }) - return ( -
- {isLoading && Loading...} - {reservations && !reservations.length && ( - No Reservations - )} - {reservations && reservations.length > 0 && ( -
    - {reservations.map((reservation) => ( -
  • {reservation.quantity}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {reservations && !reservations.length && ( + No Reservations + )} + {reservations && reservations.length > 0 && ( +
    + {reservations.map((reservation) => ( +
  • {reservation.quantity}
  • + ))} +
+ )} +
+ ) + } -export default Reservations -``` + export default Reservations + ``` -
- + + -```ts -fetch(`/admin/reservations?line_item_id=${lineItemId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ reservations, count, limit, offset }) => { - console.log(reservations.length) -}) -``` + ```ts + fetch(`/admin/reservations?line_item_id=${lineItemId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ reservations, count, limit, offset }) => { + console.log(reservations.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/reservations?line_item_id=' \ - -H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/reservations?line_item_id=' \ + -H 'Authorization: Bearer ' + ``` - +
This API Route doesn't require any path or query parameters. As mentioned earlier, you can pass query parameters to filter the reservations. In the code snippets above, you filter the reservations by a line item ID. You can, however, filter by other attributes, such as the ID of the location. You can refer to the [API reference](https://docs.medusajs.com/api/admin#reservations_getreservations) for a full list of query parameters. @@ -252,61 +252,61 @@ The request returns the reservations along with [pagination fields](https://docs You can retrieve a single item allocation by its ID using the [Get a Reservation API Route](https://docs.medusajs.com/api/admin#reservations_getreservationsreservation): - + -```ts -medusa.admin.reservations.retrieve(reservationId) -.then(({ reservation }) => { - console.log(reservation.id) -}) -``` + ```ts + medusa.admin.reservations.retrieve(reservationId) + .then(({ reservation }) => { + console.log(reservation.id) + }) + ``` - - + + -```tsx -import { useAdminReservation } from "medusa-react" + ```tsx + import { useAdminReservation } from "medusa-react" -function Reservation() { - const { - reservation, - isLoading } = useAdminReservation(reservationId) + function Reservation() { + const { + reservation, + isLoading } = useAdminReservation(reservationId) - return ( -
- {isLoading && Loading...} - {reservation && ( - {reservation.quantity} - )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {reservation && ( + {reservation.quantity} + )} +
+ ) + } -export default Reservation -``` + export default Reservation + ``` -
- + + -```ts -fetch(`/admin/reservations/${reservationId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ reservation }) => { - console.log(reservation.id) -}) -``` + ```ts + fetch(`/admin/reservations/${reservationId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ reservation }) => { + console.log(reservation.id) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/reservations/' \ - -H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/reservations/' \ + -H 'Authorization: Bearer ' + ``` - +
This API Route requires the reservation’s ID as a path parameter. @@ -318,74 +318,74 @@ The request returns the reservation as an object. You can update an item allocation to change the location to allocate from or the quantity to allocate by sending a request to the [Update Reservation API Route](https://docs.medusajs.com/api/admin#reservations_postreservationsreservation): - + -```ts -medusa.admin.reservations.update(reservationId, { - quantity, -}) -.then(({ reservation }) => { - console.log(reservation.id) -}) -``` - - - - -```tsx -import { useAdminUpdateReservation } from "medusa-react" - -const UpdateReservation = () => { - const updateReservation = useAdminUpdateReservation( - reservationId - ) - // ... - - const handleCreate = () => { - updateReservation.mutate({ + ```ts + medusa.admin.reservations.update(reservationId, { quantity, }) - } + .then(({ reservation }) => { + console.log(reservation.id) + }) + ``` - // ... -} + + -export default UpdateReservation -``` + ```tsx + import { useAdminUpdateReservation } from "medusa-react" - - + const UpdateReservation = () => { + const updateReservation = useAdminUpdateReservation( + reservationId + ) + // ... -```ts -fetch(`/admin/reservations/${reservationId}`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - quantity, - }), -}) -.then((response) => response.json()) -.then(({ reservation }) => { - console.log(reservation.id) -}) -``` + const handleCreate = () => { + updateReservation.mutate({ + quantity, + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/reservations/' \ - -H 'Authorization: Bearer ' \ - -H 'Content-Type: application/json' \ - --data-raw '{ - "quantity": 3 - }' -``` + export default UpdateReservation + ``` - + + + + ```ts + fetch(`/admin/reservations/${reservationId}`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + quantity, + }), + }) + .then((response) => response.json()) + .then(({ reservation }) => { + console.log(reservation.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/reservations/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "quantity": 3 + }' + ``` + + This API Route requires the ID of the reservation as a path parameter. @@ -405,60 +405,60 @@ Deleting an item allocation means that the quantity that was previously reserved You can delete an item allocation by sending a request to the [Delete Reservation API Route](https://docs.medusajs.com/api/admin#reservations_deletereservationsreservation): - + -```ts -medusa.admin.reservations.delete(reservationId) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + medusa.admin.reservations.delete(reservationId) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```tsx -import { useAdminDeleteReservation } from "medusa-react" + ```tsx + import { useAdminDeleteReservation } from "medusa-react" -const DeleteReservation = () => { - const deleteReservation = useAdminDeleteReservation( - reservationId - ) - // ... + const DeleteReservation = () => { + const deleteReservation = useAdminDeleteReservation( + reservationId + ) + // ... - const handleDelete = () => { - deleteReservation.mutate() - } + const handleDelete = () => { + deleteReservation.mutate() + } - // ... -} + // ... + } -export default DeleteReservation -``` + export default DeleteReservation + ``` - - + + -```ts -fetch(`/admin/reservations/${reservationId}`, { - credentials: "include", - method: "DELETE", -}) -.then((response) => response.json()) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + fetch(`/admin/reservations/${reservationId}`, { + credentials: "include", + method: "DELETE", + }) + .then((response) => response.json()) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/reservations/' \ - -H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/reservations/' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the reservation ID to be passed as a path parameter. @@ -476,36 +476,10 @@ The request returns the following fields: When you create a fulfillment of an order, you can specify the location to fulfill the item from by passing the `location_id` parameter: - + -```ts -medusa.admin.orders.createFulfillment(orderId, { - items: [ - { - item_id, - quantity, - }, - ], - // ...other parameters - location_id, -}) -.then(({ order }) => { - console.log(order.id) -}) -``` - - - - -```tsx -import { useAdminCreateFulfillment } from "medusa-react" - -const CreateFulfillment = () => { - const createFulfillment = useAdminCreateFulfillment(orderId) - // ... - - const handleCreate = () => { - createFulfillment.mutate({ + ```ts + medusa.admin.orders.createFulfillment(orderId, { items: [ { item_id, @@ -515,60 +489,86 @@ const CreateFulfillment = () => { // ...other parameters location_id, }) - } + .then(({ order }) => { + console.log(order.id) + }) + ``` - // ... -} + + -export default CreateFulfillment -``` + ```tsx + import { useAdminCreateFulfillment } from "medusa-react" - - + const CreateFulfillment = () => { + const createFulfillment = useAdminCreateFulfillment(orderId) + // ... -```ts -fetch(`/admin/orders/${orderId}/fulfillment`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - items: [ - { - item_id, - quantity, + const handleCreate = () => { + createFulfillment.mutate({ + items: [ + { + item_id, + quantity, + }, + ], + // ...other parameters + location_id, + }) + } + + // ... + } + + export default CreateFulfillment + ``` + + + + + ```ts + fetch(`/admin/orders/${orderId}/fulfillment`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", }, - ], - // ...other parameters - location_id, - }), -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.id) -}) -``` - - - - -```bash -curl -L -X POST '/admin/orders//fulfillment' \ - -H 'Authorization: Bearer ' \ - -H 'Content-Type: application/json' \ - --data-raw '{ - "items": [ + body: JSON.stringify({ + items: [ { - "item_id": "", - "quantity": 1 - } + item_id, + quantity, + }, ], - "location_id": "" - }' -``` + // ...other parameters + location_id, + }), + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.id) + }) + ``` - + + + + ```bash + curl -L -X POST '/admin/orders//fulfillment' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "items": [ + { + "item_id": "", + "quantity": 1 + } + ], + "location_id": "" + }' + ``` + + The `location_id` is an optional parameter that allows you to specify where to fulfill the item from. This subsequently decrements the stock quantity of the product variant in that location. @@ -582,99 +582,99 @@ You can learn more about this API Route's parameters and response in the [API re When requesting a return, you can specify the location to return the item to by passing the `location_id` parameter: - + -```ts -medusa.admin.orders.requestReturn(orderId, { - items: [ - { - item_id, - quantity: 1, - }, - ], - // other parameters... - location_id, -}) -.then(({ order }) => { - console.log(order.id) -}) -``` - - - - -```tsx -import { useAdminRequestReturn } from "medusa-react" - -const RequestReturn = () => { - const requestReturn = useAdminRequestReturn(orderId) - // ... - - const handleRequest = () => { - requestReturn.mutate({ + ```ts + medusa.admin.orders.requestReturn(orderId, { items: [ { item_id, - quantity, + quantity: 1, }, ], - // ...other parameters + // other parameters... location_id, }) - } + .then(({ order }) => { + console.log(order.id) + }) + ``` - // ... -} + + -export default RequestReturn -``` + ```tsx + import { useAdminRequestReturn } from "medusa-react" - - + const RequestReturn = () => { + const requestReturn = useAdminRequestReturn(orderId) + // ... -```ts -fetch(`/admin/orders/${orderId}/return`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - items: [ - { - item_id, - quantity, + const handleRequest = () => { + requestReturn.mutate({ + items: [ + { + item_id, + quantity, + }, + ], + // ...other parameters + location_id, + }) + } + + // ... + } + + export default RequestReturn + ``` + + + + + ```ts + fetch(`/admin/orders/${orderId}/return`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", }, - ], - // ...other parameters - location_id, - }), -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.id) -}) -``` - - - - -```bash -curl -L -X POST '/admin/orders//return' \ - -H 'Authorization: Bearer ' \ - -H 'Content-Type: application/json' \ - --data-raw '{ - "items": [ + body: JSON.stringify({ + items: [ { - "item_id": "", - "quantity": 1 - } + item_id, + quantity, + }, ], - "location_id": "" - }' -``` + // ...other parameters + location_id, + }), + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.id) + }) + ``` - + + + + ```bash + curl -L -X POST '/admin/orders//return' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "items": [ + { + "item_id": "", + "quantity": 1 + } + ], + "location_id": "" + }' + ``` + + The `location_id` is an optional parameter that allows you to specify where to return the item to. This subsequently increments the stock quantity of the product variant in that location. diff --git a/www/apps/docs/content/modules/multiwarehouse/admin/manage-reservations.mdx b/www/apps/docs/content/modules/multiwarehouse/admin/manage-reservations.mdx index 4345576f13..7a90eebe47 100644 --- a/www/apps/docs/content/modules/multiwarehouse/admin/manage-reservations.mdx +++ b/www/apps/docs/content/modules/multiwarehouse/admin/manage-reservations.mdx @@ -72,66 +72,66 @@ You can learn more about [authenticating as an admin user in the API reference]( You can list all reservations in your store by sending a request to the [List Reservations API Route](https://docs.medusajs.com/api/admin#reservations_getreservations): - + -```ts -medusa.admin.reservations.list() -.then(({ reservations, limit, count, offset }) => { - console.log(reservations.length) -}) -``` + ```ts + medusa.admin.reservations.list() + .then(({ reservations, limit, count, offset }) => { + console.log(reservations.length) + }) + ``` - - + + -```tsx -import { useAdminReservations } from "medusa-react" + ```tsx + import { useAdminReservations } from "medusa-react" -const Reservations = () => { - const { reservations, isLoading } = useAdminReservations() + const Reservations = () => { + const { reservations, isLoading } = useAdminReservations() - return ( -
- {isLoading && Loading...} - {reservations && !reservations.length && ( - No Reservations - )} - {reservations && reservations.length > 0 && ( -
    - {reservations.map((reservation) => ( -
  • {reservation.quantity}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {reservations && !reservations.length && ( + No Reservations + )} + {reservations && reservations.length > 0 && ( +
    + {reservations.map((reservation) => ( +
  • {reservation.quantity}
  • + ))} +
+ )} +
+ ) + } -export default Reservations -``` + export default Reservations + ``` -
- + + -```ts -fetch(`/admin/reservations`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ reservations, limit, count, offset }) => { - console.log(reservations.length) -}) -``` + ```ts + fetch(`/admin/reservations`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ reservations, limit, count, offset }) => { + console.log(reservations.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/reservations' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/reservations' \ + -H 'Authorization: Bearer ' + ``` - +
This API Route doesn't require any query or path parameters. You can pass it query parameters for filtering or pagination purposes. Check out the [API reference](https://docs.medusajs.com/api/admin#reservations_getreservations) for a list of accepted query parameters. @@ -151,80 +151,80 @@ Before you create a reservation for a product variant, make sure you’ve create You can create a reservation by sending a request to the [Create Reservation API Route](https://docs.medusajs.com/api/admin#reservations_postreservations): - + -```ts -medusa.admin.reservations.create({ - location_id, - inventory_item_id, - quantity, -}) -.then(({ reservation }) => { - console.log(reservation.id) -}) -``` - - - - -```tsx -import { useAdminCreateReservation } from "medusa-react" - -const CreateReservation = () => { - const createReservation = useAdminCreateReservation() - // ... - - const handleCreate = () => { - createReservation.mutate({ + ```ts + medusa.admin.reservations.create({ location_id, inventory_item_id, quantity, }) - } + .then(({ reservation }) => { + console.log(reservation.id) + }) + ``` - // ... -} + + -export default CreateReservation -``` + ```tsx + import { useAdminCreateReservation } from "medusa-react" - - + const CreateReservation = () => { + const createReservation = useAdminCreateReservation() + // ... -```ts -fetch(`/admin/reservations`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - location_id, - inventory_item_id, - quantity, - }), -}) -.then((response) => response.json()) -.then(({ reservation }) => { - console.log(reservation.id) -}) -``` + const handleCreate = () => { + createReservation.mutate({ + location_id, + inventory_item_id, + quantity, + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/reservations' \ - -H 'Authorization: Bearer ' \ - -H 'Content-Type: application/json' \ - --data-raw '{ - "location_id": "", - "inventory_item_id": "", - "quantity": 1 - }' -``` + export default CreateReservation + ``` - + + + + ```ts + fetch(`/admin/reservations`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + location_id, + inventory_item_id, + quantity, + }), + }) + .then((response) => response.json()) + .then(({ reservation }) => { + console.log(reservation.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/reservations' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "location_id": "", + "inventory_item_id": "", + "quantity": 1 + }' + ``` + + This API Route requires the following body parameters: @@ -242,74 +242,74 @@ The request returns the created reservation as an object. You can update a reservation by sending a request to the [Update Reservation API Route](https://docs.medusajs.com/api/admin#reservations_postreservationsreservation): - + -```ts -medusa.admin.reservations.update(reservationId, { - quantity, -}) -.then(({ reservation }) => { - console.log(reservation.id) -}) -``` - - - - -```tsx -import { useAdminUpdateReservation } from "medusa-react" - -const UpdateReservation = () => { - const updateReservation = useAdminUpdateReservation( - reservationId - ) - // ... - - const handleCreate = () => { - updateReservation.mutate({ + ```ts + medusa.admin.reservations.update(reservationId, { quantity, }) - } + .then(({ reservation }) => { + console.log(reservation.id) + }) + ``` - // ... -} + + -export default UpdateReservation -``` + ```tsx + import { useAdminUpdateReservation } from "medusa-react" - - + const UpdateReservation = () => { + const updateReservation = useAdminUpdateReservation( + reservationId + ) + // ... -```ts -fetch(`/admin/reservations/${reservationId}`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - quantity, - }), -}) -.then((response) => response.json()) -.then(({ reservation }) => { - console.log(reservation.id) -}) -``` + const handleCreate = () => { + updateReservation.mutate({ + quantity, + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/reservations/' \ - -H 'Authorization: Bearer ' \ - -H 'Content-Type: application/json' \ - --data-raw '{ - "quantity": 3 - }' -``` + export default UpdateReservation + ``` - + + + + ```ts + fetch(`/admin/reservations/${reservationId}`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + quantity, + }), + }) + .then((response) => response.json()) + .then(({ reservation }) => { + console.log(reservation.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/reservations/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "quantity": 3 + }' + ``` + + This API Route requires the ID of the reservation as a path parameter. @@ -329,60 +329,60 @@ The request returns the updated reservation as an object. You can delete a reservation by sending a request to the [Delete Reservation API Route](https://docs.medusajs.com/api/admin#reservations_deletereservationsreservation): - + -```ts -medusa.admin.reservations.delete(reservationId) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + medusa.admin.reservations.delete(reservationId) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```tsx -import { useAdminDeleteReservation } from "medusa-react" + ```tsx + import { useAdminDeleteReservation } from "medusa-react" -const DeleteReservation = () => { - const deleteReservation = useAdminDeleteReservation( - reservationId - ) - // ... + const DeleteReservation = () => { + const deleteReservation = useAdminDeleteReservation( + reservationId + ) + // ... - const handleDelete = () => { - deleteReservation.mutate() - } + const handleDelete = () => { + deleteReservation.mutate() + } - // ... -} + // ... + } -export default DeleteReservation -``` + export default DeleteReservation + ``` - - + + -```ts -fetch(`/admin/reservations/${reservationId}`, { - credentials: "include", - method: "DELETE", -}) -.then((response) => response.json()) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + fetch(`/admin/reservations/${reservationId}`, { + credentials: "include", + method: "DELETE", + }) + .then((response) => response.json()) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/reservations/' \ - -H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/reservations/' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the reservation ID to be passed as a path parameter. diff --git a/www/apps/docs/content/modules/multiwarehouse/admin/manage-stock-locations.mdx b/www/apps/docs/content/modules/multiwarehouse/admin/manage-stock-locations.mdx index 0d769691fa..1ceca79d1b 100644 --- a/www/apps/docs/content/modules/multiwarehouse/admin/manage-stock-locations.mdx +++ b/www/apps/docs/content/modules/multiwarehouse/admin/manage-stock-locations.mdx @@ -62,70 +62,70 @@ You can learn more about [authenticating as an admin user in the API reference]( You can list stock locations by using the [List Stock Locations API Route](https://docs.medusajs.com/api/admin#stock-locations_getstocklocations): - + -```ts -medusa.admin.stockLocations.list() -.then(({ stock_locations, limit, offset, count }) => { - console.log(stock_locations.length) -}) -``` + ```ts + medusa.admin.stockLocations.list() + .then(({ stock_locations, limit, offset, count }) => { + console.log(stock_locations.length) + }) + ``` - - + + -```tsx -import { useAdminStockLocations } from "medusa-react" + ```tsx + import { useAdminStockLocations } from "medusa-react" -function StockLocations() { - const { - stock_locations, - isLoading } = useAdminStockLocations() + function StockLocations() { + const { + stock_locations, + isLoading } = useAdminStockLocations() - return ( -
- {isLoading && Loading...} - {stock_locations && !stock_locations.length && ( - No Locations - )} - {stock_locations && stock_locations.length > 0 && ( -
    - {stock_locations.map( - (location) => ( -
  • {location.name}
  • - ) + return ( +
    + {isLoading && Loading...} + {stock_locations && !stock_locations.length && ( + No Locations )} -
- )} -
- ) -} + {stock_locations && stock_locations.length > 0 && ( +
    + {stock_locations.map( + (location) => ( +
  • {location.name}
  • + ) + )} +
+ )} + + ) + } -export default StockLocations -``` + export default StockLocations + ``` -
- + + -```ts -fetch(`/admin/stock-locations`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ stock_locations, limit, offset, count }) => { - console.log(stock_locations.length) -}) -``` + ```ts + fetch(`/admin/stock-locations`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ stock_locations, limit, offset, count }) => { + console.log(stock_locations.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/stock-locations' \ - -H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/stock-locations' \ + -H 'Authorization: Bearer ' + ``` - +
This API Route doesn't require any path or query parameters. You can, however, pass it query parameters to search or filter the list of stock locations. For example, you can pass the `q` query parameter to search through the locations by name. You can learn about available query parameters in the [API reference](https://docs.medusajs.com/api/admin#stock-locations_getstocklocations). @@ -139,72 +139,72 @@ The request returns an array of stock location objects along with [pagination pa You can create a stock location using the [Create a Stock Location API Route](https://docs.medusajs.com/api/admin#stock-locations_poststocklocations): - + -```ts -medusa.admin.stockLocations.create({ - name: "Main Warehouse", -}) -.then(({ stock_location }) => { - console.log(stock_location.id) -}) -``` - - - - -```tsx -import { useAdminCreateStockLocation } from "medusa-react" - -const CreateStockLocation = () => { - const createStockLocation = useAdminCreateStockLocation() - // ... - - const handleCreate = () => { - createStockLocation.mutate({ + ```ts + medusa.admin.stockLocations.create({ name: "Main Warehouse", }) - } + .then(({ stock_location }) => { + console.log(stock_location.id) + }) + ``` - // ... -} + + -export default CreateStockLocation -``` + ```tsx + import { useAdminCreateStockLocation } from "medusa-react" - - + const CreateStockLocation = () => { + const createStockLocation = useAdminCreateStockLocation() + // ... -```ts -fetch(`/admin/stock-locations`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - name: "Main Warehouse", - }), -}) -.then((response) => response.json()) -.then(({ stock_location }) => { - console.log(stock_location.id) -}) -``` + const handleCreate = () => { + createStockLocation.mutate({ + name: "Main Warehouse", + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/stock-locations' \ - -H 'Authorization: Bearer ' \ - -H 'Content-Type: application/json' \ - --data-raw '{ - "name": "Main Warehouse" - }' -``` + export default CreateStockLocation + ``` - + + + + ```ts + fetch(`/admin/stock-locations`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + name: "Main Warehouse", + }), + }) + .then((response) => response.json()) + .then(({ stock_location }) => { + console.log(stock_location.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/stock-locations' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "name": "Main Warehouse" + }' + ``` + + This API Route requires in its body parameters the `name` field, which is the name of the stock location. You can also pass in the request body parameters other fields related to the address or metadata. You can learn more in the [API reference](https://docs.medusajs.com/api/admin#stock-locations_poststocklocations). @@ -218,63 +218,63 @@ This request returns the created stock location as an object. You can retrieve a stock location by sending a request to the [Get Stock Location API Route](https://docs.medusajs.com/api/admin#stock-locations_getstocklocationsstocklocation): - + -```ts -medusa.admin.stockLocations.retrieve(stockLocationId) -.then(({ stock_location }) => { - console.log(stock_location.id) -}) -``` + ```ts + medusa.admin.stockLocations.retrieve(stockLocationId) + .then(({ stock_location }) => { + console.log(stock_location.id) + }) + ``` - - + + -```tsx -import { useAdminStockLocation } from "medusa-react" + ```tsx + import { useAdminStockLocation } from "medusa-react" -function StockLocation() { - const { - stock_location, - isLoading } = useAdminStockLocation(stockLocationId) + function StockLocation() { + const { + stock_location, + isLoading } = useAdminStockLocation(stockLocationId) - return ( -
- {isLoading && Loading...} - {stock_location && ( - {stock_location.name} - )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {stock_location && ( + {stock_location.name} + )} +
+ ) + } -export default StockLocation -``` + export default StockLocation + ``` -
- + + -```ts -fetch(`/admin/stock-locations/${stockLocationId}`, - { - credentials: "include", - } -) -.then((response) => response.json()) -.then(({ stock_location }) => { - console.log(stock_location.id) -}) -``` + ```ts + fetch(`/admin/stock-locations/${stockLocationId}`, + { + credentials: "include", + } + ) + .then((response) => response.json()) + .then(({ stock_location }) => { + console.log(stock_location.id) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/stock-locations/' \ - -H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/stock-locations/' \ + -H 'Authorization: Bearer ' + ``` - +
This API Route requires the stock location ID to be passed as a path parameter. It also accepts query parameters related to expanding and selecting fields. You can learn more in the [API reference](https://docs.medusajs.com/api/admin#stock-locations_getstocklocationsstocklocation). @@ -288,73 +288,73 @@ It returns the stock location as an object. You can associate a stock location with a sales channel by sending a request to the [Associate Stock Channel API Route](https://docs.medusajs.com/api/admin#sales-channels_postsaleschannelssaleschannelstocklocation): - + -```ts -medusa.admin.salesChannels.addLocation(salesChannelId, { - location_id, -}) -.then(({ sales_channel }) => { - console.log(sales_channel.id) -}) -``` - - - - -```tsx -import { useAdminAddLocationToSalesChannel } from "medusa-react" - -function StockLocation() { - const addLocation = useAdminAddLocationToSalesChannel() - // ... - - const handleAdd = () => { - addLocation.mutate({ - sales_channel_id, + ```ts + medusa.admin.salesChannels.addLocation(salesChannelId, { location_id, }) - } -} + .then(({ sales_channel }) => { + console.log(sales_channel.id) + }) + ``` -export default StockLocation -``` + + - - + ```tsx + import { useAdminAddLocationToSalesChannel } from "medusa-react" + + function StockLocation() { + const addLocation = useAdminAddLocationToSalesChannel() + // ... + + const handleAdd = () => { + addLocation.mutate({ + sales_channel_id, + location_id, + }) + } + } + + export default StockLocation + ``` + + + -```ts -fetch(`/admin/sales-channels/${salesChannelId}/stock-locations`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - location_id, - }), -}) -.then((response) => response.json()) -.then(({ sales_channel }) => { - console.log(sales_channel.id) -}) -``` + ```ts + fetch(`/admin/sales-channels/${salesChannelId}/stock-locations`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + location_id, + }), + }) + .then((response) => response.json()) + .then(({ sales_channel }) => { + console.log(sales_channel.id) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/sales-channels//stock-locations' \ - -H 'Authorization: Bearer ' \ - -H 'Content-Type: application/json' \ - --data-raw '{ - "location_id": "" - }' -``` + ```bash + curl -L -X POST '/admin/sales-channels//stock-locations' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "location_id": "" + }' + ``` - + This API Route requires the ID of the sales channel as a path parameter. In its body parameters, it requires the ID of the stock location you’re associating the sales channel with. @@ -374,76 +374,76 @@ You can associate a location with more than one sales channel, and you can assoc You can remove the association between a stock location and a sales channel by sending a request to the [Remove Stock Location Association API Route](https://docs.medusajs.com/api/admin#sales-channels_deletesaleschannelssaleschannelstocklocation): - + -```ts -medusa.admin.salesChannels.removeLocation(salesChannelId, { - location_id, -}) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` - - - - -```tsx -import { - useAdminRemoveLocationFromSalesChannel, -} from "medusa-react" - -function StockLocation() { - const removeLocation = - useAdminRemoveLocationFromSalesChannel() - // ... - - const handleRemove = () => { - removeLocation.mutate({ - sales_channel_id, + ```ts + medusa.admin.salesChannels.removeLocation(salesChannelId, { location_id, }) - } -} + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` -export default StockLocation -``` + + - - + ```tsx + import { + useAdminRemoveLocationFromSalesChannel, + } from "medusa-react" + + function StockLocation() { + const removeLocation = + useAdminRemoveLocationFromSalesChannel() + // ... + + const handleRemove = () => { + removeLocation.mutate({ + sales_channel_id, + location_id, + }) + } + } + + export default StockLocation + ``` + + + -```ts -fetch(`/admin/sales-channels/${salesChannelId}/stock-locations`, { - credentials: "include", - method: "DELETE", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - location_id, - }), -}) -.then((response) => response.json()) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + fetch(`/admin/sales-channels/${salesChannelId}/stock-locations`, { + credentials: "include", + method: "DELETE", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + location_id, + }), + }) + .then((response) => response.json()) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/sales-channels//stock-locations' \ - -H 'Authorization: Bearer ' \ - -H 'Content-Type: application/json' \ - --data-raw '{ - "location_id": "" - }' -``` + ```bash + curl -L -X DELETE '/admin/sales-channels//stock-locations' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "location_id": "" + }' + ``` - + This API Route requires the ID of the sales channel as a path parameter. In its body parameters, it requires the ID of the stock location you’re removing the association of the sales channel with. @@ -467,74 +467,74 @@ This request does not delete the stock location. It only removes the association You can update a stock location by sending a request to the [Update Stock Location API Route](https://docs.medusajs.com/api/admin#stock-locations_poststocklocationsstocklocation): - + -```ts -medusa.admin.stockLocations.update(stockLocationId, { - name: "Warehouse", -}) -.then(({ stock_location }) => { - console.log(stock_location.id) -}) -``` - - - - -```tsx -import { useAdminUpdateStockLocation } from "medusa-react" - -function StockLocation() { - const updateLocation = useAdminUpdateStockLocation( - stockLocationId - ) - // ... - - const handleRemove = () => { - updateLocation.mutate({ + ```ts + medusa.admin.stockLocations.update(stockLocationId, { name: "Warehouse", }) - } -} + .then(({ stock_location }) => { + console.log(stock_location.id) + }) + ``` -export default StockLocation -``` + + - - + ```tsx + import { useAdminUpdateStockLocation } from "medusa-react" -```ts -fetch(`/admin/stock-locations/${stockLocationId}`, - { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - name: "Warehouse", - }), - } -) -.then((response) => response.json()) -.then(({ stock_location }) => { - console.log(stock_location.id) -}) -``` + function StockLocation() { + const updateLocation = useAdminUpdateStockLocation( + stockLocationId + ) + // ... - - + const handleRemove = () => { + updateLocation.mutate({ + name: "Warehouse", + }) + } + } -```bash -curl -L -X POST '/admin/stock-locations/' \ - -H 'Authorization: Bearer ' \ - -H 'Content-Type: application/json' \ - --data-raw '{ - "name": "Main Warehouse" - }' -``` + export default StockLocation + ``` - + + + + ```ts + fetch(`/admin/stock-locations/${stockLocationId}`, + { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + name: "Warehouse", + }), + } + ) + .then((response) => response.json()) + .then(({ stock_location }) => { + console.log(stock_location.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/stock-locations/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "name": "Main Warehouse" + }' + ``` + + This API Route requires the ID of a stock location as a path parameter. In its body parameters, you can pass any of the location’s attributes to update, such as the name or address. You can learn more in the [API reference](https://docs.medusajs.com/api/admin#stock-locations_poststocklocationsstocklocation). @@ -548,60 +548,60 @@ This request returns the updated stock location as an object. You can delete a stock location by sending a request to the [Delete Stock Location API Route](https://docs.medusajs.com/api/admin#stock-locations_deletestocklocationsstocklocation): - + -```ts -medusa.admin.stockLocations.delete(stockLocationId) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + medusa.admin.stockLocations.delete(stockLocationId) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```tsx -import { useAdminDeleteStockLocation } from "medusa-react" + ```tsx + import { useAdminDeleteStockLocation } from "medusa-react" -function StockLocation() { - const deleteLocation = useAdminDeleteStockLocation( - stockLocationId - ) - // ... + function StockLocation() { + const deleteLocation = useAdminDeleteStockLocation( + stockLocationId + ) + // ... - const handleDelete = () => { - deleteLocation.mutate() - } -} + const handleDelete = () => { + deleteLocation.mutate() + } + } -export default StockLocation -``` + export default StockLocation + ``` - - + + -```ts -fetch(`/admin/stock-locations/${stockLocationId}`, - { - credentials: "include", - method: "DELETE", - } -) -.then((response) => response.json()) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + fetch(`/admin/stock-locations/${stockLocationId}`, + { + credentials: "include", + method: "DELETE", + } + ) + .then((response) => response.json()) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/stock-locations/' \ - -H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/stock-locations/' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the ID of the stock location as a path parameter. diff --git a/www/apps/docs/content/modules/orders/admin/edit-order.mdx b/www/apps/docs/content/modules/orders/admin/edit-order.mdx index 853c0fa670..911d82ac74 100644 --- a/www/apps/docs/content/modules/orders/admin/edit-order.mdx +++ b/www/apps/docs/content/modules/orders/admin/edit-order.mdx @@ -83,71 +83,71 @@ Before you can start making changes to an order, you have to create a new order To do that, send a request to the [Create an OrderEdit API Route](https://docs.medusajs.com/api/admin#order-edits_postorderedits): - + -```ts -medusa.admin.orderEdits.create({ - order_id, // required -}) -.then(({ order_edit }) => { - console.log(order_edit.id) -}) -``` - - - - -```tsx -import { useAdminCreateOrderEdit } from "medusa-react" - -const OrderEdit = () => { - const createOrderEdit = useAdminCreateOrderEdit() - - const handleCreateOrderEdit = (orderId: string) => { - createOrderEdit.mutate({ - order_id: orderId, + ```ts + medusa.admin.orderEdits.create({ + order_id, // required }) - } - - // ... -} + .then(({ order_edit }) => { + console.log(order_edit.id) + }) + ``` -export default OrderEdit -``` + + - - + ```tsx + import { useAdminCreateOrderEdit } from "medusa-react" -```ts -fetch(`/admin/order-edits`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - order_id, - }), -}) -.then((response) => response.json()) -.then(({ order_edit }) => { - console.log(order_edit.id) -}) -``` + const OrderEdit = () => { + const createOrderEdit = useAdminCreateOrderEdit() - - + const handleCreateOrderEdit = (orderId: string) => { + createOrderEdit.mutate({ + order_id: orderId, + }) + } + + // ... + } -```bash -curl -L -X POST '/admin/order-edits' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "order_id": "" -}' -``` + export default OrderEdit + ``` - + + + + ```ts + fetch(`/admin/order-edits`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + order_id, + }), + }) + .then((response) => response.json()) + .then(({ order_edit }) => { + console.log(order_edit.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/order-edits' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "order_id": "" + }' + ``` + + This API Route has one required request body parameter `order_id` which is the ID of the order this edit is being created for. @@ -177,76 +177,76 @@ You can only make changes to items that have not been fulfilled yet in the order To add a new item to the original order, send a request to the [Add Line Item API Route](https://docs.medusajs.com/api/admin#order-edits_postordereditseditlineitems): - + -```ts -medusa.admin.orderEdits.addLineItem(orderEditId, { - quantity: 1, - variant_id, -}) -.then(({ order_edit }) => { - console.log(order_edit.changes) -}) -``` + ```ts + medusa.admin.orderEdits.addLineItem(orderEditId, { + quantity: 1, + variant_id, + }) + .then(({ order_edit }) => { + console.log(order_edit.changes) + }) + ``` - - + + -```tsx -import { useAdminOrderEditAddLineItem } from "medusa-react" + ```tsx + import { useAdminOrderEditAddLineItem } from "medusa-react" -const OrderEdit = () => { - const addLineItem = useAdminOrderEditAddLineItem(orderEditId) + const OrderEdit = () => { + const addLineItem = useAdminOrderEditAddLineItem(orderEditId) - const handleAddLineItem = - (quantity: number, variantId: string) => { - addLineItem.mutate({ - quantity, - variant_id: variantId, - }) + const handleAddLineItem = + (quantity: number, variantId: string) => { + addLineItem.mutate({ + quantity, + variant_id: variantId, + }) + } + + // ... } - - // ... -} -export default OrderEdit -``` + export default OrderEdit + ``` - - + + -```ts -fetch(`/admin/order-edits/${orderEditId}/items`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - quantity: 1, - variant_id, - }), -}) -.then((response) => response.json()) -.then(({ order_edit }) => { - console.log(order_edit.changes) -}) -``` + ```ts + fetch(`/admin/order-edits/${orderEditId}/items`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + quantity: 1, + variant_id, + }), + }) + .then((response) => response.json()) + .then(({ order_edit }) => { + console.log(order_edit.changes) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/order-edits//items' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "quantity": 1, - "variant_id": "" -}' -``` + ```bash + curl -L -X POST '/admin/order-edits//items' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "quantity": 1, + "variant_id": "" + }' + ``` - + This request requires the ID of the order edit as a path parameter. @@ -262,76 +262,75 @@ You can edit an item’s quantity in the original order. To update an item, send a request to the [Update Line Item API Route](https://docs.medusajs.com/api/admin#order-edits_postordereditseditlineitemslineitem): - + -```ts -medusa.admin.orderEdits.updateLineItem(orderEditId, itemId, { - quantity: 2, -}) -.then(({ order_edit }) => { - console.log(order_edit.changes) -}) -``` - - - - -```tsx -import { useAdminOrderEditUpdateLineItem } from "medusa-react" - -const OrderEdit = () => { - const updateLineItem = useAdminOrderEditUpdateLineItem( - orderEditId, - itemId - ) - - const handleUpdateLineItem = (quantity: number) => { - updateLineItem.mutate({ - quantity, + ```ts + medusa.admin.orderEdits.updateLineItem(orderEditId, itemId, { + quantity: 2, }) - } + .then(({ order_edit }) => { + console.log(order_edit.changes) + }) + ``` - // ... -} + + -export default OrderEdit -``` + ```tsx + import { useAdminOrderEditUpdateLineItem } from "medusa-react" - - + const OrderEdit = () => { + const updateLineItem = useAdminOrderEditUpdateLineItem( + orderEditId, + itemId + ) + + const handleUpdateLineItem = (quantity: number) => { + updateLineItem.mutate({ + quantity, + }) + } + + // ... + } + + export default OrderEdit + ``` + + + -```ts -fetch(`/admin/order-edits/${orderEditId}/items/${itemId}`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - quantity: 2, - }), -}) -.then((response) => response.json()) -.then(({ order_edit }) => { - console.log(order_edit.changes) -}) -``` + ```ts + fetch(`/admin/order-edits/${orderEditId}/items/${itemId}`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + quantity: 2, + }), + }) + .then((response) => response.json()) + .then(({ order_edit }) => { + console.log(order_edit.changes) + }) + ``` + + - - + ```bash + curl -L -X POST '/admin/order-edits//items/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "quantity": 2 + }' + ``` -```bash -curl -L -X POST '/admin/order-edits//items/' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "quantity": 2 -}' -``` - - + This request requires the ID of the order edit and the ID of the item in the original order as path parameters. @@ -345,62 +344,62 @@ This request returns the Order Edit object. You can access returned item changes You can remove an item from the original order by sending a request to the [Remove Line Item API Route](https://docs.medusajs.com/api/admin#order-edits_deleteordereditsordereditlineitemslineitem): - + -```ts -medusa.admin.orderEdits.removeLineItem(orderEditId, itemId) -.then(({ order_edit }) => { - console.log(order_edit.changes) -}) -``` + ```ts + medusa.admin.orderEdits.removeLineItem(orderEditId, itemId) + .then(({ order_edit }) => { + console.log(order_edit.changes) + }) + ``` - - + + -```tsx -import { useAdminOrderEditDeleteLineItem } from "medusa-react" + ```tsx + import { useAdminOrderEditDeleteLineItem } from "medusa-react" -const OrderEdit = () => { - const removeLineItem = useAdminOrderEditDeleteLineItem( - orderEditId, - itemId - ) - - const handleRemoveLineItem = () => { - removeLineItem.mutate() - } + const OrderEdit = () => { + const removeLineItem = useAdminOrderEditDeleteLineItem( + orderEditId, + itemId + ) + + const handleRemoveLineItem = () => { + removeLineItem.mutate() + } - // ... -} + // ... + } -export default OrderEdit -``` + export default OrderEdit + ``` - - + + -```ts -fetch(`/admin/order-edits/${orderEditId}/items/${itemId}`, { - method: "DELETE", - credentials: "include", -}) -.then((response) => response.json()) -.then(({ order_edit }) => { - console.log(order_edit.changes) -}) -``` + ```ts + fetch(`/admin/order-edits/${orderEditId}/items/${itemId}`, { + method: "DELETE", + credentials: "include", + }) + .then((response) => response.json()) + .then(({ order_edit }) => { + console.log(order_edit.changes) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/order-edits//items/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/order-edits//items/' \ + -H 'Authorization: Bearer ' + ``` - + This request requires the order edit’s ID and the ID of the item in the original order as path parameters. @@ -416,65 +415,65 @@ A merchant might make a mistake while making a change to the original order’s To revert an item change, send a request to the [Delete Item Change API Route](https://docs.medusajs.com/api/admin#order-edits_deleteordereditsorderedititemchange): - + -```ts -medusa.admin.orderEdits.deleteItemChange(orderEditId, changeId) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + medusa.admin.orderEdits.deleteItemChange(orderEditId, changeId) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```tsx -import { useAdminDeleteOrderEditItemChange } from "medusa-react" + ```tsx + import { useAdminDeleteOrderEditItemChange } from "medusa-react" -const OrderEdit = () => { - const deleteItemChange = useAdminDeleteOrderEditItemChange( - orderEditId, - itemChangeId - ) - - const handleDeleteItemChange = () => { - deleteItemChange.mutate() - } + const OrderEdit = () => { + const deleteItemChange = useAdminDeleteOrderEditItemChange( + orderEditId, + itemChangeId + ) + + const handleDeleteItemChange = () => { + deleteItemChange.mutate() + } - // ... -} + // ... + } -export default OrderEdit -``` + export default OrderEdit + ``` - - + + -```ts -fetch( - `/admin/order-edits/${orderEditId}/changes/${changeId}`, - { - method: "DELETE", - credentials: "include", - } -) -.then((response) => response.json()) -.then(({ id, object, deleted }) => { - console.log(id, object, deleted) -}) -``` + ```ts + fetch( + `/admin/order-edits/${orderEditId}/changes/${changeId}`, + { + method: "DELETE", + credentials: "include", + } + ) + .then((response) => response.json()) + .then(({ id, object, deleted }) => { + console.log(id, object, deleted) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/order-edits//changes/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/order-edits//changes/' \ + -H 'Authorization: Bearer ' + ``` - + This request requires the order edit’s ID and the item change’s ID as path parameters. @@ -494,67 +493,67 @@ After an Order Edit is created and all the item changes are added, it must be mo To move an Order Edit into the request state, send a request to the [Request Confirmation API Route](https://docs.medusajs.com/api/admin#order-edits_postordereditsordereditrequest): - + -```ts -medusa.admin.orderEdits.requestConfirmation(orderEditId) -.then(({ order_edit }) => { - console.log( - order_edit.requested_at, - order_edit.requested_by - ) -}) -``` + ```ts + medusa.admin.orderEdits.requestConfirmation(orderEditId) + .then(({ order_edit }) => { + console.log( + order_edit.requested_at, + order_edit.requested_by + ) + }) + ``` - - + + -```tsx -import { - useAdminRequestOrderEditConfirmation, -} from "medusa-react" + ```tsx + import { + useAdminRequestOrderEditConfirmation, + } from "medusa-react" -const OrderEdit = () => { - const requestOrderConfirmation = - useAdminRequestOrderEditConfirmation( - orderEditId - ) - - const handleRequestConfirmation = () => { - requestOrderConfirmation.mutate() - } + const OrderEdit = () => { + const requestOrderConfirmation = + useAdminRequestOrderEditConfirmation( + orderEditId + ) + + const handleRequestConfirmation = () => { + requestOrderConfirmation.mutate() + } - // ... -} + // ... + } -export default OrderEdit -``` + export default OrderEdit + ``` - - + + -```ts -fetch(`/admin/order-edits/${orderEditId}/request`, { - method: "POST", - credentials: "include", -}) -.then((response) => response.json()) -.then(({ order_edit }) => { - console.log(order_edit.requested_at, order_edit.requested_by) -}) -``` + ```ts + fetch(`/admin/order-edits/${orderEditId}/request`, { + method: "POST", + credentials: "include", + }) + .then((response) => response.json()) + .then(({ order_edit }) => { + console.log(order_edit.requested_at, order_edit.requested_by) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/order-edits//request' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X POST '/admin/order-edits//request' \ + -H 'Authorization: Bearer ' + ``` - + This request requires the order edit’s ID as a path parameter. @@ -590,59 +589,59 @@ This section covers how the Admin API can be used to force-confirm the Order Edi To confirm an Order Edit, send a request to the [Confirm Order Edit API Route](https://docs.medusajs.com/api/admin#order-edits_postordereditsordereditconfirm): - + -```ts -medusa.admin.orderEdits.confirm(orderEditId) -.then(({ order_edit }) => { - console.log(order_edit.confirmed_at, order_edit.confirmed_by) -}) -``` + ```ts + medusa.admin.orderEdits.confirm(orderEditId) + .then(({ order_edit }) => { + console.log(order_edit.confirmed_at, order_edit.confirmed_by) + }) + ``` - - + + -```tsx -import { useAdminConfirmOrderEdit } from "medusa-react" + ```tsx + import { useAdminConfirmOrderEdit } from "medusa-react" -const OrderEdit = () => { - const confirmOrderEdit = useAdminConfirmOrderEdit(orderEditId) - - const handleConfirmOrderEdit = () => { - confirmOrderEdit.mutate() - } + const OrderEdit = () => { + const confirmOrderEdit = useAdminConfirmOrderEdit(orderEditId) + + const handleConfirmOrderEdit = () => { + confirmOrderEdit.mutate() + } - // ... -} + // ... + } -export default OrderEdit -``` + export default OrderEdit + ``` - - + + -```ts -fetch(`/admin/order-edits/${orderEditId}/confirm`, { - method: "POST", - credentials: "include", -}) -.then((response) => response.json()) -.then(({ order_edit }) => { - console.log(order_edit.confirmed_at, order_edit.confirmed_by) -}) -``` + ```ts + fetch(`/admin/order-edits/${orderEditId}/confirm`, { + method: "POST", + credentials: "include", + }) + .then((response) => response.json()) + .then(({ order_edit }) => { + console.log(order_edit.confirmed_at, order_edit.confirmed_by) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/order-edits//confirm' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X POST '/admin/order-edits//confirm' \ + -H 'Authorization: Bearer ' + ``` - + This request accepts the order edit ID as a path parameter. @@ -673,59 +672,59 @@ You can learn how to allow customers to authorize payment on the storefront in [ If the payment is authorized by the customer, it can be captured by sending a request to the [Capture Payment API Route](https://docs.medusajs.com/api/admin#payments_postpaymentspaymentcapture): - + -```ts -medusa.admin.payments.capturePayment(paymentId) -.then(({ payment }) => { - console.log(payment.captured_at) -}) -``` + ```ts + medusa.admin.payments.capturePayment(paymentId) + .then(({ payment }) => { + console.log(payment.captured_at) + }) + ``` - - + + -```tsx -import { useAdminPaymentsCapturePayment } from "medusa-react" + ```tsx + import { useAdminPaymentsCapturePayment } from "medusa-react" -const OrderEditPayment = () => { - const capturePayment = useAdminPaymentsCapturePayment( - paymentId - ) - - const handleCapturePayment = () => { - capturePayment.mutate() - } + const OrderEditPayment = () => { + const capturePayment = useAdminPaymentsCapturePayment( + paymentId + ) + + const handleCapturePayment = () => { + capturePayment.mutate() + } - // ... -} + // ... + } -export default OrderEditPayment -``` + export default OrderEditPayment + ``` - - + + -```ts -fetch(`/admin/payments/${paymentId}/capture`, { - method: "POST", - credentials: "include", -}) -.then((response) => response.json()) -.then(({ payment }) => { - console.log(payment.captured_at) -}) -``` + ```ts + fetch(`/admin/payments/${paymentId}/capture`, { + method: "POST", + credentials: "include", + }) + .then((response) => response.json()) + .then(({ payment }) => { + console.log(payment.captured_at) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/payments//capture' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X POST '/admin/payments//capture' \ + -H 'Authorization: Bearer ' + ``` - + This request requires the ID of the payment as a path parameter. The payment can be retrieved from the order by accessing the array property `order.payments`. @@ -739,80 +738,80 @@ When the total after the order edit is less than the original order total, the m To refund the difference to the customer, send a request to the [Refund Payment API Route](https://docs.medusajs.com/api/admin#payments_postpaymentspaymentrefunds): - + -```ts -import { RefundReason } from "@medusajs/medusa" -// ... + ```ts + import { RefundReason } from "@medusajs/medusa" + // ... -medusa.admin.payments.refundPayment(paymentId, { - amount, - reason: RefundReason.DISCOUNT, // for example -}) -.then(({ refund }) => { - console.log(refund.id) -}) -``` + medusa.admin.payments.refundPayment(paymentId, { + amount, + reason: RefundReason.DISCOUNT, // for example + }) + .then(({ refund }) => { + console.log(refund.id) + }) + ``` - - + + -```tsx -import { useAdminPaymentsRefundPayment } from "medusa-react" -import { RefundReason } from "@medusajs/medusa" + ```tsx + import { useAdminPaymentsRefundPayment } from "medusa-react" + import { RefundReason } from "@medusajs/medusa" -const OrderEditPayment = () => { - const refundPayment = useAdminPaymentsRefundPayment(paymentId) - - const handleRefundPayment = - (amount: number, reason: RefundReason) => { - refundPayment.mutate({ - amount, - reason, - }) + const OrderEditPayment = () => { + const refundPayment = useAdminPaymentsRefundPayment(paymentId) + + const handleRefundPayment = + (amount: number, reason: RefundReason) => { + refundPayment.mutate({ + amount, + reason, + }) + } + + // ... } - // ... -} + export default OrderEditPayment + ``` -export default OrderEditPayment -``` + + - - + ```ts + fetch(`/admin/payments/${paymentId}/refund`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + amount, + reason: "discount", + }), + }) + .then((response) => response.json()) + .then(({ refund }) => { + console.log(refund.id) + }) + ``` -```ts -fetch(`/admin/payments/${paymentId}/refund`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - amount, - reason: "discount", - }), -}) -.then((response) => response.json()) -.then(({ refund }) => { - console.log(refund.id) -}) -``` + + - - + ```bash + curl -L -X POST '/admin/payments//refund' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "amount": 1000, + "reason": "discount" + }' + ``` -```bash -curl -L -X POST '/admin/payments//refund' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "amount": 1000, - "reason": "discount" -}' -``` - - + This request requires the ID of the payment as a path parameter. The payment can be retrieved from the order by accessing the array property `order.payments`. diff --git a/www/apps/docs/content/modules/orders/admin/manage-claims.mdx b/www/apps/docs/content/modules/orders/admin/manage-claims.mdx index 6340eb7daa..ce006d8f1a 100644 --- a/www/apps/docs/content/modules/orders/admin/manage-claims.mdx +++ b/www/apps/docs/content/modules/orders/admin/manage-claims.mdx @@ -61,72 +61,72 @@ You can learn more about [authenticating as an admin user in the API reference]( To view an order’s claims, you can retrieve the order using the [Get Order API Route](https://docs.medusajs.com/api/admin#orders_getordersorder) and access the order’s claims: - + -```ts -medusa.admin.orders.retrieve(orderId) -.then(({ order }) => { - console.log(order.claims) -}) -``` + ```ts + medusa.admin.orders.retrieve(orderId) + .then(({ order }) => { + console.log(order.claims) + }) + ``` - - + + -```tsx -import { useAdminOrder } from "medusa-react" + ```tsx + import { useAdminOrder } from "medusa-react" -const Order = () => { - const { - order, - isLoading, - } = useAdminOrder(orderId) - - return ( -
- {isLoading && Loading...} - {order && ( - <> - {order.display_id} - {order.claims?.length > 0 && ( -
    - {order.claims.map((claim) => ( -
  • {claim.id}
  • - ))} -
+ const Order = () => { + const { + order, + isLoading, + } = useAdminOrder(orderId) + + return ( +
+ {isLoading && Loading...} + {order && ( + <> + {order.display_id} + {order.claims?.length > 0 && ( +
    + {order.claims.map((claim) => ( +
  • {claim.id}
  • + ))} +
+ )} + )} - - )} - -
- ) -} + +
+ ) + } -export default Order -``` + export default Order + ``` -
- + + -```ts -fetch(`/admin/orders/${orderId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.claims) -}) -``` + ```ts + fetch(`/admin/orders/${orderId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.claims) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/orders/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/orders/' \ + -H 'Authorization: Bearer ' + ``` - +
This request requires the order’s ID as a path parameter. @@ -140,35 +140,10 @@ The request returns the order as an object. In that object, you can access an ar You can create a claim by sending a request to the [Create Claim API Route](https://docs.medusajs.com/api/admin#orders_postordersorderclaims): - + -```ts -medusa.admin.orders.createClaim(orderId, { - type: "refund", - claim_items: [ - { - item_id, - quantity: 1, - }, - ], -}) -.then(({ order }) => { - console.log(order.claims) -}) -``` - - - - -```tsx -import { useAdminCreateClaim } from "medusa-react" - -const CreateClaim = () => { - const createClaim = useAdminCreateClaim(orderId) - // ... - - const handleCreate = () => { - createClaim.mutate({ + ```ts + medusa.admin.orders.createClaim(orderId, { type: "refund", claim_items: [ { @@ -177,59 +152,84 @@ const CreateClaim = () => { }, ], }) - } + .then(({ order }) => { + console.log(order.claims) + }) + ``` - // ... -} + + -export default CreateClaim -``` + ```tsx + import { useAdminCreateClaim } from "medusa-react" - - + const CreateClaim = () => { + const createClaim = useAdminCreateClaim(orderId) + // ... -```ts -fetch(`/admin/orders/${orderId}/claims`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - type: "refund", - claim_items: [ - { - item_id, - quantity: 1, - }, - ], - }), -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.claims) -}) -``` - - - - -```bash -curl -L -X POST '/admin/orders//claims' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "type": "refund", - "claim_items": [ - { - "item_id": "", - "quantity": 1 + const handleCreate = () => { + createClaim.mutate({ + type: "refund", + claim_items: [ + { + item_id, + quantity: 1, + }, + ], + }) } - ] -}' -``` - + // ... + } + + export default CreateClaim + ``` + + + + + ```ts + fetch(`/admin/orders/${orderId}/claims`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + type: "refund", + claim_items: [ + { + item_id, + quantity: 1, + }, + ], + }), + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.claims) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/orders//claims' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "type": "refund", + "claim_items": [ + { + "item_id": "", + "quantity": 1 + } + ] + }' + ``` + + This API Route requires the order ID to be passed as a path parameter. @@ -258,76 +258,76 @@ The request returns the updated order as an object. You can access the order’s You can update a claim by sending a request to the [Update Claim API Route](https://docs.medusajs.com/api/admin#orders_postordersorderclaimsclaim): - + -```ts -medusa.admin.orders.updateClaim(orderId, claimId, { - no_notification: true, -}) -.then(({ order }) => { - console.log(order.claims) -}) -``` - - - - -```tsx -import { useAdminUpdateClaim } from "medusa-react" - -const UpdateClaim = () => { - const updateClaim = useAdminUpdateClaim(orderId) - // ... - - const handleUpdate = () => { - updateClaim.mutate({ - claim_id, + ```ts + medusa.admin.orders.updateClaim(orderId, claimId, { no_notification: true, }) - } + .then(({ order }) => { + console.log(order.claims) + }) + ``` - // ... -} + + -export default UpdateClaim -``` + ```tsx + import { useAdminUpdateClaim } from "medusa-react" - - + const UpdateClaim = () => { + const updateClaim = useAdminUpdateClaim(orderId) + // ... -```ts -fetch( - `/admin/orders/${orderId}/claims/${claimId}`, - { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - no_notification: true, - }), - } -) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.claims) -}) -``` + const handleUpdate = () => { + updateClaim.mutate({ + claim_id, + no_notification: true, + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/orders//claims/' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "no_notification": true -}' -``` + export default UpdateClaim + ``` - + + + + ```ts + fetch( + `/admin/orders/${orderId}/claims/${claimId}`, + { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + no_notification: true, + }), + } + ) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.claims) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/orders//claims/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "no_notification": true + }' + ``` + + This API Route requires the ID of the order and the claim to be passed as path parameters. @@ -349,63 +349,63 @@ Fulfillments are available on a claim object under the `fulfillments` property, You can create a fulfillment for a claim by sending a request to the [Create Claim Fulfillment API Route](https://docs.medusajs.com/api/admin#orders_postordersorderclaimsclaimfulfillments): - + -```ts -medusa.admin.orders.fulfillClaim(orderId, claimId, { -}) -.then(({ order }) => { - console.log(order.claims) -}) -``` - - - - -```tsx -import { useAdminFulfillClaim } from "medusa-react" - -const FulfillClaim = () => { - const fulfillClaim = useAdminFulfillClaim(orderId) - // ... - - const handleFulfill = () => { - fulfillClaim.mutate({ - claim_id, + ```ts + medusa.admin.orders.fulfillClaim(orderId, claimId, { }) - } + .then(({ order }) => { + console.log(order.claims) + }) + ``` - // ... -} + + -export default FulfillClaim -``` + ```tsx + import { useAdminFulfillClaim } from "medusa-react" - - + const FulfillClaim = () => { + const fulfillClaim = useAdminFulfillClaim(orderId) + // ... + + const handleFulfill = () => { + fulfillClaim.mutate({ + claim_id, + }) + } + + // ... + } + + export default FulfillClaim + ``` + + + -```ts -fetch(`/admin/orders/${orderId}/claims/${claimId}/fulfillments`, { - credentials: "include", - method: "POST", -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.claims) -}) -``` + ```ts + fetch(`/admin/orders/${orderId}/claims/${claimId}/fulfillments`, { + credentials: "include", + method: "POST", + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.claims) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/orders//claims//fulfillments' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X POST '/admin/orders//claims//fulfillments' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the order and claim IDs as path parameters. @@ -419,75 +419,75 @@ The request returns the updated order as an object. You can access the order’s You can create a shipment for a claim by sending a request to the [Create Claim Shipment API Route](https://docs.medusajs.com/api/admin#orders_postordersorderclaimsclaimshipments): - + -```ts -medusa.admin.orders.createClaimShipment(orderId, claimId, { - fulfillment_id, -}) -.then(({ order }) => { - console.log(order.claims) -}) -``` - - - - -```tsx -import { useAdminCreateClaimShipment } from "medusa-react" - -const CreateShipment = () => { - const createShipment = useAdminCreateClaimShipment(orderId) - // ... - - const handleCreate = () => { - createShipment.mutate({ - claim_id, + ```ts + medusa.admin.orders.createClaimShipment(orderId, claimId, { fulfillment_id, }) - } + .then(({ order }) => { + console.log(order.claims) + }) + ``` - // ... -} + + -export default CreateShipment -``` + ```tsx + import { useAdminCreateClaimShipment } from "medusa-react" - - + const CreateShipment = () => { + const createShipment = useAdminCreateClaimShipment(orderId) + // ... + + const handleCreate = () => { + createShipment.mutate({ + claim_id, + fulfillment_id, + }) + } + + // ... + } + + export default CreateShipment + ``` + + + -```ts -fetch(`/admin/orders/${orderId}/claims/${claimId}/shipments`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - fulfillment_id, - }), -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.claims) -}) -``` + ```ts + fetch(`/admin/orders/${orderId}/claims/${claimId}/shipments`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + fulfillment_id, + }), + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.claims) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/orders//claims//shipments' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "fulfillment_id": "" -}' -``` + ```bash + curl -L -X POST '/admin/orders//claims//shipments' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "fulfillment_id": "" + }' + ``` - + This API Route requires the order and claim IDs as path parameters. @@ -511,69 +511,69 @@ You can’t cancel a fulfillment that has a shipment You can cancel a fulfillment by sending a request to the [Cancel Fulfillment API Route](https://docs.medusajs.com/api/admin#orders_postordersclaimfulfillmentscancel): - + -```ts -medusa.admin.orders.cancelClaimFulfillment( - orderId, - claimId, - fulfillmentId -) -.then(({ order }) => { - console.log(order.claims) -}) -``` - - - - -```tsx -import { useAdminCancelClaimFulfillment } from "medusa-react" - -const CancelFulfillment = () => { - const cancelFulfillment = useAdminCancelClaimFulfillment( - orderId - ) - // ... - - const handleCancel = () => { - cancelFulfillment.mutate({ - claim_id, - fulfillment_id, + ```ts + medusa.admin.orders.cancelClaimFulfillment( + orderId, + claimId, + fulfillmentId + ) + .then(({ order }) => { + console.log(order.claims) }) - } + ``` - // ... -} + + -export default CancelFulfillment -``` + ```tsx + import { useAdminCancelClaimFulfillment } from "medusa-react" - - + const CancelFulfillment = () => { + const cancelFulfillment = useAdminCancelClaimFulfillment( + orderId + ) + // ... + + const handleCancel = () => { + cancelFulfillment.mutate({ + claim_id, + fulfillment_id, + }) + } + + // ... + } + + export default CancelFulfillment + ``` + + + -```ts -fetch(`/admin/orders/${orderId}/claims/${claimId}/fulfillments/${fulfillmentId}/cancel`, { - credentials: "include", - method: "POST", -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.claims) -}) -``` + ```ts + fetch(`/admin/orders/${orderId}/claims/${claimId}/fulfillments/${fulfillmentId}/cancel`, { + credentials: "include", + method: "POST", + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.claims) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/orders//claims//fulfillments//cancel' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X POST '/admin/orders//claims//fulfillments//cancel' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the order, claim, and fulfillment IDs to be passed as path parameters. @@ -595,60 +595,60 @@ You can’t cancel a claim that has been refunded. You must also cancel the clai You can cancel a claim by sending a request to the [Cancel Claim API Route](https://docs.medusajs.com/api/admin#orders_postordersclaimcancel): - + -```ts -medusa.admin.orders.cancelClaim(orderId, claimId) -.then(({ order }) => { - console.log(order.claims) -}) -``` + ```ts + medusa.admin.orders.cancelClaim(orderId, claimId) + .then(({ order }) => { + console.log(order.claims) + }) + ``` - - + + -```tsx -import { useAdminCancelClaim } from "medusa-react" + ```tsx + import { useAdminCancelClaim } from "medusa-react" -const CancelClaim = () => { - const cancelClaim = useAdminCancelClaim(orderId) - // ... + const CancelClaim = () => { + const cancelClaim = useAdminCancelClaim(orderId) + // ... - const handleCancel = () => { - cancelClaim.mutate(claimId) - } + const handleCancel = () => { + cancelClaim.mutate(claimId) + } - // ... -} + // ... + } -export default CancelClaim -``` + export default CancelClaim + ``` - - + + -```ts -fetch(`/admin/orders/${orderId}/claims/${claimId}/cancel`, { - credentials: "include", - method: "POST", -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.claims) -}) -``` + ```ts + fetch(`/admin/orders/${orderId}/claims/${claimId}/cancel`, { + credentials: "include", + method: "POST", + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.claims) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/orders//claims//cancel' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X POST '/admin/orders//claims//cancel' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the order and claim IDs as path parameters. diff --git a/www/apps/docs/content/modules/orders/admin/manage-draft-orders.mdx b/www/apps/docs/content/modules/orders/admin/manage-draft-orders.mdx index 030953b5ee..07f8c3bc2c 100644 --- a/www/apps/docs/content/modules/orders/admin/manage-draft-orders.mdx +++ b/www/apps/docs/content/modules/orders/admin/manage-draft-orders.mdx @@ -55,66 +55,66 @@ You can learn more about [authenticating as an admin user in the API reference]( You can list draft orders by sending a request to the [List Draft Orders API Route](https://docs.medusajs.com/api/admin#draft-orders_getdraftorders): - + -```ts -medusa.admin.draftOrders.list() -.then(({ draft_orders, limit, offset, count }) => { - console.log(draft_orders.length) -}) -``` + ```ts + medusa.admin.draftOrders.list() + .then(({ draft_orders, limit, offset, count }) => { + console.log(draft_orders.length) + }) + ``` - - + + -```tsx -import { useAdminDraftOrders } from "medusa-react" + ```tsx + import { useAdminDraftOrders } from "medusa-react" -const DraftOrders = () => { - const { draft_orders, isLoading } = useAdminDraftOrders() + const DraftOrders = () => { + const { draft_orders, isLoading } = useAdminDraftOrders() - return ( -
- {isLoading && Loading...} - {draft_orders && !draft_orders.length && ( - No Draft Orders - )} - {draft_orders && draft_orders.length > 0 && ( -
    - {draft_orders.map((order) => ( -
  • {order.display_id}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {draft_orders && !draft_orders.length && ( + No Draft Orders + )} + {draft_orders && draft_orders.length > 0 && ( +
    + {draft_orders.map((order) => ( +
  • {order.display_id}
  • + ))} +
+ )} +
+ ) + } -export default DraftOrders -``` + export default DraftOrders + ``` -
- + + -```ts -fetch(`/admin/draft-orders`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ draft_orders, limit, offset, count }) => { - console.log(draft_orders.length) -}) -``` + ```ts + fetch(`/admin/draft-orders`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ draft_orders, limit, offset, count }) => { + console.log(draft_orders.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/draft-orders' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/draft-orders' \ + -H 'Authorization: Bearer ' + ``` - +
This API Route doesn't require any path or query parameters. You can pass search or pagination query parameters as explained in the [API reference](https://docs.medusajs.com/api/admin#draft-orders_getdraftorders). @@ -128,50 +128,10 @@ The request returns an array of draft order objects along with [pagination param You can create a draft order by sending a request to the [Create Draft Order API Route](https://docs.medusajs.com/api/admin#draft-orders_postdraftorders): - + -```ts -medusa.admin.draftOrders.create({ - email, - region_id, - items: [ - { - // defined product - quantity: 1, - variant_id, - }, - { - // custom product - quantity: 1, - unit_price: 1000, - title: "Custom Product", - }, - ], - shipping_methods: [ - { - option_id, - // for custom shipping price - price, - }, - ], -}) -.then(({ draft_order }) => { - console.log(draft_order.id) -}) -``` - - - - -```tsx -import { useAdminCreateDraftOrder } from "medusa-react" - -const CreateDraftOrder = () => { - const createDraftOrder = useAdminCreateDraftOrder() - // ... - - const handleCreate = () => { - createDraftOrder.mutate({ + ```ts + medusa.admin.draftOrders.create({ email, region_id, items: [ @@ -195,86 +155,126 @@ const CreateDraftOrder = () => { }, ], }) - } + .then(({ draft_order }) => { + console.log(draft_order.id) + }) + ``` - // ... -} + + -export default CreateDraftOrder -``` + ```tsx + import { useAdminCreateDraftOrder } from "medusa-react" - - + const CreateDraftOrder = () => { + const createDraftOrder = useAdminCreateDraftOrder() + // ... -```ts -fetch(`/admin/draft-orders`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email, - region_id, - items: [ - { - // defined product - quantity: 1, - variant_id, - }, - { - // custom product - quantity: 1, - unit_price: 1000, - title: "Custom Product", - }, - ], - shipping_methods: [ - { - option_id, - // for custom shipping price - price, - }, - ], - }), -}) -.then((response) => response.json()) -.then(({ draft_order }) => { - console.log(draft_order.id) -}) -``` + const handleCreate = () => { + createDraftOrder.mutate({ + email, + region_id, + items: [ + { + // defined product + quantity: 1, + variant_id, + }, + { + // custom product + quantity: 1, + unit_price: 1000, + title: "Custom Product", + }, + ], + shipping_methods: [ + { + option_id, + // for custom shipping price + price, + }, + ], + }) + } - - - -```bash -curl -L -X POST '/admin/draft-orders' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "email": "", - "region_id": "", - "items": [ - { - "quantity": 1, - "variant_id": "" - }, - { - "quantity": 1, - "unit_price": 1000, - "title": "Custom Product" + // ... } - ], - "shipping_methods": [ - { - "option_id": "", - "price": 1000 - } - ] -}' -``` - + export default CreateDraftOrder + ``` + + + + + ```ts + fetch(`/admin/draft-orders`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + email, + region_id, + items: [ + { + // defined product + quantity: 1, + variant_id, + }, + { + // custom product + quantity: 1, + unit_price: 1000, + title: "Custom Product", + }, + ], + shipping_methods: [ + { + option_id, + // for custom shipping price + price, + }, + ], + }), + }) + .then((response) => response.json()) + .then(({ draft_order }) => { + console.log(draft_order.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/draft-orders' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "email": "", + "region_id": "", + "items": [ + { + "quantity": 1, + "variant_id": "" + }, + { + "quantity": 1, + "unit_price": 1000, + "title": "Custom Product" + } + ], + "shipping_methods": [ + { + "option_id": "", + "price": 1000 + } + ] + }' + ``` + + This API Route requires the following request body parameters: @@ -301,61 +301,61 @@ The request returns the created draft order as an object. You can retrieve a draft order by sending a request to the [Get Draft Order API Route](https://docs.medusajs.com/api/admin#draft-orders_getdraftordersdraftorder): - + -```ts -medusa.admin.draftOrders.retrieve(draftOrderId) -.then(({ draft_order }) => { - console.log(draft_order.id) -}) -``` + ```ts + medusa.admin.draftOrders.retrieve(draftOrderId) + .then(({ draft_order }) => { + console.log(draft_order.id) + }) + ``` - - + + -```tsx -import { useAdminDraftOrder } from "medusa-react" + ```tsx + import { useAdminDraftOrder } from "medusa-react" -const DraftOrder = () => { - const { - draft_order, - isLoading, - } = useAdminDraftOrder(draftOrderId) - - return ( -
- {isLoading && Loading...} - {draft_order && {draft_order.display_id}} - -
- ) -} + const DraftOrder = () => { + const { + draft_order, + isLoading, + } = useAdminDraftOrder(draftOrderId) + + return ( +
+ {isLoading && Loading...} + {draft_order && {draft_order.display_id}} + +
+ ) + } -export default DraftOrder -``` + export default DraftOrder + ``` -
- + + -```ts -fetch(`/admin/draft-orders/${draftOrderId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ draft_order }) => { - console.log(draft_order.id) -}) -``` + ```ts + fetch(`/admin/draft-orders/${draftOrderId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ draft_order }) => { + console.log(draft_order.id) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/draft-orders/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/draft-orders/' \ + -H 'Authorization: Bearer ' + ``` - +
This API Route requires the draft order’s ID as a path parameter. @@ -369,74 +369,74 @@ The request returns the draft order as an object. You can update a draft order by sending a request to the [Update Draft Order API Route](https://docs.medusajs.com/api/admin#draft-orders_postdraftordersdraftorder): - + -```ts -medusa.admin.draftOrders.update(draftOrderId, { - email: "user@example.com", -}) -.then(({ draft_order }) => { - console.log(draft_order.id) -}) -``` - - - - -```tsx -import { useAdminUpdateDraftOrder } from "medusa-react" - -const UpdateDraftOrder = () => { - const updateDraftOrder = useAdminUpdateDraftOrder( - draftOrderId - ) - // ... - - const handleUpdate = () => { - updateDraftOrder.mutate({ + ```ts + medusa.admin.draftOrders.update(draftOrderId, { email: "user@example.com", }) - } + .then(({ draft_order }) => { + console.log(draft_order.id) + }) + ``` - // ... -} + + -export default UpdateDraftOrder -``` + ```tsx + import { useAdminUpdateDraftOrder } from "medusa-react" - - + const UpdateDraftOrder = () => { + const updateDraftOrder = useAdminUpdateDraftOrder( + draftOrderId + ) + // ... -```ts -fetch(`/admin/draft-orders/${draftOrderId}`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email: "user@example.com", - }), -}) -.then((response) => response.json()) -.then(({ draft_order }) => { - console.log(draft_order.id) -}) -``` + const handleUpdate = () => { + updateDraftOrder.mutate({ + email: "user@example.com", + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/draft-orders/' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "email": "user@example.com" -}' -``` + export default UpdateDraftOrder + ``` - + + + + ```ts + fetch(`/admin/draft-orders/${draftOrderId}`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + email: "user@example.com", + }), + }) + .then((response) => response.json()) + .then(({ draft_order }) => { + console.log(draft_order.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/draft-orders/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "email": "user@example.com" + }' + ``` + + This API Route requires the draft order’s ID as a path parameter. @@ -454,76 +454,76 @@ The request returns the updated draft order as an object. You can add line items to a draft order by sending a request to the [Create Line Items API Route](https://docs.medusajs.com/api/admin#draft-orders_postdraftordersdraftorderlineitems): - + -```ts -medusa.admin.draftOrders.addLineItem(draftOrderId, { - quantity: 1, -}) -.then(({ draft_order }) => { - console.log(draft_order.cart.items) -}) -``` - - - - -```tsx -import { useAdminDraftOrderAddLineItem } from "medusa-react" - -const AddLineItem = () => { - const addLineItem = useAdminDraftOrderAddLineItem( - draftOrderId - ) - // ... - - const handleAdd = () => { - addLineItem.mutate({ + ```ts + medusa.admin.draftOrders.addLineItem(draftOrderId, { quantity: 1, }) - } + .then(({ draft_order }) => { + console.log(draft_order.cart.items) + }) + ``` - // ... -} + + -export default AddLineItem -``` + ```tsx + import { useAdminDraftOrderAddLineItem } from "medusa-react" - - + const AddLineItem = () => { + const addLineItem = useAdminDraftOrderAddLineItem( + draftOrderId + ) + // ... + + const handleAdd = () => { + addLineItem.mutate({ + quantity: 1, + }) + } + + // ... + } + + export default AddLineItem + ``` + + + -```ts -fetch(`/admin/draft-orders/${draftOrderId}/line-items`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - quantity: 1, - }), - }) - .then((response) => response.json()) - .then(({ draft_order }) => { - console.log(draft_order.cart.items) - }) -``` + ```ts + fetch(`/admin/draft-orders/${draftOrderId}/line-items`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + quantity: 1, + }), + }) + .then((response) => response.json()) + .then(({ draft_order }) => { + console.log(draft_order.cart.items) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/draft-orders//line-items' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "quantity": 1 -}' -``` + ```bash + curl -L -X POST '/admin/draft-orders//line-items' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "quantity": 1 + }' + ``` - + This API Route requires the ID of the draft order as a path parameter. @@ -544,77 +544,77 @@ The request returns the updated draft order as an object. You can access the dra You can update a line item by sending a request to the [Update Line Item API Route](https://docs.medusajs.com/api/admin#draft-orders_postdraftordersdraftorderlineitemsitem): - + -```ts -medusa.admin.draftOrders.updateLineItem(draftOrderId, itemId, { - quantity: 1, -}) -.then(({ draft_order }) => { - console.log(draft_order.cart.items) -}) -``` - - - - -```tsx -import { useAdminDraftOrderUpdateLineItem } from "medusa-react" - -const UpdateLineItem = () => { - const updateLineItem = useAdminDraftOrderUpdateLineItem( - draftOrderId - ) - // ... - - const handleUpdate = () => { - updateLineItem.mutate({ - item_id, + ```ts + medusa.admin.draftOrders.updateLineItem(draftOrderId, itemId, { quantity: 1, }) - } + .then(({ draft_order }) => { + console.log(draft_order.cart.items) + }) + ``` - // ... -} + + -export default UpdateLineItem -``` + ```tsx + import { useAdminDraftOrderUpdateLineItem } from "medusa-react" - - + const UpdateLineItem = () => { + const updateLineItem = useAdminDraftOrderUpdateLineItem( + draftOrderId + ) + // ... + + const handleUpdate = () => { + updateLineItem.mutate({ + item_id, + quantity: 1, + }) + } + + // ... + } + + export default UpdateLineItem + ``` + + + -```ts -fetch(`/admin/draft-orders/${draftOrderId}/line-items/${itemId}`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - quantity: 1, - }), -}) -.then((response) => response.json()) -.then(({ draft_order }) => { - console.log(draft_order.cart.items) -}) -``` + ```ts + fetch(`/admin/draft-orders/${draftOrderId}/line-items/${itemId}`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + quantity: 1, + }), + }) + .then((response) => response.json()) + .then(({ draft_order }) => { + console.log(draft_order.cart.items) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/draft-orders//line-items/' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "quantity": 1 -}' -``` + ```bash + curl -L -X POST '/admin/draft-orders//line-items/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "quantity": 1 + }' + ``` - + This API Route requires the draft order and line item’s IDs as path parameters. @@ -628,62 +628,62 @@ The request returns the updated draft order as an object. You can access the dra You can delete a line item by sending a request to the [Delete Line Item API Route](https://docs.medusajs.com/api/admin#draft-orders_deletedraftordersdraftorderlineitemsitem): - + -```ts -medusa.admin.draftOrders.removeLineItem(draftOrderId, itemId) -.then(({ draft_order }) => { - console.log(draft_order.cart.items) -}) -``` + ```ts + medusa.admin.draftOrders.removeLineItem(draftOrderId, itemId) + .then(({ draft_order }) => { + console.log(draft_order.cart.items) + }) + ``` - - + + -```tsx -import { useAdminDraftOrderRemoveLineItem } from "medusa-react" + ```tsx + import { useAdminDraftOrderRemoveLineItem } from "medusa-react" -const DeleteLineItem = () => { - const deleteLineItem = useAdminDraftOrderRemoveLineItem( - draftOrderId - ) - // ... + const DeleteLineItem = () => { + const deleteLineItem = useAdminDraftOrderRemoveLineItem( + draftOrderId + ) + // ... - const handleDelete = () => { - deleteLineItem.mutate(itemId) - } + const handleDelete = () => { + deleteLineItem.mutate(itemId) + } - // ... -} + // ... + } -export default DeleteLineItem -``` + export default DeleteLineItem + ``` - - + + -```ts -fetch(`/admin/draft-orders/${draftOrderId}/line-items/${itemId}`, { - credentials: "include", - method: "DELETE", -}) -.then((response) => response.json()) -.then(({ draft_order }) => { - console.log(draft_order.cart.items) -}) -``` + ```ts + fetch(`/admin/draft-orders/${draftOrderId}/line-items/${itemId}`, { + credentials: "include", + method: "DELETE", + }) + .then((response) => response.json()) + .then(({ draft_order }) => { + console.log(draft_order.cart.items) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/draft-orders//line-items/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/draft-orders//line-items/' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the draft order and line item’s IDs as path parameters. @@ -699,60 +699,60 @@ Registering the draft order’s payment leads to authorizing and capturing the p You can register the draft order payment by sending a request to the [Register Draft Order Payment API Route](https://docs.medusajs.com/api/admin#draft-orders_postdraftordersdraftorderregisterpayment): - + -```ts -medusa.admin.draftOrders.markPaid(draftOrderId) -.then(({ order }) => { - console.log(order.id) -}) -``` + ```ts + medusa.admin.draftOrders.markPaid(draftOrderId) + .then(({ order }) => { + console.log(order.id) + }) + ``` - - + + -```tsx -import { useAdminDraftOrderRegisterPayment } from "medusa-react" + ```tsx + import { useAdminDraftOrderRegisterPayment } from "medusa-react" -const RegisterPayment = () => { - const registerPayment = useAdminDraftOrderRegisterPayment( - draftOrderId - ) - // ... + const RegisterPayment = () => { + const registerPayment = useAdminDraftOrderRegisterPayment( + draftOrderId + ) + // ... - const handlePayment = () => { - registerPayment.mutate() - } + const handlePayment = () => { + registerPayment.mutate() + } - // ... -} + // ... + } -export default RegisterPayment -``` + export default RegisterPayment + ``` - - + + -```ts -fetch(`/admin/draft-orders/${draftOrderId}/pay`, { - credentials: "include", - method: "POST", -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.id) -}) -``` + ```ts + fetch(`/admin/draft-orders/${draftOrderId}/pay`, { + credentials: "include", + method: "POST", + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.id) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/draft-orders//pay' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X POST '/admin/draft-orders//pay' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the draft order’s ID as a path parameter. @@ -766,60 +766,60 @@ The request returns the order created from the draft order as an object. You can delete a draft order by sending a request to the [Delete Draft Order API Route](https://docs.medusajs.com/api/admin#draft-orders_deletedraftordersdraftorder): - + -```ts -medusa.admin.draftOrders.delete(draftOrderId) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + medusa.admin.draftOrders.delete(draftOrderId) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```tsx -import { useAdminDeleteDraftOrder } from "medusa-react" + ```tsx + import { useAdminDeleteDraftOrder } from "medusa-react" -const DeleteDraftOrder = () => { - const deleteDraftOrder = useAdminDeleteDraftOrder( - draftOrderId - ) - // ... + const DeleteDraftOrder = () => { + const deleteDraftOrder = useAdminDeleteDraftOrder( + draftOrderId + ) + // ... - const handleDelete = () => { - deleteDraftOrder.mutate() - } + const handleDelete = () => { + deleteDraftOrder.mutate() + } - // ... -} + // ... + } -export default DeleteDraftOrder -``` + export default DeleteDraftOrder + ``` - - + + -```ts -fetch(`/admin/draft-orders/${draftOrderId}`, { - credentials: "include", - method: "DELETE", -}) -.then((response) => response.json()) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + fetch(`/admin/draft-orders/${draftOrderId}`, { + credentials: "include", + method: "DELETE", + }) + .then((response) => response.json()) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/draft-orders/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/draft-orders/' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the draft order’s ID as a path parameter. diff --git a/www/apps/docs/content/modules/orders/admin/manage-orders.mdx b/www/apps/docs/content/modules/orders/admin/manage-orders.mdx index 47a190904d..d269c4f974 100644 --- a/www/apps/docs/content/modules/orders/admin/manage-orders.mdx +++ b/www/apps/docs/content/modules/orders/admin/manage-orders.mdx @@ -63,64 +63,64 @@ You can learn more about [authenticating as an admin user in the API reference]( You can list orders by sending a request to the [List Orders API Route](https://docs.medusajs.com/api/admin#orders_getorders): - + -```ts -medusa.admin.orders.list() -.then(({ orders, limit, offset, count }) => { - console.log(orders.length) -}) -``` + ```ts + medusa.admin.orders.list() + .then(({ orders, limit, offset, count }) => { + console.log(orders.length) + }) + ``` - - + + -```tsx -import { useAdminOrders } from "medusa-react" + ```tsx + import { useAdminOrders } from "medusa-react" -const Orders = () => { - const { orders, isLoading } = useAdminOrders() + const Orders = () => { + const { orders, isLoading } = useAdminOrders() - return ( -
- {isLoading && Loading...} - {orders && !orders.length && No Orders} - {orders && orders.length > 0 && ( -
    - {orders.map((order) => ( -
  • {order.display_id}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {orders && !orders.length && No Orders} + {orders && orders.length > 0 && ( +
    + {orders.map((order) => ( +
  • {order.display_id}
  • + ))} +
+ )} +
+ ) + } -export default Orders -``` + export default Orders + ``` -
- + + -```ts -fetch(`/admin/orders`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ orders, limit, offset, count }) => { - console.log(orders.length) -}) -``` + ```ts + fetch(`/admin/orders`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ orders, limit, offset, count }) => { + console.log(orders.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/orders' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/orders' \ + -H 'Authorization: Bearer ' + ``` - +
This API Route doesn't require any path parameters. You can pass it query parameters to filter the orders received. @@ -134,76 +134,76 @@ This API Route accepts a variety of query parameters that allow you to filter or For example, you can filter the orders by one or more status: - + -```ts -medusa.admin.orders.list({ - status: ["completed"], - // the JS client requires these fields - // to be passed - offset, - limit, -}) -.then(({ orders, limit, offset, count }) => { - console.log(orders.length) -}) -``` + ```ts + medusa.admin.orders.list({ + status: ["completed"], + // the JS client requires these fields + // to be passed + offset, + limit, + }) + .then(({ orders, limit, offset, count }) => { + console.log(orders.length) + }) + ``` - - + + -```tsx -import { useAdminOrders } from "medusa-react" + ```tsx + import { useAdminOrders } from "medusa-react" -const Orders = () => { - const { orders, isLoading } = useAdminOrders({ - status: ["completed"], - // the JS client requires these fields - // to be passed - offset, - limit, - }) + const Orders = () => { + const { orders, isLoading } = useAdminOrders({ + status: ["completed"], + // the JS client requires these fields + // to be passed + offset, + limit, + }) - return ( -
- {isLoading && Loading...} - {orders && !orders.length && No Orders} - {orders && orders.length > 0 && ( -
    - {orders.map((order) => ( -
  • {order.display_id}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {orders && !orders.length && No Orders} + {orders && orders.length > 0 && ( +
    + {orders.map((order) => ( +
  • {order.display_id}
  • + ))} +
+ )} +
+ ) + } -export default Orders -``` + export default Orders + ``` -
- + + -```ts -fetch(`/admin/orders?status[]=completed`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ orders, limit, offset, count }) => { - console.log(orders.length) -}) -``` + ```ts + fetch(`/admin/orders?status[]=completed`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ orders, limit, offset, count }) => { + console.log(orders.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/orders?status[]=completed' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/orders?status[]=completed' \ + -H 'Authorization: Bearer ' + ``` - +
:::note @@ -215,165 +215,165 @@ You can check available order statuses [here](../../../references/entities/enums Another example is filtering the orders by a sales channel: - + -```ts -medusa.admin.orders.list({ - sales_channel_id: [ - salesChannelId, - ], - // the JS client requires these fields - // to be passed - offset, - limit, -}) -.then(({ orders, limit, offset, count }) => { - console.log(orders.length) -}) -``` + ```ts + medusa.admin.orders.list({ + sales_channel_id: [ + salesChannelId, + ], + // the JS client requires these fields + // to be passed + offset, + limit, + }) + .then(({ orders, limit, offset, count }) => { + console.log(orders.length) + }) + ``` - - + + -```tsx -import { useAdminOrders } from "medusa-react" + ```tsx + import { useAdminOrders } from "medusa-react" -const Orders = () => { - const { orders, isLoading } = useAdminOrders({ - sales_channel_id: [ - salesChannelId, - ], - // the JS client requires these fields - // to be passed - offset, - limit, - }) + const Orders = () => { + const { orders, isLoading } = useAdminOrders({ + sales_channel_id: [ + salesChannelId, + ], + // the JS client requires these fields + // to be passed + offset, + limit, + }) - return ( -
- {isLoading && Loading...} - {orders && !orders.length && No Orders} - {orders && orders.length > 0 && ( -
    - {orders.map((order) => ( -
  • {order.display_id}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {orders && !orders.length && No Orders} + {orders && orders.length > 0 && ( +
    + {orders.map((order) => ( +
  • {order.display_id}
  • + ))} +
+ )} +
+ ) + } -export default Orders -``` + export default Orders + ``` -
- + + -```ts -fetch(`/admin/orders?sales_channel_id[]=${salesChannelId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ orders, limit, offset, count }) => { - console.log(orders.length) -}) -``` + ```ts + fetch(`/admin/orders?sales_channel_id[]=${salesChannelId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ orders, limit, offset, count }) => { + console.log(orders.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/orders?sales_channel_id[]=' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/orders?sales_channel_id[]=' \ + -H 'Authorization: Bearer ' + ``` - +
You can also combine filters together: - + -```ts -medusa.admin.orders.list({ - status: ["completed"], - sales_channel_id: [ - salesChannelId, - ], - // the JS client requires these fields - // to be passed - offset, - limit, -}) -.then(({ orders, limit, offset, count }) => { - console.log(orders.length) -}) -``` + ```ts + medusa.admin.orders.list({ + status: ["completed"], + sales_channel_id: [ + salesChannelId, + ], + // the JS client requires these fields + // to be passed + offset, + limit, + }) + .then(({ orders, limit, offset, count }) => { + console.log(orders.length) + }) + ``` - - + + -```tsx -import { useAdminOrders } from "medusa-react" + ```tsx + import { useAdminOrders } from "medusa-react" -const Orders = () => { - const { orders, isLoading } = useAdminOrders({ - status: ["completed"], - sales_channel_id: [ - salesChannelId, - ], - // the JS client requires these fields - // to be passed - offset, - limit, - }) + const Orders = () => { + const { orders, isLoading } = useAdminOrders({ + status: ["completed"], + sales_channel_id: [ + salesChannelId, + ], + // the JS client requires these fields + // to be passed + offset, + limit, + }) - return ( -
- {isLoading && Loading...} - {orders && !orders.length && No Orders} - {orders && orders.length > 0 && ( -
    - {orders.map((order) => ( -
  • {order.display_id}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {orders && !orders.length && No Orders} + {orders && orders.length > 0 && ( +
    + {orders.map((order) => ( +
  • {order.display_id}
  • + ))} +
+ )} +
+ ) + } -export default Orders -``` + export default Orders + ``` -
- + + -```ts -fetch(`/admin/orders?status[]=completed&sales_channel_id[]=${salesChannelId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ orders, limit, offset, count }) => { - console.log(orders.length) -}) -``` + ```ts + fetch(`/admin/orders?status[]=completed&sales_channel_id[]=${salesChannelId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ orders, limit, offset, count }) => { + console.log(orders.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/orders?status[]=completed&sales_channel_id[]=' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/orders?status[]=completed&sales_channel_id[]=' \ + -H 'Authorization: Bearer ' + ``` - +
--- @@ -383,61 +383,61 @@ curl -L -X GET '/admin/orders?status[]=completed&sales_channel_id[] You can retrieve an order by sending a request to the [Get an Order API Route](https://docs.medusajs.com/api/admin#orders_getordersorder): - + -```ts -medusa.admin.orders.retrieve(orderId) -.then(({ order }) => { - console.log(order.id) -}) -``` + ```ts + medusa.admin.orders.retrieve(orderId) + .then(({ order }) => { + console.log(order.id) + }) + ``` - - + + -```tsx -import { useAdminOrder } from "medusa-react" + ```tsx + import { useAdminOrder } from "medusa-react" -const Order = () => { - const { - order, - isLoading, - } = useAdminOrder(orderId) - - return ( -
- {isLoading && Loading...} - {order && {order.display_id}} - -
- ) -} + const Order = () => { + const { + order, + isLoading, + } = useAdminOrder(orderId) + + return ( +
+ {isLoading && Loading...} + {order && {order.display_id}} + +
+ ) + } -export default Order -``` + export default Order + ``` -
- + + -```ts -fetch(`/admin/orders/${orderId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.id) -}) -``` + ```ts + fetch(`/admin/orders/${orderId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.id) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/orders/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/orders/' \ + -H 'Authorization: Bearer ' + ``` - +
This API Route requires the order ID to be passed as a path parameter. @@ -464,74 +464,74 @@ Updating an order’s details can include updating its: You can update any of the above details of an order by sending a request to the [Update an Order API Route](https://docs.medusajs.com/api/admin#orders_postordersorder): - + -```ts -medusa.admin.orders.update(orderId, { - email, -}) -.then(({ order }) => { - console.log(order.id) -}) -``` - - - - -```tsx -import { useAdminUpdateOrder } from "medusa-react" - -const UpdateOrder = () => { - const updateOrder = useAdminUpdateOrder( - orderId - ) - // ... - - const handleUpdate = () => { - updateOrder.mutate({ + ```ts + medusa.admin.orders.update(orderId, { email, }) - } + .then(({ order }) => { + console.log(order.id) + }) + ``` - // ... -} + + -export default UpdateOrder -``` + ```tsx + import { useAdminUpdateOrder } from "medusa-react" - - + const UpdateOrder = () => { + const updateOrder = useAdminUpdateOrder( + orderId + ) + // ... -```ts -fetch(`/admin/orders/${orderId}`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email, - }), -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.id) -}) -``` + const handleUpdate = () => { + updateOrder.mutate({ + email, + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/orders/' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "email": "user@example.com" -}' -``` + export default UpdateOrder + ``` - + + + + ```ts + fetch(`/admin/orders/${orderId}`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + email, + }), + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/orders/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "email": "user@example.com" + }' + ``` + + This API Route requires the order’s ID to be passed as a path parameter. @@ -549,61 +549,60 @@ The request returns the updated order as an object. You can capture an order’s payment by sending a request to the [Capture Order’s Payment API Route](https://docs.medusajs.com/api/admin#orders_postordersordercapture): - + -```ts -medusa.admin.orders.capturePayment(orderId) -.then(({ order }) => { - console.log(order.payment_status) -}) -``` + ```ts + medusa.admin.orders.capturePayment(orderId) + .then(({ order }) => { + console.log(order.payment_status) + }) + ``` - - + + -```tsx -import { useAdminCapturePayment } from "medusa-react" + ```tsx + import { useAdminCapturePayment } from "medusa-react" -const CapturePayment = () => { - const capturePayment = useAdminCapturePayment( - orderId - ) - // ... + const CapturePayment = () => { + const capturePayment = useAdminCapturePayment( + orderId + ) + // ... - const handleCapture = () => { - capturePayment.mutate() - } + const handleCapture = () => { + capturePayment.mutate() + } - // ... -} + // ... + } -export default CapturePayment -``` + export default CapturePayment + ``` + + - - + ```ts + fetch(`/admin/orders/${orderId}/capture`, { + credentials: "include", + method: "POST", + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.payment_status) + }) + ``` -```ts -fetch(`/admin/orders/${orderId}/capture`, { - credentials: "include", - method: "POST", -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.payment_status) -}) -``` + + - - + ```bash + curl -L -X POST '/admin/orders//capture' \ + -H 'Authorization: Bearer ' + ``` -```bash -curl -L -X POST '/admin/orders//capture' \ --H 'Authorization: Bearer ' -``` - - + This API Route requires the Order ID as a path parameter. @@ -617,78 +616,78 @@ You can refund an amount that is less than `order.refundable_amount`. To refund payment, send a request to the [Refund Payment API Route](https://docs.medusajs.com/api/admin#orders_postordersorderrefunds): - + -```ts -medusa.admin.orders.refundPayment(orderId, { - amount, - reason, -}) -.then(({ order }) => { - console.log(order.payment_status, order.refunded_total) -}) -``` - - - - -```tsx -import { useAdminRefundPayment } from "medusa-react" - -const RefundPayment = () => { - const refundPayment = useAdminRefundPayment( - orderId - ) - // ... - - const handleRefund = () => { - refundPayment.mutate({ + ```ts + medusa.admin.orders.refundPayment(orderId, { amount, reason, }) - } + .then(({ order }) => { + console.log(order.payment_status, order.refunded_total) + }) + ``` - // ... -} + + -export default RefundPayment -``` + ```tsx + import { useAdminRefundPayment } from "medusa-react" - - + const RefundPayment = () => { + const refundPayment = useAdminRefundPayment( + orderId + ) + // ... -```ts -fetch(`/admin/orders/${orderId}/refund`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - amount, - reason, - }), -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.payment_status, order.refunded_total) -}) -``` + const handleRefund = () => { + refundPayment.mutate({ + amount, + reason, + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/orders//refund' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "amount": 1000, - "reason": "customer did not like the order" -}' -``` + export default RefundPayment + ``` - + + + + ```ts + fetch(`/admin/orders/${orderId}/refund`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + amount, + reason, + }), + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.payment_status, order.refunded_total) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/orders//refund' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "amount": 1000, + "reason": "customer did not like the order" + }' + ``` + + This API Route requires the order’s ID to be passed as a path parameter. @@ -711,36 +710,10 @@ The request returns the updated order as an object. You can create a fulfillment by sending a request to the [Create a Fulfillment API Route](https://docs.medusajs.com/api/admin#orders_postordersorderfulfillments): - + -```ts -medusa.admin.orders.createFulfillment(orderId, { - items: [ - { - itemId, - quantity, - }, - ], -}) -.then(({ order }) => { - console.log(order.fulfillment_status, order.fulfillments) -}) -``` - - - - -```tsx -import { useAdminCreateFulfillment } from "medusa-react" - -const CreateFuilfillment = () => { - const createFulfillment = useAdminCreateFulfillment( - orderId - ) - // ... - - const handleCreate = () => { - createFulfillment.mutate({ + ```ts + medusa.admin.orders.createFulfillment(orderId, { items: [ { itemId, @@ -748,57 +721,83 @@ const CreateFuilfillment = () => { }, ], }) - } + .then(({ order }) => { + console.log(order.fulfillment_status, order.fulfillments) + }) + ``` - // ... -} + + -export default CreateFuilfillment -``` + ```tsx + import { useAdminCreateFulfillment } from "medusa-react" - - + const CreateFuilfillment = () => { + const createFulfillment = useAdminCreateFulfillment( + orderId + ) + // ... -```ts -fetch(`/admin/orders/${orderId}/fulfillment`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - items: [ - { - itemId, - quantity, - }, - ], - }), -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.fulfillment_status, order.fulfillments) -}) -``` - - - - -```bash -curl -L -X POST '/admin/orders//fulfillment' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "items": [ - { - "item_id": "", - "quantity": 1 + const handleCreate = () => { + createFulfillment.mutate({ + items: [ + { + itemId, + quantity, + }, + ], + }) } - ] -}' -``` - + // ... + } + + export default CreateFuilfillment + ``` + + + + + ```ts + fetch(`/admin/orders/${orderId}/fulfillment`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + items: [ + { + itemId, + quantity, + }, + ], + }), + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.fulfillment_status, order.fulfillments) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/orders//fulfillment' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "items": [ + { + "item_id": "", + "quantity": 1 + } + ] + }' + ``` + + This API Route requires the order’s ID to be passed as a path parameter. @@ -819,74 +818,74 @@ The request returns the updated order as an object. You can create a shipment for a fulfillment by sending a request to the [Create Shipment API Route](https://docs.medusajs.com/api/admin#orders_postordersordershipment): - + -```ts -medusa.admin.orders.createShipment(orderId, { - fulfillment_id, -}) -.then(({ order }) => { - console.log(order.fulfillment_status, order.fulfillments) -}) -``` - - - - -```tsx -import { useAdminCreateShipment } from "medusa-react" - -const CreateShipment = () => { - const createShipment = useAdminCreateShipment( - orderId - ) - // ... - - const handleCreate = () => { - createShipment.mutate({ + ```ts + medusa.admin.orders.createShipment(orderId, { fulfillment_id, }) - } + .then(({ order }) => { + console.log(order.fulfillment_status, order.fulfillments) + }) + ``` - // ... -} + + -export default CreateShipment -``` + ```tsx + import { useAdminCreateShipment } from "medusa-react" - - + const CreateShipment = () => { + const createShipment = useAdminCreateShipment( + orderId + ) + // ... -```ts -fetch(`/admin/orders/${orderId}/shipment`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - fulfillment_id, - }), -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.fulfillment_status, order.fulfillments) -}) -``` + const handleCreate = () => { + createShipment.mutate({ + fulfillment_id, + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/orders//shipment' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "fulfillment_id": "" -}' -``` + export default CreateShipment + ``` - + + + + ```ts + fetch(`/admin/orders/${orderId}/shipment`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + fulfillment_id, + }), + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.fulfillment_status, order.fulfillments) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/orders//shipment' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "fulfillment_id": "" + }' + ``` + + This API Route requires passing the order’s ID as a path parameter. @@ -900,62 +899,62 @@ The request returns the updated order as an object. You can cancel a fulfillment by sending a request to the [Cancel Fulfillment API Route](https://docs.medusajs.com/api/admin#orders_postordersorderfulfillmentscancel): - + -```ts -medusa.admin.orders.cancelFulfillment(orderId, fulfillmentId) -.then(({ order }) => { - console.log(order.fulfillment_status) -}) -``` + ```ts + medusa.admin.orders.cancelFulfillment(orderId, fulfillmentId) + .then(({ order }) => { + console.log(order.fulfillment_status) + }) + ``` - - + + -```tsx -import { useAdminCancelFulfillment } from "medusa-react" + ```tsx + import { useAdminCancelFulfillment } from "medusa-react" -const CancelFulfillment = () => { - const cancelFulfillment = useAdminCancelFulfillment( - orderId - ) - // ... + const CancelFulfillment = () => { + const cancelFulfillment = useAdminCancelFulfillment( + orderId + ) + // ... - const handleCancel = () => { - cancelFulfillment.mutate(fulfillment_id) - } + const handleCancel = () => { + cancelFulfillment.mutate(fulfillment_id) + } - // ... -} + // ... + } -export default CancelFulfillment -``` + export default CancelFulfillment + ``` - - + + -```ts -fetch(`/admin/orders/${orderId}/fulfillments/${fulfillmentId}/cancel`, { - credentials: "include", - method: "POST", -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.id) -}) -``` + ```ts + fetch(`/admin/orders/${orderId}/fulfillments/${fulfillmentId}/cancel`, { + credentials: "include", + method: "POST", + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.id) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/orders//fulfillments//cancel' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X POST '/admin/orders//fulfillments//cancel' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires passing the order’s ID and fulfillment ID as path parameters. @@ -969,60 +968,60 @@ The request returns the updated order as an object. You can mark an order completed, changing its status, by sending a request to the [Complete an Order API Route](https://docs.medusajs.com/api/admin#orders_postordersordercomplete): - + -```ts -medusa.admin.orders.complete(orderId) -.then(({ order }) => { - console.log(order.status) -}) -``` + ```ts + medusa.admin.orders.complete(orderId) + .then(({ order }) => { + console.log(order.status) + }) + ``` - - + + -```tsx -import { useAdminCompleteOrder } from "medusa-react" + ```tsx + import { useAdminCompleteOrder } from "medusa-react" -const CompleteOrder = () => { - const completeOrder = useAdminCompleteOrder( - orderId - ) - // ... + const CompleteOrder = () => { + const completeOrder = useAdminCompleteOrder( + orderId + ) + // ... - const handleComplete = () => { - completeOrder.mutate() - } + const handleComplete = () => { + completeOrder.mutate() + } - // ... -} + // ... + } -export default CompleteOrder -``` + export default CompleteOrder + ``` - - + + -```ts -fetch(`/admin/orders/${orderId}/complete`, { - credentials: "include", - method: "POST", -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.status) -}) -``` + ```ts + fetch(`/admin/orders/${orderId}/complete`, { + credentials: "include", + method: "POST", + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.status) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/orders//complete' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X POST '/admin/orders//complete' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the order ID to be passed as a path parameter. @@ -1036,60 +1035,60 @@ The request returns the updated order as an object. You can cancel an order by sending a request to the [Cancel Order API Route](https://docs.medusajs.com/api/admin#orders_postordersordercancel): - + -```ts -medusa.admin.orders.cancel(orderId) -.then(({ order }) => { - console.log(order.status) -}) -``` + ```ts + medusa.admin.orders.cancel(orderId) + .then(({ order }) => { + console.log(order.status) + }) + ``` - - + + -```tsx -import { useAdminCancelOrder } from "medusa-react" + ```tsx + import { useAdminCancelOrder } from "medusa-react" -const CancelOrder = () => { - const cancelOrder = useAdminCancelOrder( - orderId - ) - // ... + const CancelOrder = () => { + const cancelOrder = useAdminCancelOrder( + orderId + ) + // ... - const handleCancel = () => { - cancelOrder.mutate() - } + const handleCancel = () => { + cancelOrder.mutate() + } - // ... -} + // ... + } -export default CancelOrder -``` + export default CancelOrder + ``` - - + + -```ts -fetch(`/admin/orders/${orderId}/cancel`, { - credentials: "include", - method: "POST", -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.status) -}) -``` + ```ts + fetch(`/admin/orders/${orderId}/cancel`, { + credentials: "include", + method: "POST", + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.status) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/orders//cancel' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X POST '/admin/orders//cancel' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the order ID to be passed as a path parameter. @@ -1103,60 +1102,60 @@ The request returns the updated order as an object. You can archive an order by sending a request to the [Archive Order API Route](https://docs.medusajs.com/api/admin#orders_postordersorderarchive): - + -```ts -medusa.admin.orders.archive(orderId) -.then(({ order }) => { - console.log(order.status) -}) -``` + ```ts + medusa.admin.orders.archive(orderId) + .then(({ order }) => { + console.log(order.status) + }) + ``` - - + + -```tsx -import { useAdminArchiveOrder } from "medusa-react" + ```tsx + import { useAdminArchiveOrder } from "medusa-react" -const ArchiveOrder = () => { - const archiveOrder = useAdminArchiveOrder( - orderId - ) - // ... + const ArchiveOrder = () => { + const archiveOrder = useAdminArchiveOrder( + orderId + ) + // ... - const handleArchive = () => { - archiveOrder.mutate() - } + const handleArchive = () => { + archiveOrder.mutate() + } - // ... -} + // ... + } -export default ArchiveOrder -``` + export default ArchiveOrder + ``` - - + + -```ts -fetch(`/admin/orders/${orderId}/archive`, { - credentials: "include", - method: "POST", -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.status) -}) -``` + ```ts + fetch(`/admin/orders/${orderId}/archive`, { + credentials: "include", + method: "POST", + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.status) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/orders//archive' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X POST '/admin/orders//archive' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the order ID to be passed as a path parameter. diff --git a/www/apps/docs/content/modules/orders/admin/manage-returns.mdx b/www/apps/docs/content/modules/orders/admin/manage-returns.mdx index b723f4017c..9c9e140740 100644 --- a/www/apps/docs/content/modules/orders/admin/manage-returns.mdx +++ b/www/apps/docs/content/modules/orders/admin/manage-returns.mdx @@ -60,68 +60,68 @@ Return reasons allow you to specify why an item is returned. They are especially You can list available return reasons using the [List Return Reasons API Route](https://docs.medusajs.com/api/admin#return-reasons_getreturnreasons): - + -```ts -medusa.admin.returnReasons.list() -.then(({ return_reasons }) => { - console.log(return_reasons.length) -}) -``` + ```ts + medusa.admin.returnReasons.list() + .then(({ return_reasons }) => { + console.log(return_reasons.length) + }) + ``` - - + + -```tsx -import { useAdminReturnReasons } from "medusa-react" + ```tsx + import { useAdminReturnReasons } from "medusa-react" -const ReturnReasons = () => { - const { return_reasons, isLoading } = useAdminReturnReasons() + const ReturnReasons = () => { + const { return_reasons, isLoading } = useAdminReturnReasons() - return ( -
- {isLoading && Loading...} - {return_reasons && !return_reasons.length && ( - No Return Reasons - )} - {return_reasons && return_reasons.length > 0 && ( -
    - {return_reasons.map((reason) => ( -
  • - {reason.label}: {reason.value} -
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {return_reasons && !return_reasons.length && ( + No Return Reasons + )} + {return_reasons && return_reasons.length > 0 && ( +
    + {return_reasons.map((reason) => ( +
  • + {reason.label}: {reason.value} +
  • + ))} +
+ )} +
+ ) + } -export default ReturnReasons -``` + export default ReturnReasons + ``` -
- + + -```ts -fetch(`/admin/return-reasons`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ return_reasons }) => { - console.log(return_reasons.length) -}) -``` + ```ts + fetch(`/admin/return-reasons`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ return_reasons }) => { + console.log(return_reasons.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/return-reasons' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/return-reasons' \ + -H 'Authorization: Bearer ' + ``` - +
This API Route doesn't require or accept any path or query parameters. @@ -133,76 +133,76 @@ The request returns an array of return reason objects. You can create a return reason using the [Create Return Reason API Route](https://docs.medusajs.com/api/admin#return-reasons_postreturnreasons): - + -```ts -medusa.admin.returnReasons.create({ - label: "Damaged", - value: "damaged", -}) -.then(({ return_reason }) => { - console.log(return_reason.id) -}) -``` - - - - -```tsx -import { useAdminCreateReturnReason } from "medusa-react" - -const CreateReturnReason = () => { - const createReturnReason = useAdminCreateReturnReason() - // ... - - const handleCreate = () => { - createReturnReason.mutate({ + ```ts + medusa.admin.returnReasons.create({ label: "Damaged", value: "damaged", }) - } + .then(({ return_reason }) => { + console.log(return_reason.id) + }) + ``` - // ... -} + + -export default CreateReturnReason -``` + ```tsx + import { useAdminCreateReturnReason } from "medusa-react" - - + const CreateReturnReason = () => { + const createReturnReason = useAdminCreateReturnReason() + // ... -```ts -fetch(`/admin/return-reasons`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - label: "Damaged", - value: "damaged", - }), -}) -.then((response) => response.json()) -.then(({ return_reason }) => { - console.log(return_reason.id) -}) -``` + const handleCreate = () => { + createReturnReason.mutate({ + label: "Damaged", + value: "damaged", + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/return-reasons' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "label": "Damaged", - "value": "damaged" -}' -``` + export default CreateReturnReason + ``` - + + + + ```ts + fetch(`/admin/return-reasons`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + label: "Damaged", + value: "damaged", + }), + }) + .then((response) => response.json()) + .then(({ return_reason }) => { + console.log(return_reason.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/return-reasons' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "label": "Damaged", + "value": "damaged" + }' + ``` + + This API Route requires the following request body parameters: @@ -219,74 +219,74 @@ This request returns the created return reason as an object. You can update a return reason by sending a request to the [Update Return Reason API Route](https://docs.medusajs.com/api/admin#return-reasons_postreturnreasonsreason): - + -```ts -medusa.admin.returnReasons.update(returnReasonId, { - label: "Damaged", -}) -.then(({ return_reason }) => { - console.log(return_reason.id) -}) -``` - - - - -```tsx -import { useAdminUpdateReturnReason } from "medusa-react" - -const UpdateReturnReason = () => { - const updateReturnReason = useAdminUpdateReturnReason( - returnReasonId - ) - // ... - - const handleUpdate = () => { - updateReturnReason.mutate({ + ```ts + medusa.admin.returnReasons.update(returnReasonId, { label: "Damaged", }) - } + .then(({ return_reason }) => { + console.log(return_reason.id) + }) + ``` - // ... -} + + -export default UpdateReturnReason -``` + ```tsx + import { useAdminUpdateReturnReason } from "medusa-react" - - + const UpdateReturnReason = () => { + const updateReturnReason = useAdminUpdateReturnReason( + returnReasonId + ) + // ... -```ts -fetch(`/admin/return-reasons/${returnReasonId}`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - label: "Damaged", - }), -}) -.then((response) => response.json()) -.then(({ return_reason }) => { - console.log(return_reason.id) -}) -``` + const handleUpdate = () => { + updateReturnReason.mutate({ + label: "Damaged", + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/return-reasons/' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "label": "Damaged" -}' -``` + export default UpdateReturnReason + ``` - + + + + ```ts + fetch(`/admin/return-reasons/${returnReasonId}`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + label: "Damaged", + }), + }) + .then((response) => response.json()) + .then(({ return_reason }) => { + console.log(return_reason.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/return-reasons/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "label": "Damaged" + }' + ``` + + This API Route requires the return reason ID to be passed as a path parameter. @@ -300,60 +300,60 @@ The request returns the updated return reason as an object. You can delete a return reason by sending a request to the [Delete Return Reason API Route](https://docs.medusajs.com/api/admin#return-reasons_deletereturnreason): - + -```ts -medusa.admin.returnReasons.delete(returnReasonId) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + medusa.admin.returnReasons.delete(returnReasonId) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```tsx -import { useAdminDeleteReturnReason } from "medusa-react" + ```tsx + import { useAdminDeleteReturnReason } from "medusa-react" -const DeleteReturnReason = () => { - const deleteReturnReason = useAdminDeleteReturnReason( - returnReasonId - ) - // ... + const DeleteReturnReason = () => { + const deleteReturnReason = useAdminDeleteReturnReason( + returnReasonId + ) + // ... - const handleDelete = () => { - deleteReturnReason.mutate() - } + const handleDelete = () => { + deleteReturnReason.mutate() + } - // ... -} + // ... + } -export default DeleteReturnReason -``` + export default DeleteReturnReason + ``` - - + + -```ts -fetch(`/admin/return-reasons/${returnReasonId}`, { - credentials: "include", - method: "DELETE", -}) -.then((response) => response.json()) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + fetch(`/admin/return-reasons/${returnReasonId}`, { + credentials: "include", + method: "DELETE", + }) + .then((response) => response.json()) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/return-reasons/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/return-reasons/' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the return reason ID as a path parameter. @@ -377,72 +377,72 @@ You can view all returns in your commerce system, regardless of which order they When you retrieve an order using the [Get Order API Route](https://docs.medusajs.com/api/admin#orders_getordersorder), you can access the returns within the order object: - + -```ts -medusa.admin.orders.retrieve(orderId) -.then(({ order }) => { - console.log(order.returns) -}) -``` + ```ts + medusa.admin.orders.retrieve(orderId) + .then(({ order }) => { + console.log(order.returns) + }) + ``` - - + + -```tsx -import { useAdminOrder } from "medusa-react" + ```tsx + import { useAdminOrder } from "medusa-react" -const Order = () => { - const { - order, - isLoading, - } = useAdminOrder(orderId) - - return ( -
- {isLoading && Loading...} - {order && ( - <> - {order.display_id} - {order.returns?.length > 0 && ( -
    - {order.returns.map((orderReturn) => ( -
  • {orderReturn.id}
  • - ))} -
+ const Order = () => { + const { + order, + isLoading, + } = useAdminOrder(orderId) + + return ( +
+ {isLoading && Loading...} + {order && ( + <> + {order.display_id} + {order.returns?.length > 0 && ( +
    + {order.returns.map((orderReturn) => ( +
  • {orderReturn.id}
  • + ))} +
+ )} + )} - - )} - -
- ) -} + +
+ ) + } -export default Order -``` + export default Order + ``` -
- + + -```ts -fetch(`/admin/orders/${orderId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.returns) -}) -``` + ```ts + fetch(`/admin/orders/${orderId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.returns) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/orders/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/orders/' \ + -H 'Authorization: Bearer ' + ``` - +
This API Route requires the order ID as a path parameter. @@ -470,89 +470,89 @@ You can retrieve a claim using the Get Order API Route as explained [here](./man You can mark a return as received by sending a request to the [Receive a Return API Route](https://docs.medusajs.com/api/admin#returns_postreturnsreturnreceive): - + -```ts -medusa.admin.returns.receive(return_id, { - items: [ - { - item_id, - quantity: 1, - }, - ], -}) -.then((data) => { - console.log(data.return.id) -}) -``` - - - - -```tsx -import { useAdminReceiveReturn } from "medusa-react" - -const ReceiveReturn = () => { - const receiveReturn = useAdminReceiveReturn( - returnId - ) - // ... - - const handleReceive = () => { - receiveReturn.mutate({ - email, + ```ts + medusa.admin.returns.receive(return_id, { + items: [ + { + item_id, + quantity: 1, + }, + ], }) - } + .then((data) => { + console.log(data.return.id) + }) + ``` - // ... -} + + -export default ReceiveReturn -``` + ```tsx + import { useAdminReceiveReturn } from "medusa-react" - - + const ReceiveReturn = () => { + const receiveReturn = useAdminReceiveReturn( + returnId + ) + // ... -```ts -fetch(`/admin/returns/${returnId}/receive`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - items: [ - { - item_id, - quantity: 1, - }, - ], - }), -}) -.then((response) => response.json()) -.then((data) => { - console.log(data.return.id) -}) -``` - - - - -```bash -curl -L -X POST '/admin/returns//receive' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "items": [ - { - "item_id": "", - "quantity": 1 + const handleReceive = () => { + receiveReturn.mutate({ + email, + }) } - ] -}' -``` - + // ... + } + + export default ReceiveReturn + ``` + + + + + ```ts + fetch(`/admin/returns/${returnId}/receive`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + items: [ + { + item_id, + quantity: 1, + }, + ], + }), + }) + .then((response) => response.json()) + .then((data) => { + console.log(data.return.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/returns//receive' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "items": [ + { + "item_id": "", + "quantity": 1 + } + ] + }' + ``` + + This API Route requires the ID of the return as a path parameter. @@ -579,60 +579,60 @@ A received return can’t be canceled. You can cancel a return by sending a request to the [Cancel Return API Route](https://docs.medusajs.com/api/admin#returns_postreturnsreturncancel): - + -```ts -medusa.admin.returns.cancel(returnId) -.then(({ order }) => { - console.log(order.returns) -}) -``` + ```ts + medusa.admin.returns.cancel(returnId) + .then(({ order }) => { + console.log(order.returns) + }) + ``` - - + + -```tsx -import { useAdminCancelReturn } from "medusa-react" + ```tsx + import { useAdminCancelReturn } from "medusa-react" -const CancelReturn = () => { - const cancelReturn = useAdminCancelReturn( - returnId - ) - // ... + const CancelReturn = () => { + const cancelReturn = useAdminCancelReturn( + returnId + ) + // ... - const handleCancel = () => { - cancelReturn.mutate() - } + const handleCancel = () => { + cancelReturn.mutate() + } - // ... -} + // ... + } -export default CancelReturn -``` + export default CancelReturn + ``` - - + + -```ts -fetch(`/admin/returns/${returnId}/cancel`, { - credentials: "include", - method: "POST", -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.returns) -}) -``` + ```ts + fetch(`/admin/returns/${returnId}/cancel`, { + credentials: "include", + method: "POST", + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.returns) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/returns//cancel' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X POST '/admin/returns//cancel' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the return ID to be passed as a path parameter. diff --git a/www/apps/docs/content/modules/orders/admin/manage-swaps.mdx b/www/apps/docs/content/modules/orders/admin/manage-swaps.mdx index 3b884088f3..98afbdaab3 100644 --- a/www/apps/docs/content/modules/orders/admin/manage-swaps.mdx +++ b/www/apps/docs/content/modules/orders/admin/manage-swaps.mdx @@ -68,71 +68,71 @@ If you want to view all swaps in your system, and not swaps specific to an order You can view an order’s swaps by retrieving the order using the [Get Order API Route](https://docs.medusajs.com/api/admin#orders_getordersorder): - + -```ts -medusa.admin.orders.retrieve(orderId) -.then(({ order }) => { - console.log(order.swaps) -}) -``` + ```ts + medusa.admin.orders.retrieve(orderId) + .then(({ order }) => { + console.log(order.swaps) + }) + ``` - - + + -```tsx -import { useAdminOrder } from "medusa-react" + ```tsx + import { useAdminOrder } from "medusa-react" -const Order = () => { - const { - order, - isLoading, - } = useAdminOrder(orderId) - - return ( -
- {isLoading && Loading...} - {order && ( - <> - {order.display_id} - {order.swaps?.length > 0 && ( -
    - {order.swaps.map((swap) => ( -
  • {swap.difference_due}
  • - ))} -
+ const Order = () => { + const { + order, + isLoading, + } = useAdminOrder(orderId) + + return ( +
+ {isLoading && Loading...} + {order && ( + <> + {order.display_id} + {order.swaps?.length > 0 && ( +
    + {order.swaps.map((swap) => ( +
  • {swap.difference_due}
  • + ))} +
+ )} + )} - - )} -
- ) -} +
+ ) + } -export default Order -``` + export default Order + ``` -
- + + -```ts -fetch(`/admin/orders/${orderId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.swaps) -}) -``` + ```ts + fetch(`/admin/orders/${orderId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.swaps) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/orders/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/orders/' \ + -H 'Authorization: Bearer ' + ``` - +
This API Route requires the order ID to be passed as a path parameter. @@ -148,62 +148,62 @@ Processing a swap’s payment can mean either refunding or capturing payment, de Regardless of whether you need to refund or capture the payment, you can process the swap’s payment by sending a request to the [Process Swap Payment API Route](https://docs.medusajs.com/api/admin#orders_postordersorderswapsswapprocesspayment): - + -```ts -medusa.admin.orders.processSwapPayment(orderId, swapId) -.then(({ order }) => { - console.log(order.swaps) -}) -``` + ```ts + medusa.admin.orders.processSwapPayment(orderId, swapId) + .then(({ order }) => { + console.log(order.swaps) + }) + ``` - - + + -```tsx -import { useAdminProcessSwapPayment } from "medusa-react" + ```tsx + import { useAdminProcessSwapPayment } from "medusa-react" -const ProcessPayment = () => { - const processPayment = useAdminProcessSwapPayment( - orderId - ) - // ... + const ProcessPayment = () => { + const processPayment = useAdminProcessSwapPayment( + orderId + ) + // ... - const handleProcess = () => { - processPayment.mutate(swapId) - } + const handleProcess = () => { + processPayment.mutate(swapId) + } - // ... -} + // ... + } -export default ProcessPayment -``` + export default ProcessPayment + ``` - - + + -```ts -fetch(`/admin/orders/${orderId}/swaps/${swapId}/process-payment`, { - credentials: "include", - method: "POST", -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.swaps) -}) -``` + ```ts + fetch(`/admin/orders/${orderId}/swaps/${swapId}/process-payment`, { + credentials: "include", + method: "POST", + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.swaps) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/orders//swaps//process-payment' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X POST '/admin/orders//swaps//process-payment' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the order ID and the swap ID as path parameters. @@ -223,65 +223,65 @@ Fulfillments are available on a swap object under the `fulfillments` property, w You can create a fulfillment for a swap by sending a request to the [Create Swap Fulfillment API Route](https://docs.medusajs.com/api/admin#orders_postordersorderswapsswapfulfillments): - + -```ts -medusa.admin.orders.fulfillSwap(orderId, swapId, { -}) -.then(({ order }) => { - console.log(order.swaps) -}) -``` - - - - -```tsx -import { useAdminFulfillSwap } from "medusa-react" - -const FulfillSwap = () => { - const fulfillSwap = useAdminFulfillSwap( - orderId - ) - // ... - - const handleFulfill = () => { - fulfillSwap.mutate({ - swap_id: swapId, + ```ts + medusa.admin.orders.fulfillSwap(orderId, swapId, { }) - } + .then(({ order }) => { + console.log(order.swaps) + }) + ``` - // ... -} + + -export default FulfillSwap -``` + ```tsx + import { useAdminFulfillSwap } from "medusa-react" - - + const FulfillSwap = () => { + const fulfillSwap = useAdminFulfillSwap( + orderId + ) + // ... + + const handleFulfill = () => { + fulfillSwap.mutate({ + swap_id: swapId, + }) + } + + // ... + } + + export default FulfillSwap + ``` + + + -```ts -fetch(`/admin/orders/${orderId}/swaps/${swapId}/fulfillments`, { - credentials: "include", - method: "POST", -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.swaps) -}) -``` + ```ts + fetch(`/admin/orders/${orderId}/swaps/${swapId}/fulfillments`, { + credentials: "include", + method: "POST", + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.swaps) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/orders//swaps//fulfillments' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X POST '/admin/orders//swaps//fulfillments' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the order ID and swap ID as path parameters. @@ -295,77 +295,77 @@ The request returns the updated order as an object. You can access the order’s You can create a shipment for a swap’s fulfillment using the [Create Swap Shipment API Route](https://docs.medusajs.com/api/admin#orders_postordersorderswapsswapshipments): - + -```ts -medusa.admin.orders.createSwapShipment(orderId, swapId, { - fulfillment_id, -}) -.then(({ order }) => { - console.log(order.swaps) -}) -``` - - - - -```tsx -import { useAdminCreateSwapShipment } from "medusa-react" - -const CreateShipment = () => { - const createShipment = useAdminCreateSwapShipment( - orderId - ) - // ... - - const handleCreate = () => { - createShipment.mutate({ - swap_id, + ```ts + medusa.admin.orders.createSwapShipment(orderId, swapId, { fulfillment_id, }) - } + .then(({ order }) => { + console.log(order.swaps) + }) + ``` - // ... -} + + -export default CreateShipment -``` + ```tsx + import { useAdminCreateSwapShipment } from "medusa-react" - - + const CreateShipment = () => { + const createShipment = useAdminCreateSwapShipment( + orderId + ) + // ... + + const handleCreate = () => { + createShipment.mutate({ + swap_id, + fulfillment_id, + }) + } + + // ... + } + + export default CreateShipment + ``` + + + -```ts -fetch(`/admin/orders/${orderId}/swaps/${swapId}/shipments`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - fulfillment_id, - }), -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.swaps) -}) -``` + ```ts + fetch(`/admin/orders/${orderId}/swaps/${swapId}/shipments`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + fulfillment_id, + }), + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.swaps) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/orders//swaps//shipments' \ --H 'Authorization: Bearer '\ --H 'Content-Type: application/json' \ ---data-raw '{ - "fulfillment_id": "" -}' -``` + ```bash + curl -L -X POST '/admin/orders//swaps//shipments' \ + -H 'Authorization: Bearer '\ + -H 'Content-Type: application/json' \ + --data-raw '{ + "fulfillment_id": "" + }' + ``` - + This API Route expects the order and swap IDs to be passed as path parameters. @@ -389,69 +389,69 @@ You can’t cancel a fulfillment that has a shipment You can cancel a fulfillment by sending a request to the [Cancel Swap Fulfillment API Route](https://docs.medusajs.com/api/admin#orders_postordersswapfulfillmentscancel): - + -```ts -medusa.admin.orders.cancelSwapFulfillment( - orderId, - swapId, - fulfillmentId -) -.then(({ order }) => { - console.log(order.swaps) -}) -``` - - - - -```tsx -import { useAdminCancelSwapFulfillment } from "medusa-react" - -const CancelFulfillment = () => { - const cancelFulfillment = useAdminCancelSwapFulfillment( - orderId - ) - // ... - - const handleCancel = () => { - cancelFulfillment.mutate({ - swap_id, - fulfillment_id, + ```ts + medusa.admin.orders.cancelSwapFulfillment( + orderId, + swapId, + fulfillmentId + ) + .then(({ order }) => { + console.log(order.swaps) }) - } + ``` - // ... -} + + -export default CancelFulfillment -``` + ```tsx + import { useAdminCancelSwapFulfillment } from "medusa-react" - - + const CancelFulfillment = () => { + const cancelFulfillment = useAdminCancelSwapFulfillment( + orderId + ) + // ... + + const handleCancel = () => { + cancelFulfillment.mutate({ + swap_id, + fulfillment_id, + }) + } + + // ... + } + + export default CancelFulfillment + ``` + + + -```ts -fetch(`/admin/orders/${orderId}/swaps/${swapId}/shipments/${fulfillmentId}/cancel`, { - credentials: "include", - method: "POST", -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.swaps) -}) -``` + ```ts + fetch(`/admin/orders/${orderId}/swaps/${swapId}/shipments/${fulfillmentId}/cancel`, { + credentials: "include", + method: "POST", + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.swaps) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/orders//swaps//fulfillments//cancel' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X POST '/admin/orders//swaps//fulfillments//cancel' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the order, swap, and fulfillment IDs to be passed as path parameters. @@ -473,62 +473,62 @@ You can’t cancel a swap that has been refunded. You must also cancel all swap You can cancel a swap by sending a request to the [Cancel Swap API Route](https://docs.medusajs.com/api/admin#orders_postordersswapcancel): - + -```ts -medusa.admin.orders.cancelSwap(orderId, swapId) -.then(({ order }) => { - console.log(order.swaps) -}) -``` + ```ts + medusa.admin.orders.cancelSwap(orderId, swapId) + .then(({ order }) => { + console.log(order.swaps) + }) + ``` - - + + -```tsx -import { useAdminCancelSwap } from "medusa-react" + ```tsx + import { useAdminCancelSwap } from "medusa-react" -const CancelSwap = () => { - const cancelSwap = useAdminCancelSwap( - orderId - ) - // ... + const CancelSwap = () => { + const cancelSwap = useAdminCancelSwap( + orderId + ) + // ... - const handleCancel = () => { - cancelSwap.mutate(swapId) - } + const handleCancel = () => { + cancelSwap.mutate(swapId) + } - // ... -} + // ... + } -export default CancelSwap -``` + export default CancelSwap + ``` - - + + -```ts -fetch(`/admin/orders/${orderId}/swaps/${swapId}/cancel`, { - credentials: "include", - method: "POST", - }) - .then((response) => response.json()) - .then(({ order }) => { - console.log(order.swaps) - }) -``` + ```ts + fetch(`/admin/orders/${orderId}/swaps/${swapId}/cancel`, { + credentials: "include", + method: "POST", + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.swaps) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/orders//swaps//cancel' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X POST '/admin/orders//swaps//cancel' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the order and swap IDs as path parameters. diff --git a/www/apps/docs/content/modules/orders/storefront/create-return.mdx b/www/apps/docs/content/modules/orders/storefront/create-return.mdx index 594c75993c..c7e13b1a56 100644 --- a/www/apps/docs/content/modules/orders/storefront/create-return.mdx +++ b/www/apps/docs/content/modules/orders/storefront/create-return.mdx @@ -60,65 +60,65 @@ When a customer wants to create a return, they must choose the items they want t You can optionally allow customers to choose a return shipping option that they’ll use to return the items. To show the customers the available return shipping options, send a request to the Get [Shipping Options API Route](https://docs.medusajs.com/api/store#shipping-options_getshippingoptions): - + -```ts -medusa.shippingOptions.list({ - is_return: "true", -}) -.then(({ shipping_options }) => { - console.log(shipping_options.length) -}) -``` + ```ts + medusa.shippingOptions.list({ + is_return: "true", + }) + .then(({ shipping_options }) => { + console.log(shipping_options.length) + }) + ``` - - + + -```tsx -import { useShippingOptions } from "medusa-react" + ```tsx + import { useShippingOptions } from "medusa-react" -const ReturnShippingOptions = () => { - const { - shipping_options, - isLoading, - } = useShippingOptions({ - is_return: "true", - }) - - return ( -
- {isLoading && Loading...} - {shipping_options?.length && - shipping_options?.length > 0 && ( -
    - {shipping_options?.map((shipping_option) => ( -
  • - {shipping_option.id} -
  • - ))} -
- )} -
- ) -} + const ReturnShippingOptions = () => { + const { + shipping_options, + isLoading, + } = useShippingOptions({ + is_return: "true", + }) + + return ( +
+ {isLoading && Loading...} + {shipping_options?.length && + shipping_options?.length > 0 && ( +
    + {shipping_options?.map((shipping_option) => ( +
  • + {shipping_option.id} +
  • + ))} +
+ )} +
+ ) + } -export default ReturnShippingOptions -``` + export default ReturnShippingOptions + ``` -
- + + -```ts -fetch(`/store/shipping-options?is_return=true`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ shipping_options }) => { - console.log(shipping_options.length) -}) -``` + ```ts + fetch(`/store/shipping-options?is_return=true`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ shipping_options }) => { + console.log(shipping_options.length) + }) + ``` - +
This API Route allows you to pass the `is_return` query parameter to indicate whether the shipping options should be return shipping options. You can learn about other available filters in the [API reference](https://docs.medusajs.com/api/store#shipping-options_getshippingoptions). @@ -132,38 +132,10 @@ The request returns an array of shipping option objects. You can create the return by sending a request to the [Create Return API Route](https://docs.medusajs.com/api/store#returns_postreturns): - + -```ts -medusa.returns.create({ - order_id, - items: [ - { - item_id, - quantity: 1, - }, - ], - return_shipping: { - option_id, - }, -}) -.then((data) => { - console.log(data.return.id) -}) -``` - - - - -```tsx -import { useCreateReturn } from "medusa-react" - -const CreateReturn = () => { - const createReturn = useCreateReturn() - // ... - - const handleCreate = () => { - createReturn.mutate({ + ```ts + medusa.returns.create({ order_id, items: [ { @@ -175,44 +147,72 @@ const CreateReturn = () => { option_id, }, }) - } + .then((data) => { + console.log(data.return.id) + }) + ``` - // ... -} + + -export default CreateReturn -``` + ```tsx + import { useCreateReturn } from "medusa-react" - - + const CreateReturn = () => { + const createReturn = useCreateReturn() + // ... -```ts -fetch(`/store/returns`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - order_id, - items: [ - { - item_id, - quantity: 1, + const handleCreate = () => { + createReturn.mutate({ + order_id, + items: [ + { + item_id, + quantity: 1, + }, + ], + return_shipping: { + option_id, + }, + }) + } + + // ... + } + + export default CreateReturn + ``` + + + + + ```ts + fetch(`/store/returns`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", }, - ], - return_shipping: { - option_id, - }, - }), -}) -.then((response) => response.json()) -.then((data) => { - console.log(data.return.id) -}) -``` + body: JSON.stringify({ + order_id, + items: [ + { + item_id, + quantity: 1, + }, + ], + return_shipping: { + option_id, + }, + }), + }) + .then((response) => response.json()) + .then((data) => { + console.log(data.return.id) + }) + ``` - + This API Route requires the following request body parameters: diff --git a/www/apps/docs/content/modules/orders/storefront/create-swap.mdx b/www/apps/docs/content/modules/orders/storefront/create-swap.mdx index df3526650a..edba5dfe26 100644 --- a/www/apps/docs/content/modules/orders/storefront/create-swap.mdx +++ b/www/apps/docs/content/modules/orders/storefront/create-swap.mdx @@ -63,42 +63,10 @@ You can optionally allow customers to choose a return shipping option that they After collecting the swap details in step 1, you can create a swap in the Medusa backend by sending a request to the [Create Swap API Route](https://docs.medusajs.com/api/store#swaps_postswaps): - + -```ts -medusa.swaps.create({ - order_id, - return_items: [ - { - item_id, - quantity: 1, - }, - ], - additional_items: [ - { - variant_id, - quantity: 1, - }, - ], - return_shipping_option, -}) -.then(({ swap }) => { - console.log(swap.id) -}) -``` - - - - -```tsx -import { useCreateSwap } from "medusa-react" - -const CreateSwap = () => { - const createSwap = useCreateSwap() - // ... - - const handleCreate = () => { - createSwap.mutate({ + ```ts + medusa.swaps.create({ order_id, return_items: [ { @@ -114,48 +82,80 @@ const CreateSwap = () => { ], return_shipping_option, }) - } + .then(({ swap }) => { + console.log(swap.id) + }) + ``` - // ... -} + + -export default CreateSwap -``` + ```tsx + import { useCreateSwap } from "medusa-react" - - + const CreateSwap = () => { + const createSwap = useCreateSwap() + // ... -```ts -fetch(`/store/swaps`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - order_id, - return_items: [ - { - item_id, - quantity: 1, + const handleCreate = () => { + createSwap.mutate({ + order_id, + return_items: [ + { + item_id, + quantity: 1, + }, + ], + additional_items: [ + { + variant_id, + quantity: 1, + }, + ], + return_shipping_option, + }) + } + + // ... + } + + export default CreateSwap + ``` + + + + + ```ts + fetch(`/store/swaps`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", }, - ], - additional_items: [ - { - variant_id, - quantity: 1, - }, - ], - return_shipping_option, - }), -}) -.then((response) => response.json()) -.then(({ swap }) => { - console.log(swap.id) -}) -``` + body: JSON.stringify({ + order_id, + return_items: [ + { + item_id, + quantity: 1, + }, + ], + additional_items: [ + { + variant_id, + quantity: 1, + }, + ], + return_shipping_option, + }), + }) + .then((response) => response.json()) + .then(({ swap }) => { + console.log(swap.id) + }) + ``` - + This API Route requires the following request body parameters: @@ -191,53 +191,53 @@ When you complete the cart, the returned `type` field can be used to indicate th During your checkout flow, you might need to retrieve the swap using the cart’s ID. For example, if you want to display the swap’s details after the cart is successfully completed. You can do that using the [Get by Cart ID API Route](https://docs.medusajs.com/api/store#swaps_getswapsswapcartid): - + -```ts -medusa.swaps.retrieveByCartId(cartId) -.then(({ swap }) => { - console.log(swap.id) -}) -``` + ```ts + medusa.swaps.retrieveByCartId(cartId) + .then(({ swap }) => { + console.log(swap.id) + }) + ``` - - + + -```tsx -import { useCartSwap } from "medusa-react" + ```tsx + import { useCartSwap } from "medusa-react" -const Swap = () => { - const { - swap, - isLoading, - } = useCartSwap(cartId) - - return ( -
- {isLoading && Loading...} - {swap && {swap.id}} - -
- ) -} + const Swap = () => { + const { + swap, + isLoading, + } = useCartSwap(cartId) + + return ( +
+ {isLoading && Loading...} + {swap && {swap.id}} + +
+ ) + } -export default Swap -``` + export default Swap + ``` -
- + + -```ts -fetch(`/store/swaps/${cartId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ swap }) => { - console.log(swap.id) -}) -``` + ```ts + fetch(`/store/swaps/${cartId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ swap }) => { + console.log(swap.id) + }) + ``` - +
This API Route requires the ID of the cart as a path parameter. diff --git a/www/apps/docs/content/modules/orders/storefront/handle-order-edits.mdx b/www/apps/docs/content/modules/orders/storefront/handle-order-edits.mdx index 5887140197..6cdab82497 100644 --- a/www/apps/docs/content/modules/orders/storefront/handle-order-edits.mdx +++ b/www/apps/docs/content/modules/orders/storefront/handle-order-edits.mdx @@ -73,44 +73,44 @@ You must have an existing order edit in the “request” state. You can retrieve a single order edit by its ID by sending a request to the [Get Order Edit API Route](https://docs.medusajs.com/api/store#order-edits_getordereditsorderedit): - + -```ts -medusa.orderEdits.retrieve(orderEditId) -.then(({ order_edit }) => { - console.log(order_edit.changes) - // show changed items to the customer -}) -``` + ```ts + medusa.orderEdits.retrieve(orderEditId) + .then(({ order_edit }) => { + console.log(order_edit.changes) + // show changed items to the customer + }) + ``` - - + + -```tsx -import { useOrderEdit } from "medusa-react" + ```tsx + import { useOrderEdit } from "medusa-react" -const OrderEdit = () => { - const { order_edit, isLoading } = useOrderEdit(orderEditId) + const OrderEdit = () => { + const { order_edit, isLoading } = useOrderEdit(orderEditId) - // ... -} + // ... + } -export default OrderEdit -``` + export default OrderEdit + ``` - - + + -```ts -fetch(`/store/order-edits/${orderEditId}`) -.then((response) => response.json()) -.then(({ order_edit }) => { - console.log(order_edit.changes) - // show changed items to the customer -}) -``` + ```ts + fetch(`/store/order-edits/${orderEditId}`) + .then((response) => response.json()) + .then(({ order_edit }) => { + console.log(order_edit.changes) + // show changed items to the customer + }) + ``` - + The request requires the order edit’s ID as a path parameter. @@ -201,132 +201,132 @@ If `difference_due` is greater than 0, then additional payment from the customer 2. When the customer selects the payment processor, initialize the payment session of that provider in the payment collection. You can do that by sending a request to the [Manage Payment Sessions API Route](https://docs.medusajs.com/api/store#payment-collections_postpaymentcollectionspaymentcollectionsessionsbatch), passing it the payment collection’s ID as a path parameter, and the payment processor's ID as a request body parameter: - + -```ts -medusa.paymentCollections.managePaymentSession(paymentCollectionId, { - provider_id, -}) -.then(({ payment_collection }) => { - console.log(payment_collection.payment_sessions) -}) -``` - - - - -```tsx -import { useManagePaymentSession } from "medusa-react" - -const OrderEditPayment = () => { - const managePaymentSession = useManagePaymentSession( - paymentCollectionId - ) - // ... - - const handleAdditionalPayment = (provider_id: string) => { - managePaymentSession.mutate({ + ```ts + medusa.paymentCollections.managePaymentSession(paymentCollectionId, { provider_id, }) - } + .then(({ payment_collection }) => { + console.log(payment_collection.payment_sessions) + }) + ``` - // ... -} + + -export default OrderEditPayment -``` + ```tsx + import { useManagePaymentSession } from "medusa-react" - - + const OrderEditPayment = () => { + const managePaymentSession = useManagePaymentSession( + paymentCollectionId + ) + // ... + + const handleAdditionalPayment = (provider_id: string) => { + managePaymentSession.mutate({ + provider_id, + }) + } + + // ... + } + + export default OrderEditPayment + ``` + + + -```ts -fetch( - `/store/payment-collections/${paymentCollectionId}/sessions`, - { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - provider_id, - }), - } -) -.then((response) => response.json()) -.then(({ payment_collection }) => { - console.log(payment_collection.payment_sessions) -}) -``` + ```ts + fetch( + `/store/payment-collections/${paymentCollectionId}/sessions`, + { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + provider_id, + }), + } + ) + .then((response) => response.json()) + .then(({ payment_collection }) => { + console.log(payment_collection.payment_sessions) + }) + ``` - + 1. Show the customer the payment details form based on the payment session’s provider. For example, if the provider ID of a payment session is `stripe`, you must show Stripe’s card component to enter the customer’s card details. 2. Authorize the payment using the payment processor. The [Authorize Payment Session API Route](https://docs.medusajs.com/api/store#payment-collections_postpaymentcollectionssessionssessionauthorize) accepts the payment collection’s ID and the ID of the payment session as path parameters: - + -```ts -medusa - .paymentCollection - .authorizePaymentSession( - paymentCollectionId, - paymentSessionId - ) -.then(({ payment_session }) => { - console.log(payment_session.id) -}) -``` + ```ts + medusa + .paymentCollection + .authorizePaymentSession( + paymentCollectionId, + paymentSessionId + ) + .then(({ payment_session }) => { + console.log(payment_session.id) + }) + ``` - - + + -```tsx -import { useAuthorizePaymentSession } from "medusa-react" + ```tsx + import { useAuthorizePaymentSession } from "medusa-react" -const OrderEditPayment = () => { - const authorizePaymentSession = useAuthorizePaymentSession( - paymentCollectionId - ) - // ... + const OrderEditPayment = () => { + const authorizePaymentSession = useAuthorizePaymentSession( + paymentCollectionId + ) + // ... - const handleAuthorizePayment = (paymentSessionId: string) => { - authorizePaymentSession.mutate(paymentSessionId) - } + const handleAuthorizePayment = (paymentSessionId: string) => { + authorizePaymentSession.mutate(paymentSessionId) + } - // ... -} + // ... + } -export default OrderEditPayment -``` + export default OrderEditPayment + ``` - - + + -```ts -fetch( - `/store/payment-collection/${paymentCollectionId}` + - `/sessions/${paymentSessionId}/authorize`, - { - method: "POST", - credentials: "include", - } -) -.then((response) => response.json()) -.then(({ payment_session }) => { - console.log(payment_session.id) -}) -``` + ```ts + fetch( + `/store/payment-collection/${paymentCollectionId}` + + `/sessions/${paymentSessionId}/authorize`, + { + method: "POST", + credentials: "include", + } + ) + .then((response) => response.json()) + .then(({ payment_session }) => { + console.log(payment_session.id) + }) + ``` - + After performing the above steps, you can [complete the Order Edit](#complete-the-order-edit). @@ -338,52 +338,52 @@ After performing the above steps, you can [complete the Order Edit](#complete-th To confirm and complete the order edit, send a request to the [Complete Order Edit API Route](https://docs.medusajs.com/api/store#order-edits_postordereditsordereditcomplete): - + -```ts -medusa.orderEdits.complete(orderEditId) -.then(({ order_edit }) => { - console.log(order_edit.confirmed_at) -}) -``` + ```ts + medusa.orderEdits.complete(orderEditId) + .then(({ order_edit }) => { + console.log(order_edit.confirmed_at) + }) + ``` - - + + -```tsx -import { useCompleteOrderEdit } from "medusa-react" + ```tsx + import { useCompleteOrderEdit } from "medusa-react" -const OrderEdit = () => { - const completeOrderEdit = useCompleteOrderEdit(orderEditId) - // ... + const OrderEdit = () => { + const completeOrderEdit = useCompleteOrderEdit(orderEditId) + // ... - const handleCompleteOrderEdit = () => { - completeOrderEdit.mutate() - } + const handleCompleteOrderEdit = () => { + completeOrderEdit.mutate() + } - // ... -} + // ... + } -export default OrderEdit -``` + export default OrderEdit + ``` - - + + -```ts -fetch(`/store/order-edits/${orderEditId}/complete`, { - method: "POST", - credentials: "include", -}) -.then((response) => response.json()) -.then(({ order_edit }) => { - console.log(order_edit.confirmed_at) -}) -``` + ```ts + fetch(`/store/order-edits/${orderEditId}/complete`, { + method: "POST", + credentials: "include", + }) + .then((response) => response.json()) + .then(({ order_edit }) => { + console.log(order_edit.confirmed_at) + }) + ``` - + This request accepts the order edit’s ID as a path parameter. @@ -405,63 +405,63 @@ If the payment isn’t authorized first, the order edit completion will fail. If the customer wants to decline the Order Edit, you can do that by sending a request to the Decline Order Edit API Route: - + -```ts -medusa.orderEdits.decline(orderEditId, { - decline_reason: "I am not satisfied", -}) -.then(({ order_edit }) => { - console.log(order_edit.declined_at) -}) -``` - - - - -```tsx -import { useDeclineOrderEdit } from "medusa-react" - -const OrderEdit = () => { - const declineOrderEdit = useDeclineOrderEdit(orderEditId) - // ... - - const handleDeclineOrderEdit = () => { - declineOrderEdit.mutate({ - declined_reason: "I am not satisfied", - }) - } - - // ... -} - -export default OrderEdit -``` - - - - -```ts -fetch( - `/store/order-edits/${orderEditId}/decline`, - { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ + ```ts + medusa.orderEdits.decline(orderEditId, { decline_reason: "I am not satisfied", - }), - } -) -.then((response) => response.json()) -.then(({ order_edit }) => { - console.log(order_edit.declined_at) -}) -``` + }) + .then(({ order_edit }) => { + console.log(order_edit.declined_at) + }) + ``` - + + + + ```tsx + import { useDeclineOrderEdit } from "medusa-react" + + const OrderEdit = () => { + const declineOrderEdit = useDeclineOrderEdit(orderEditId) + // ... + + const handleDeclineOrderEdit = () => { + declineOrderEdit.mutate({ + declined_reason: "I am not satisfied", + }) + } + + // ... + } + + export default OrderEdit + ``` + + + + + ```ts + fetch( + `/store/order-edits/${orderEditId}/decline`, + { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + decline_reason: "I am not satisfied", + }), + } + ) + .then((response) => response.json()) + .then(({ order_edit }) => { + console.log(order_edit.declined_at) + }) + ``` + + The request requires passing the order edit’s ID as a path parameter. diff --git a/www/apps/docs/content/modules/orders/storefront/implement-claim-order.mdx b/www/apps/docs/content/modules/orders/storefront/implement-claim-order.mdx index d261e036dc..f5ca8d59bc 100644 --- a/www/apps/docs/content/modules/orders/storefront/implement-claim-order.mdx +++ b/www/apps/docs/content/modules/orders/storefront/implement-claim-order.mdx @@ -80,47 +80,47 @@ When the customer wants to claim an order, they must supply its ID. To allow the customer to claim an order, send a request to the Claim an Order API Route: - + -```ts -medusa.orders.requestCustomerOrders({ - order_ids: [ - order_id, - ], -}) -.then(() => { - // successful -}) -.catch(() => { - // an error occurred -}) -``` + ```ts + medusa.orders.requestCustomerOrders({ + order_ids: [ + order_id, + ], + }) + .then(() => { + // successful + }) + .catch(() => { + // an error occurred + }) + ``` - - + + -```ts -fetch(`/store/orders/batch/customer/token`, { - method: "POST", - credentials: "include", - body: JSON.stringify({ - order_ids: [ - order_id, - ], - }), - headers: { - "Content-Type": "application/json", - }, -}) -.then(() => { - // successful -}) -.catch(() => { - // display an error to the customer -}) -``` + ```ts + fetch(`/store/orders/batch/customer/token`, { + method: "POST", + credentials: "include", + body: JSON.stringify({ + order_ids: [ + order_id, + ], + }), + headers: { + "Content-Type": "application/json", + }, + }) + .then(() => { + // successful + }) + .catch(() => { + // display an error to the customer + }) + ``` - + This request accepts as a body parameter the array `order_ids`. Each item in the array is the ID of an order that the customer wants to claim. You can pass more than one ID. @@ -138,65 +138,65 @@ The link in the email that the customer receives should be a page in your storef Then, you send a request to the Verify Claim Order API Route: - + -```ts -medusa.orders.confirmRequest({ - token, -}) -.then(() => { - // successful -}) -.catch(() => { - // an error occurred -}) -``` - - - - -```tsx -import { useGrantOrderAccess } from "medusa-react" - -const ClaimOrder = () => { - const grantOrderAccess = useGrantOrderAccess() - // ... - - const handleVerifyOrderClaim = (token: string) => { - grantOrderAccess.mutate(({ + ```ts + medusa.orders.confirmRequest({ token, - })) - } + }) + .then(() => { + // successful + }) + .catch(() => { + // an error occurred + }) + ``` - // ... -} + + -export default ClaimOrder -``` + ```tsx + import { useGrantOrderAccess } from "medusa-react" - - + const ClaimOrder = () => { + const grantOrderAccess = useGrantOrderAccess() + // ... -```ts -fetch(`/store/orders/customer/confirm`, { - method: "POST", - credentials: "include", - body: JSON.stringify({ - token, - }), - headers: { - "Content-Type": "application/json", - }, -}) -.then(() => { - // successful -}) -.catch(() => { - // display an error to the customer -}) -``` + const handleVerifyOrderClaim = (token: string) => { + grantOrderAccess.mutate(({ + token, + })) + } - + // ... + } + + export default ClaimOrder + ``` + + + + + ```ts + fetch(`/store/orders/customer/confirm`, { + method: "POST", + credentials: "include", + body: JSON.stringify({ + token, + }), + headers: { + "Content-Type": "application/json", + }, + }) + .then(() => { + // successful + }) + .catch(() => { + // display an error to the customer + }) + ``` + + This request accepts as a body parameter the string `token`. This would be the token passed as a parameter to your storefront page through the link in the email. diff --git a/www/apps/docs/content/modules/orders/storefront/retrieve-order-details.mdx b/www/apps/docs/content/modules/orders/storefront/retrieve-order-details.mdx index 0dcdd820f1..71d3600c68 100644 --- a/www/apps/docs/content/modules/orders/storefront/retrieve-order-details.mdx +++ b/www/apps/docs/content/modules/orders/storefront/retrieve-order-details.mdx @@ -39,53 +39,53 @@ Retrieving an order by its ID is useful for different scenarios, such as using a You can retrieve an order by its ID using the [Get Order API Route](https://docs.medusajs.com/api/store#orders_getordersorder): - + -```ts -medusa.orders.retrieve(orderId) -.then(({ order }) => { - console.log(order.id) -}) -``` + ```ts + medusa.orders.retrieve(orderId) + .then(({ order }) => { + console.log(order.id) + }) + ``` - - + + -```tsx -import { useOrder } from "medusa-react" + ```tsx + import { useOrder } from "medusa-react" -const Order = () => { - const { - order, - isLoading, - } = useOrder(orderId) - - return ( -
- {isLoading && Loading...} - {order && {order.display_id}} - -
- ) -} + const Order = () => { + const { + order, + isLoading, + } = useOrder(orderId) + + return ( +
+ {isLoading && Loading...} + {order && {order.display_id}} + +
+ ) + } -export default Order -``` + export default Order + ``` -
- + + -```ts -fetch(`/store/orders/${orderId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.id) -}) -``` + ```ts + fetch(`/store/orders/${orderId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.id) + }) + ``` - +
This API Route requires the order’s ID to be passed as a path parameter. You can utilize the [expand](https://docs.medusajs.com/api/store#expanding-fields) and [fields](https://docs.medusajs.com/api/store#selecting-fields) query parameters to select parameters and relations to return. @@ -101,61 +101,61 @@ Display IDs allow you to show human-readable IDs to your customers. Retrieving a You can retrieve an order by its display ID using the [Look Up Order API Route](https://docs.medusajs.com/api/store#orders_getorders): - + -```ts -medusa.orders.lookupOrder({ - display_id: 1, - email: "user@example.com", -}) -.then(({ order }) => { - console.log(order.id) -}) -``` + ```ts + medusa.orders.lookupOrder({ + display_id: 1, + email: "user@example.com", + }) + .then(({ order }) => { + console.log(order.id) + }) + ``` - - + + -```tsx -import { useOrders } from "medusa-react" + ```tsx + import { useOrders } from "medusa-react" -const Order = () => { - const { - order, - isLoading, - } = useOrders({ - display_id: 1, - email: "user@example.com", - }) - - return ( -
- {isLoading && Loading...} - {order && {order.display_id}} - -
- ) -} + const Order = () => { + const { + order, + isLoading, + } = useOrders({ + display_id: 1, + email: "user@example.com", + }) + + return ( +
+ {isLoading && Loading...} + {order && {order.display_id}} + +
+ ) + } -export default Order -``` + export default Order + ``` -
- + + -```ts -fetch(`/store/orders?display_id=1&email=user@example.com`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.id) -}) -``` + ```ts + fetch(`/store/orders?display_id=1&email=user@example.com`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.id) + }) + ``` - +
This API Route requires two query parameters: @@ -176,53 +176,53 @@ In certain scenarios, you may need to retrieve an order’s details using the ID You can retrieve an order by the cart ID using the [Get by Cart ID API Route](https://docs.medusajs.com/api/store#orders_getordersordercartid): - + -```ts -medusa.orders.retrieveByCartId(cartId) -.then(({ order }) => { - console.log(order.id) -}) -``` + ```ts + medusa.orders.retrieveByCartId(cartId) + .then(({ order }) => { + console.log(order.id) + }) + ``` - - + + -```tsx -import { useCartOrder } from "medusa-react" + ```tsx + import { useCartOrder } from "medusa-react" -const Order = () => { - const { - order, - isLoading, - } = useCartOrder(cartId) - - return ( -
- {isLoading && Loading...} - {order && {order.display_id}} - -
- ) -} + const Order = () => { + const { + order, + isLoading, + } = useCartOrder(cartId) + + return ( +
+ {isLoading && Loading...} + {order && {order.display_id}} + +
+ ) + } -export default Order -``` + export default Order + ``` -
- + + -```ts -fetch(`/store/orders/cart/${cartId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ order }) => { - console.log(order.id) -}) -``` + ```ts + fetch(`/store/orders/cart/${cartId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ order }) => { + console.log(order.id) + }) + ``` - +
This API Route requires the ID of the cart as a path parameter. diff --git a/www/apps/docs/content/modules/price-lists/admin/_import-prices.mdx b/www/apps/docs/content/modules/price-lists/admin/_import-prices.mdx index 35a91fcb4a..446f3ee75d 100644 --- a/www/apps/docs/content/modules/price-lists/admin/_import-prices.mdx +++ b/www/apps/docs/content/modules/price-lists/admin/_import-prices.mdx @@ -3,8 +3,9 @@ description: 'Learn how to bulk-import prices into Medusa using the Admin REST A addHowToData: true --- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; +import Tabs from '@theme/Tabs' +import TabItem from '@theme/TabItem' +import Details from "@site/src/theme/MDXProvider/Details" # How to Bulk Import Prices @@ -39,81 +40,79 @@ Part of the process of importing prices is uploading a CSV file. This requires a You must have a CSV file that you will use to import prices into your Medusa backend. You can check [this CSV example file](https://medusa-doc-files.s3.amazonaws.com/price-list-import-template.csv) to see which format is required for your import. -
- -Expected columns - +
+ Expected columns - - - - - - - - +
-Column Name - -Description - -Is required? -
+ + + + + + + - + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - + -
+ Column Name + + Description + + Is required? +
-Product Variant ID - -The ID of the product variant this price belongs to. - -Either this or the SKU column are required. -
+ Product Variant ID + + The ID of the product variant this price belongs to. + + Either this or the SKU column are required. +
-SKU - -The SKU of the product variant this price belongs to. - -Either this or the Product Variant ID column are required. -
+ SKU + + The SKU of the product variant this price belongs to. + + Either this or the Product Variant ID column are required. +
-Price (region name) - -The price amount in a region, where (region name) is the name of the region. - -No -
+ Price (region name) + + The price amount in a region, where (region name) is the name of the region. + + No +
-Price (currency code) - -The price amount for a currency, where (currency code) is the 3 character iso code of the currency. For example, "Price USD". - -No -
+ Price (currency code) + + The price amount for a currency, where (currency code) is the 3 character iso code of the currency. For example, "Price USD". + + No +
+ -
+
### JS Client @@ -148,67 +147,67 @@ The first step is to upload the CSV file to import prices from. You can do that by sending the following request to the [Upload Files API Route](https://docs.medusajs.com/api/admin#uploads_postuploads): - + -```ts -medusa.admin.uploads.create(file) // file is an instance of File -.then(({ uploads }) => { - const key = uploads[0].key -}) -``` + ```ts + medusa.admin.uploads.create(file) // file is an instance of File + .then(({ uploads }) => { + const key = uploads[0].key + }) + ``` - - + + -```tsx -import { useAdminUploadFile } from "medusa-react" + ```tsx + import { useAdminUploadFile } from "medusa-react" -const ImportPrices = () => { - const uploadFile = useAdminUploadFile() - // ... + const ImportPrices = () => { + const uploadFile = useAdminUploadFile() + // ... - const handleFileUpload = (file: File) => { - uploadFile.mutate(file) - } + const handleFileUpload = (file: File) => { + uploadFile.mutate(file) + } - // ... -} + // ... + } -export default ImportPrices -``` + export default ImportPrices + ``` - - + + -```ts -const formData = new FormData() -formData.append("files", file) // file is an instance of File + ```ts + const formData = new FormData() + formData.append("files", file) // file is an instance of File -fetch(`/admin/uploads`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "multipart/form-data", - }, - body: formData, -}) -.then((response) => response.json()) -.then(({ uploads }) => { - const key = uploads[0].key -}) -``` + fetch(`/admin/uploads`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "multipart/form-data", + }, + body: formData, + }) + .then((response) => response.json()) + .then(({ uploads }) => { + const key = uploads[0].key + }) + ``` - - + + -```bash -curl -L -X POST '/admin/uploads' \ - -H 'Authorization: Bearer {api_token}' \ - -H 'Content-Type: text/csv' \ - -F 'files=@""' -``` + ```bash + curl -L -X POST '/admin/uploads' \ + -H 'Authorization: Bearer {api_token}' \ + -H 'Content-Type: text/csv' \ + -F 'files=@""' + ``` - + This request returns an array of uploads. Each item in the array is an object that includes the properties `url` and `key`. You’ll need the `key` to import the prices next. @@ -222,93 +221,93 @@ To start a new price import, you must create a batch job. You can do that by sending the following request to the [Create a Batch Job API Route](https://docs.medusajs.com/api/admin#batch-jobs_postbatchjobs): - + -```ts -medusa.admin.batchJobs.create({ - type: "price-list-import", - context: { - fileKey: key, // obtained from previous step - price_list_id, - }, - dry_run: true, -}) -.then(( batch_job ) => { - console.log(batch_job.status) -}) -``` - - - - -```tsx -import { useAdminCreateBatchJob } from "medusa-react" - -const ImportPrices = () => { - const createBatchJob = useAdminCreateBatchJob() - // ... - - const handleCreateBatchJob = () => { - createBatchJob.mutate({ + ```ts + medusa.admin.batchJobs.create({ type: "price-list-import", context: { fileKey: key, // obtained from previous step + price_list_id, }, dry_run: true, }) - } + .then(( batch_job ) => { + console.log(batch_job.status) + }) + ``` - // ... -} + + -export default ImportPrices -``` + ```tsx + import { useAdminCreateBatchJob } from "medusa-react" - - + const ImportPrices = () => { + const createBatchJob = useAdminCreateBatchJob() + // ... -```ts -fetch(`/admin/batch-jobs`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - type: "price-list-import", - context: { - fileKey: key, // obtained from previous step - price_list_id, - }, - dry_run: true, - }), -}) -.then((response) => response.json()) -.then(({ batch_job }) => { - console.log(batch_job.status) -}) -``` + const handleCreateBatchJob = () => { + createBatchJob.mutate({ + type: "price-list-import", + context: { + fileKey: key, // obtained from previous step + }, + dry_run: true, + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/batch-jobs' \ --H 'Authorization: Bearer {api_token}' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "type": "price-list-import", - "context": { - "fileKey": "", - "price_list_id": "" - }, - "dry_run": true -}' -# is the key you obtained from the previous step -# is the ID of the price list to import prices into -``` + export default ImportPrices + ``` - + + + + ```ts + fetch(`/admin/batch-jobs`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + type: "price-list-import", + context: { + fileKey: key, // obtained from previous step + price_list_id, + }, + dry_run: true, + }), + }) + .then((response) => response.json()) + .then(({ batch_job }) => { + console.log(batch_job.status) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/batch-jobs' \ + -H 'Authorization: Bearer {api_token}' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "type": "price-list-import", + "context": { + "fileKey": "", + "price_list_id": "" + }, + "dry_run": true + }' + # is the key you obtained from the previous step + # is the ID of the price list to import prices into + ``` + + In the body of the request, you must pass the following parameters: @@ -336,65 +335,65 @@ After creating the batch job, it will be pre-processed. At this point, the CSV f You can retrieve all the details of the batch job, including its status and the brief statistics related to the prices by sending the following request: - + -```ts -medusa.admin.batchJobs.retrieve(batchJobId) -.then(( batch_job ) => { - console.log(batch_job.status, batch_job.result) -}) -``` + ```ts + medusa.admin.batchJobs.retrieve(batchJobId) + .then(( batch_job ) => { + console.log(batch_job.status, batch_job.result) + }) + ``` - - + + -```tsx -import { useAdminBatchJob } from "medusa-react" + ```tsx + import { useAdminBatchJob } from "medusa-react" -const ImportPrices = () => { - const { batch_job, isLoading } = useAdminBatchJob(batchJobId) - // ... + const ImportPrices = () => { + const { batch_job, isLoading } = useAdminBatchJob(batchJobId) + // ... - return ( -
- {/* ... */} - {isLoading && Loading} - {batch_job && ( - - Status: {batch_job.status}. - Number of Prices: {batch_job.result.count} - - )} -
- ) -} + return ( +
+ {/* ... */} + {isLoading && Loading} + {batch_job && ( + + Status: {batch_job.status}. + Number of Prices: {batch_job.result.count} + + )} +
+ ) + } -export default ImportPrices -``` + export default ImportPrices + ``` -
- + + -```ts -fetch(`/admin/batch-jobs/${batchJobId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ batch_job }) => { - console.log(batch_job.status, batch_job.result) -}) -``` + ```ts + fetch(`/admin/batch-jobs/${batchJobId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ batch_job }) => { + console.log(batch_job.status, batch_job.result) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/batch-jobs/' \ --H 'Authorization: Bearer {api_token}' -# is the ID of the batch job -``` + ```bash + curl -L -X GET '/admin/batch-jobs/' \ + -H 'Authorization: Bearer {api_token}' + # is the ID of the batch job + ``` - +
This request accepts the batch job’s ID as a parameter, which can be retrieved from the previous request. It returns the batch job in the response. @@ -426,59 +425,59 @@ A batch job can be confirmed only once the batch job has the status `pre_process To confirm a batch job send the following request: - + -```ts -medusa.admin.batchJobs.confirm(batchJobId) -.then(( batch_job ) => { - console.log(batch_job.status) -}) -``` + ```ts + medusa.admin.batchJobs.confirm(batchJobId) + .then(( batch_job ) => { + console.log(batch_job.status) + }) + ``` - - + + -```tsx -import { useAdminConfirmBatchJob } from "medusa-react" + ```tsx + import { useAdminConfirmBatchJob } from "medusa-react" -const ImportPrices = () => { - const confirmBatchJob = useAdminConfirmBatchJob(batchJobId) - // ... + const ImportPrices = () => { + const confirmBatchJob = useAdminConfirmBatchJob(batchJobId) + // ... - const handleConfirmJob = () => { - confirmBatchJob.mutate() - } - - // ... -} + const handleConfirmJob = () => { + confirmBatchJob.mutate() + } + + // ... + } -export default ImportPrices -``` + export default ImportPrices + ``` - - + + -```ts -fetch(`/admin/batch-jobs/${batchJobId}/confirm`, { - method: "POST", - credentials: "include", -}) -.then((response) => response.json()) -.then(({ batch_job }) => { - console.log(batch_job.status) -}) -``` + ```ts + fetch(`/admin/batch-jobs/${batchJobId}/confirm`, { + method: "POST", + credentials: "include", + }) + .then((response) => response.json()) + .then(({ batch_job }) => { + console.log(batch_job.status) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/batch-jobs//confirm' \ --H 'Authorization: Bearer {api_token}' -# is the ID of the batch job -``` + ```bash + curl -L -X POST '/admin/batch-jobs//confirm' \ + -H 'Authorization: Bearer {api_token}' + # is the ID of the batch job + ``` - + This request accepts the ID of the batch job as a path parameter and returns the updated batch job. The returned batch job should have the status `confirmed`, which indicates that the batch job will now start processing. diff --git a/www/apps/docs/content/modules/price-lists/admin/manage-price-lists.mdx b/www/apps/docs/content/modules/price-lists/admin/manage-price-lists.mdx index 85e87b29a0..4fdbdcb81b 100644 --- a/www/apps/docs/content/modules/price-lists/admin/manage-price-lists.mdx +++ b/www/apps/docs/content/modules/price-lists/admin/manage-price-lists.mdx @@ -77,55 +77,15 @@ You can learn more about what the conditions you can apply on a price list and i For example, sending the following request creates a price list with two prices: one that is applied when the maximum quantity of the product variant in the cart is 3; another is applied when the minimum quantity of the same variant in the cart is 4: - + -```jsx -import { - PriceListStatus, - PriceListType, -} from "@medusajs/medusa" + ```jsx + import { + PriceListStatus, + PriceListType, + } from "@medusajs/medusa" -medusa.admin.priceLists.create({ - name: "New Price List", - description: "A new price list", - type: PriceListType.SALE, - status: PriceListStatus.ACTIVE, - prices: [ - { - amount: 1000, - variant_id, - currency_code: "eur", - max_quantity: 3, - }, - { - amount: 1500, - variant_id, - currency_code: "eur", - min_quantity: 4, - }, - ], -}) -.then(({ price_list }) => { - console.log(price_list.id) -}) -``` - - - - -```tsx -import { - PriceListStatus, - PriceListType, -} from "@medusajs/medusa" -import { useAdminCreatePriceList } from "medusa-react" - -const CreatePriceList = () => { - const createPriceList = useAdminCreatePriceList() - // ... - - const handleCreate = () => { - createPriceList.mutate({ + medusa.admin.priceLists.create({ name: "New Price List", description: "A new price list", type: PriceListType.SALE, @@ -145,81 +105,121 @@ const CreatePriceList = () => { }, ], }) - } + .then(({ price_list }) => { + console.log(price_list.id) + }) + ``` - // ... -} + + -export default CreatePriceList -``` + ```tsx + import { + PriceListStatus, + PriceListType, + } from "@medusajs/medusa" + import { useAdminCreatePriceList } from "medusa-react" - - + const CreatePriceList = () => { + const createPriceList = useAdminCreatePriceList() + // ... -```jsx -fetch(`/admin/price-lists`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - name: "New Price List", - description: "A new price list", - type: "sale", - status: "active", - prices: [ - { - amount: 1000, - variant_id, - currency_code: "eur", - max_quantity: 3, + const handleCreate = () => { + createPriceList.mutate({ + name: "New Price List", + description: "A new price list", + type: PriceListType.SALE, + status: PriceListStatus.ACTIVE, + prices: [ + { + amount: 1000, + variant_id, + currency_code: "eur", + max_quantity: 3, + }, + { + amount: 1500, + variant_id, + currency_code: "eur", + min_quantity: 4, + }, + ], + }) + } + + // ... + } + + export default CreatePriceList + ``` + + + + + ```jsx + fetch(`/admin/price-lists`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", }, - { - amount: 1500, - variant_id, - currency_code: "eur", - min_quantity: 4, - }, - ], - }), -}) -.then((response) => response.json()) -.then(({ price_list }) => { - console.log(price_list.id) -}) -``` + body: JSON.stringify({ + name: "New Price List", + description: "A new price list", + type: "sale", + status: "active", + prices: [ + { + amount: 1000, + variant_id, + currency_code: "eur", + max_quantity: 3, + }, + { + amount: 1500, + variant_id, + currency_code: "eur", + min_quantity: 4, + }, + ], + }), + }) + .then((response) => response.json()) + .then(({ price_list }) => { + console.log(price_list.id) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/price-lists' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "name": "New Price List", - "description": "A new price list", - "type": "sale", - "status": "active", - "prices": [ - { - "amount": 1500, - "variant_id": "", - "max_quantity": 3, - "currency_code": "eur" - }, - { - "amount": 1000, - "variant_id": "", - "currency_code": "eur", - "min_quantity": 4 - } - ] -}' -``` + ```bash + curl -L -X POST '/admin/price-lists' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "name": "New Price List", + "description": "A new price list", + "type": "sale", + "status": "active", + "prices": [ + { + "amount": 1500, + "variant_id": "", + "max_quantity": 3, + "currency_code": "eur" + }, + { + "amount": 1000, + "variant_id": "", + "currency_code": "eur", + "min_quantity": 4 + } + ] + }' + ``` - + This request returns the created price list. @@ -233,61 +233,61 @@ You can check the full list of request body parameters in the [API reference](ht You can retrieve all of a price list’s details using the Get a Price List API Route: - + -```jsx -medusa.admin.priceLists.retrieve(priceListId) -.then(({ price_list }) => { - console.log(price_list.id) -}) -``` + ```jsx + medusa.admin.priceLists.retrieve(priceListId) + .then(({ price_list }) => { + console.log(price_list.id) + }) + ``` - - + + -```tsx -import { CustomerGroup } from "@medusajs/medusa" -import { useAdminPriceList } from "medusa-react" + ```tsx + import { CustomerGroup } from "@medusajs/medusa" + import { useAdminPriceList } from "medusa-react" -const PriceList = () => { - const { - price_list, - isLoading, - } = useAdminPriceList(priceListId) + const PriceList = () => { + const { + price_list, + isLoading, + } = useAdminPriceList(priceListId) - return ( -
- {isLoading && Loading...} - {price_list && {price_list.name}} -
- ) -} + return ( +
+ {isLoading && Loading...} + {price_list && {price_list.name}} +
+ ) + } -export default PriceList -``` + export default PriceList + ``` -
- + + -```jsx -fetch(`/admin/price-lists/${priceListId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ price_list }) => { - console.log(price_list.id) -}) -``` + ```jsx + fetch(`/admin/price-lists/${priceListId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ price_list }) => { + console.log(price_list.id) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/price-lists/{id}' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/price-lists/{id}' \ + -H 'Authorization: Bearer ' + ``` - +
--- @@ -299,76 +299,76 @@ After creating a price list, you can update all of its fields including its stat For example, by sending the following request the end date of the price list will be updated: - + -```jsx -medusa.admin.priceLists.update(priceListId, { - ends_at: "2022-10-11", -}) -.then(({ price_list }) => { - console.log(price_list.id) -}) -``` - - - - -```tsx -import { - PriceListStatus, - PriceListType, -} from "@medusajs/medusa" -import { useAdminUpdatePriceList } from "medusa-react" - -const CreatePriceList = () => { - const updatePriceList = useAdminUpdatePriceList(priceListId) - // ... - - const handleUpdate = () => { - updatePriceList.mutate({ + ```jsx + medusa.admin.priceLists.update(priceListId, { ends_at: "2022-10-11", }) - } + .then(({ price_list }) => { + console.log(price_list.id) + }) + ``` - // ... -} + + -export default CreatePriceList -``` + ```tsx + import { + PriceListStatus, + PriceListType, + } from "@medusajs/medusa" + import { useAdminUpdatePriceList } from "medusa-react" - - + const CreatePriceList = () => { + const updatePriceList = useAdminUpdatePriceList(priceListId) + // ... -```jsx -fetch(`/admin/price-lists/${priceListId}`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - ends_at: "2022-10-11", - }), -}) -.then((response) => response.json()) -.then(({ price_list }) => { - console.log(price_list.id) -}) -``` + const handleUpdate = () => { + updatePriceList.mutate({ + ends_at: "2022-10-11", + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/price-lists/' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "ends_at": "2022-10-11" -}' -``` + export default CreatePriceList + ``` - + + + + ```jsx + fetch(`/admin/price-lists/${priceListId}`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + ends_at: "2022-10-11", + }), + }) + .then((response) => response.json()) + .then(({ price_list }) => { + console.log(price_list.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/price-lists/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "ends_at": "2022-10-11" + }' + ``` + + This request returns the updated price list. @@ -388,35 +388,10 @@ You can also set the `override` request body parameter to `true` to replace the For example, sending the following request adds a new price to the price list: - + -```jsx -medusa.admin.priceLists.addPrices(priceListId, { - prices: [ - { - amount: 1200, - variant_id, - currency_code: "eur", - }, - ], -}) -.then(({ price_list }) => { - console.log(price_list.id) -}) -``` - - - - -```tsx -import { useAdminCreatePriceListPrices } from "medusa-react" - -const PriceList = () => { - const addPrice = useAdminCreatePriceListPrices(priceListId) - // ... - - const handleAddPrice = () => { - addPrice.mutate({ + ```jsx + medusa.admin.priceLists.addPrices(priceListId, { prices: [ { amount: 1200, @@ -425,61 +400,86 @@ const PriceList = () => { }, ], }) - } + .then(({ price_list }) => { + console.log(price_list.id) + }) + ``` - // ... -} + + -export default PriceList -``` + ```tsx + import { useAdminCreatePriceListPrices } from "medusa-react" - - + const PriceList = () => { + const addPrice = useAdminCreatePriceListPrices(priceListId) + // ... + + const handleAddPrice = () => { + addPrice.mutate({ + prices: [ + { + amount: 1200, + variant_id, + currency_code: "eur", + }, + ], + }) + } + + // ... + } + + export default PriceList + ``` + + + -```jsx -fetch(`/admin/price-lists/${priceListId}/prices/batch`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - prices: [ - { - amount: 1200, - variant_id, - currency_code: "eur", - }, - ], - }), -}) -.then((response) => response.json()) -.then(({ price_list }) => { - console.log(price_list.id) -}) -``` + ```jsx + fetch(`/admin/price-lists/${priceListId}/prices/batch`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + prices: [ + { + amount: 1200, + variant_id, + currency_code: "eur", + }, + ], + }), + }) + .then((response) => response.json()) + .then(({ price_list }) => { + console.log(price_list.id) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/price-lists/' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "prices": [ - { - "amount": 1200, - "variant_id": "", - "currency_code": "eur" - } - ] -}' -``` + ```bash + curl -L -X POST '/admin/price-lists/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "prices": [ + { + "amount": 1200, + "variant_id": "", + "currency_code": "eur" + } + ] + }' + ``` - + This request returns the price list with the updated prices. @@ -491,71 +491,71 @@ For a full list of request body parameters, check out the [API reference](https: You can delete all the prices of a product’s variants using the [Delete Product Prices API Route](https://docs.medusajs.com/api/admin#price-lists_deletepricelistspricelistpricesbatch): - + -```tsx -medusa - .admin - .priceLists - .deleteProductPrices(priceListId, productId) - .then(({ ids, object, deleted }) => { - console.log(ids.length) - }) -``` + ```tsx + medusa + .admin + .priceLists + .deleteProductPrices(priceListId, productId) + .then(({ ids, object, deleted }) => { + console.log(ids.length) + }) + ``` - - + + -```tsx -import { - useAdminDeletePriceListProductPrices, -} from "medusa-react" + ```tsx + import { + useAdminDeletePriceListProductPrices, + } from "medusa-react" -const PriceList = () => { - const deletePrices = useAdminDeletePriceListProductPrices( - priceListId, - productId - ) - // ... + const PriceList = () => { + const deletePrices = useAdminDeletePriceListProductPrices( + priceListId, + productId + ) + // ... - const handleDeletePrices = () => { - deletePrices.mutate() - } + const handleDeletePrices = () => { + deletePrices.mutate() + } - // ... -} + // ... + } -export default PriceList -``` + export default PriceList + ``` - - + + -```jsx -fetch( - `/admin/price-lists/${priceListId}/products/${productId}/prices`, - { - method: "DELETE", - credentials: "include", - } -) -.then((response) => response.json()) -.then(({ ids, object, deleted }) => { - console.log(ids.length) -}) -``` + ```jsx + fetch( + `/admin/price-lists/${priceListId}/products/${productId}/prices`, + { + method: "DELETE", + credentials: "include", + } + ) + .then((response) => response.json()) + .then(({ ids, object, deleted }) => { + console.log(ids.length) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/price-lists//products//prices' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/price-lists//products//prices' \ + -H 'Authorization: Bearer ' + ``` - + This request returns the IDs of the deleted prices. @@ -565,72 +565,72 @@ This request returns the IDs of the deleted prices. You can delete all the prices of a variant using the [Delete Variant Prices API Route](https://docs.medusajs.com/api/admin#price-lists_deletepricelistspricelistvariantsvariantprices): - + -```tsx -medusa - .admin - .priceLists - .deleteVariantPrices(priceListId, variantId) - .then(({ ids, object, deleted }) => { - console.log(ids) - }) -``` + ```tsx + medusa + .admin + .priceLists + .deleteVariantPrices(priceListId, variantId) + .then(({ ids, object, deleted }) => { + console.log(ids) + }) + ``` - - + + -```tsx -import { - useAdminDeletePriceListVariantPrices, -} from "medusa-react" + ```tsx + import { + useAdminDeletePriceListVariantPrices, + } from "medusa-react" -const PriceList = () => { - const deleteVariantPrices = - useAdminDeletePriceListVariantPrices( - priceListId, - variantId - ) - // ... + const PriceList = () => { + const deleteVariantPrices = + useAdminDeletePriceListVariantPrices( + priceListId, + variantId + ) + // ... - const handleDeletePrices = () => { - deleteVariantPrices.mutate() - } + const handleDeletePrices = () => { + deleteVariantPrices.mutate() + } - // ... -} + // ... + } -export default PriceList -``` + export default PriceList + ``` - - + + -```jsx -fetch( - `/admin/price-lists/${priceListId}/variants/${variantId}/prices`, - { - method: "DELETE", - credentials: "include", - } -) -.then((response) => response.json()) -.then(({ ids, object, deleted }) => { - console.log(ids.length) -}) -``` + ```jsx + fetch( + `/admin/price-lists/${priceListId}/variants/${variantId}/prices`, + { + method: "DELETE", + credentials: "include", + } + ) + .then((response) => response.json()) + .then(({ ids, object, deleted }) => { + console.log(ids.length) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/price-lists//variants//prices' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/price-lists//variants//prices' \ + -H 'Authorization: Bearer ' + ``` - + This request returns the IDs of the deleted prices. @@ -642,58 +642,58 @@ This request returns the IDs of the deleted prices. You can delete a price list, and subsequently all prices defined in it, using the [Delete Price List API Route](https://docs.medusajs.com/api/admin#price-lists_deletepricelistspricelist): - + -```jsx -medusa.admin.priceLists.delete(priceListId) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```jsx + medusa.admin.priceLists.delete(priceListId) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```tsx -import { useAdminDeletePriceList } from "medusa-react" + ```tsx + import { useAdminDeletePriceList } from "medusa-react" -const PriceList = () => { - const deletePriceList = useAdminDeletePriceList(priceListId) - // ... + const PriceList = () => { + const deletePriceList = useAdminDeletePriceList(priceListId) + // ... - const handleDeletePriceList = () => { - deletePriceList.mutate() - } + const handleDeletePriceList = () => { + deletePriceList.mutate() + } - // ... -} + // ... + } -export default PriceList -``` + export default PriceList + ``` - - + + -```jsx -fetch(`/admin/price-lists/${priceListId}`, { - method: "DELETE", - credentials: "include", -}) -.then((response) => response.json()) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```jsx + fetch(`/admin/price-lists/${priceListId}`, { + method: "DELETE", + credentials: "include", + }) + .then((response) => response.json()) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/price-lists/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/price-lists/' \ + -H 'Authorization: Bearer ' + ``` - + This request returns the ID of the deleted price list. \ No newline at end of file diff --git a/www/apps/docs/content/modules/products/admin/import-products.mdx b/www/apps/docs/content/modules/products/admin/import-products.mdx index 50fdfe8df4..a7a3d3b74a 100644 --- a/www/apps/docs/content/modules/products/admin/import-products.mdx +++ b/www/apps/docs/content/modules/products/admin/import-products.mdx @@ -3,8 +3,8 @@ description: 'Learn how to import products into Medusa using the Admin REST APIs addHowToData: true --- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; +import Tabs from '@theme/Tabs' +import TabItem from '@theme/TabItem' # How to Bulk Import Products @@ -39,810 +39,808 @@ The local file service can't be used for product import. You must have a CSV file that you will use to import products into your Medusa backend. You can check [this CSV example file](https://medusa-doc-files.s3.amazonaws.com/product-import-sales-channels.csv) to see which format is required for your import. -
- -Expected columns - - -#### Product columns - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Column name - -Description - -Is required? -
-Product Handle - -The handle of the product - -Yes -
-Product Id - -The ID of the product - -No -
-Product Title - -The title of the product - -No -
-Product Subtitle - -The subtitle of the product - -No -
-Product Description - -The description of the product - -No -
-Product Status - -The status of the product. Its value can be `draft`, `proposed`, `published`, or `rejected`. - -No -
-Product Thumbnail - -A URL to the thumbnail of the product - -No -
-Image (number) Url - -A URL to a product image. To add more than one image, you can specify the image number in the column title. For example, "Image 1 Url". - -No -
-Product Weight - -The weight of the product - -No -
-Product Length - -The length of the product - -No -
-Product Width - -The width of the product - -No -
-Product Height - -The height of the product - -No -
-Product HS Code - -The HS Code of the product - -No -
-Product Origin Country - -The origin country of the product - -No -
-Product MID Code - -The MID code of the product - -No -
-Product Material - -The material of the product - -No -
-Product Discountable - -A boolean value indicating whether the product is discountable. - -No -
-Product External Id - -The external ID of the product. Useful if the product is being imported from another platform and you want to maintain the link to it. - -No -
-Product Profile Name - -The name of the product's shipping profile. - -No -
-Product Profile Type - -The type of the product's shipping profile. Its value can be `default`, `gift_card`, or `custom`. - -No -
- -#### Product Collection columns - -:::note - -A product collection is only associated with the product if the handle provided exists. Otherwise, it's skipped. - -::: - - - - - - - - - - - - - - - - - - - - - - - - - -
-Column name - -Description - -Is required? -
-Product Collection Title - -The title of the product collection - -No -
-Product Collection Handle - -The handle of the product collection - -No -
- -#### Product Type columns - - - - - - - - - - - - - - - - - - - -
-Column name - -Description - -Is required? -
-Product Type - -The value of the product type - -No -
- -#### Product Tag columns - - - - - - - - - - - - - - - - - - - -
-Column name - -Description - -Is required? -
-Product Tags - -A comma-separated list of product tags - -No -
- -#### Product Option columns - - - - - - - - - - - - - - - - - - - - - - - - - -
-Column name - -Description - -Is required? -
-"Option Name" or "Option (number) Name" - -The name of the product option. If you name the column "Option Name", it means only one option will be added, and there should be no duplicate column with the same name for another option. To add more than one option, use the "Option (number) Name" name. For example, "Option 1 Name". - -No -
-"Option Value" or "Option (number) Value" - -The value of the product option. If you name the column "Option Value", it means only one option will be added, and there should be no duplicate column with the same name for another option. To add more than one option value, use the "Option (number) Value" name. For example, "Option 1 Value". The number of the value should correspond to the same option name number. - -No -
- -#### Product Variant Columns - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Column name - -Description - -Is required? -
-Variant Id - -The ID of the product variant - -No -
-Variant Title - -The title of the product variant - -No -
-Variant SKU - -The SKU of the product variant - -No -
-Variant Barcode - -The barcode of the product variant - -No -
-Variant Inventory Quantity - -The inventory quantity of the product variant - -No -
-Variant Allow Backorder - -A boolean value indicating if the variant can be back-ordered. - -No -
-Variant Manage Inventory - -A boolean value indicating if the variant's inventory can be managed. - -No -
-Variant Weight - -The weight of the product variant - -No -
-Variant Length - -The length of the product variant - -No -
-Variant Width - -The width of the product variant - -No -
-Variant Height - -The height of the product variant - -No -
-Variant HS Code - -The HS Code of the product variant - -No -
-Variant Origin Country - -The origin country of the product variant - -No -
-Variant MID Code - -The MID code of the product variant - -No -
-Variant Material - -The material of the product variant - -No -
- -#### Prices columns - - - - - - - - - - - - - - - - - - - - - - - - - -
-Column name - -Description - -Is required? -
-Price (region name) - -The price amount for a particular region, where (region name) is the name of the region. - -No -
-Price (currency code) - -The price amount for a particular currency, where (currency code) is the 3 character ISO code of the currency. For example, "Price USD". - -No -
- -#### Sales channel columns - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Column name - -Description - -Is required? -
-Sales Channel (number) Id - -The ID of the sales channel this product is available in, if it already exists. - -No -
-Sales Channel (number) Name - -The name of the sales channel this product is available in. To specify more than one sales channel, include a number in the name. For example, "Sales Channel 1 Name". - -No -
-Sales Channel (number) Description - -The description of the sales channel this product is available in. Make sure the column name has the same number as the corresponding sales channel name. - -No -
- -#### Product Category columns - -:::note - -The [product categories beta feature](../../../beta.md) must be enabled first. Otherwise, these columns will be ignored. - -::: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Column name - -Description - -Is required? -
-Product Category (number) Handle - -The handle of the product category this product belongs to. If you're specifying more than one product category, you must include a number in the column name. For example, "Product Category 1 Handle". If a product category with this handle doesn't exist, the product category will be ignored. - -No -
-Product Category (number) Name - -The name of the product category this product belongs to. Make sure to use the same number as that of the corresponding product category handle. - -No -
-Product Category (number) Description - -The description of the product category this product belongs to. Make sure to use the same number as that of the corresponding product category handle. - -No -
- -
+
+ Expected columns + + #### Product columns + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Column name + + Description + + Is required? +
+ Product Handle + + The handle of the product + + Yes +
+ Product Id + + The ID of the product + + No +
+ Product Title + + The title of the product + + No +
+ Product Subtitle + + The subtitle of the product + + No +
+ Product Description + + The description of the product + + No +
+ Product Status + + The status of the product. Its value can be `draft`, `proposed`, `published`, or `rejected`. + + No +
+ Product Thumbnail + + A URL to the thumbnail of the product + + No +
+ Image (number) Url + + A URL to a product image. To add more than one image, you can specify the image number in the column title. For example, "Image 1 Url". + + No +
+ Product Weight + + The weight of the product + + No +
+ Product Length + + The length of the product + + No +
+ Product Width + + The width of the product + + No +
+ Product Height + + The height of the product + + No +
+ Product HS Code + + The HS Code of the product + + No +
+ Product Origin Country + + The origin country of the product + + No +
+ Product MID Code + + The MID code of the product + + No +
+ Product Material + + The material of the product + + No +
+ Product Discountable + + A boolean value indicating whether the product is discountable. + + No +
+ Product External Id + + The external ID of the product. Useful if the product is being imported from another platform and you want to maintain the link to it. + + No +
+ Product Profile Name + + The name of the product's shipping profile. + + No +
+ Product Profile Type + + The type of the product's shipping profile. Its value can be `default`, `gift_card`, or `custom`. + + No +
+ + #### Product Collection columns + + :::note + + A product collection is only associated with the product if the handle provided exists. Otherwise, it's skipped. + + ::: + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Column name + + Description + + Is required? +
+ Product Collection Title + + The title of the product collection + + No +
+ Product Collection Handle + + The handle of the product collection + + No +
+ + #### Product Type columns + + + + + + + + + + + + + + + + + + + +
+ Column name + + Description + + Is required? +
+ Product Type + + The value of the product type + + No +
+ + #### Product Tag columns + + + + + + + + + + + + + + + + + + + +
+ Column name + + Description + + Is required? +
+ Product Tags + + A comma-separated list of product tags + + No +
+ + #### Product Option columns + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Column name + + Description + + Is required? +
+ "Option Name" or "Option (number) Name" + + The name of the product option. If you name the column "Option Name", it means only one option will be added, and there should be no duplicate column with the same name for another option. To add more than one option, use the "Option (number) Name" name. For example, "Option 1 Name". + + No +
+ "Option Value" or "Option (number) Value" + + The value of the product option. If you name the column "Option Value", it means only one option will be added, and there should be no duplicate column with the same name for another option. To add more than one option value, use the "Option (number) Value" name. For example, "Option 1 Value". The number of the value should correspond to the same option name number. + + No +
+ + #### Product Variant Columns + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Column name + + Description + + Is required? +
+ Variant Id + + The ID of the product variant + + No +
+ Variant Title + + The title of the product variant + + No +
+ Variant SKU + + The SKU of the product variant + + No +
+ Variant Barcode + + The barcode of the product variant + + No +
+ Variant Inventory Quantity + + The inventory quantity of the product variant + + No +
+ Variant Allow Backorder + + A boolean value indicating if the variant can be back-ordered. + + No +
+ Variant Manage Inventory + + A boolean value indicating if the variant's inventory can be managed. + + No +
+ Variant Weight + + The weight of the product variant + + No +
+ Variant Length + + The length of the product variant + + No +
+ Variant Width + + The width of the product variant + + No +
+ Variant Height + + The height of the product variant + + No +
+ Variant HS Code + + The HS Code of the product variant + + No +
+ Variant Origin Country + + The origin country of the product variant + + No +
+ Variant MID Code + + The MID code of the product variant + + No +
+ Variant Material + + The material of the product variant + + No +
+ + #### Prices columns + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Column name + + Description + + Is required? +
+ Price (region name) + + The price amount for a particular region, where (region name) is the name of the region. + + No +
+ Price (currency code) + + The price amount for a particular currency, where (currency code) is the 3 character ISO code of the currency. For example, "Price USD". + + No +
+ + #### Sales channel columns + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Column name + + Description + + Is required? +
+ Sales Channel (number) Id + + The ID of the sales channel this product is available in, if it already exists. + + No +
+ Sales Channel (number) Name + + The name of the sales channel this product is available in. To specify more than one sales channel, include a number in the name. For example, "Sales Channel 1 Name". + + No +
+ Sales Channel (number) Description + + The description of the sales channel this product is available in. Make sure the column name has the same number as the corresponding sales channel name. + + No +
+ + #### Product Category columns + + :::note + + The [product categories beta feature](../../../beta.md) must be enabled first. Otherwise, these columns will be ignored. + + ::: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Column name + + Description + + Is required? +
+ Product Category (number) Handle + + The handle of the product category this product belongs to. If you're specifying more than one product category, you must include a number in the column name. For example, "Product Category 1 Handle". If a product category with this handle doesn't exist, the product category will be ignored. + + No +
+ Product Category (number) Name + + The name of the product category this product belongs to. Make sure to use the same number as that of the corresponding product category handle. + + No +
+ Product Category (number) Description + + The description of the product category this product belongs to. Make sure to use the same number as that of the corresponding product category handle. + + No +
+ +
### JS Client @@ -871,66 +869,66 @@ The first step is to upload the CSV file that you want to import products. You can do that by sending the following request to the [Upload Files API Route](https://docs.medusajs.com/api/admin#uploads_postuploads): - + -```ts -medusa.admin.uploads.create(file) // file is an instance of File -.then(({ uploads }) => { - const key = uploads[0].key -}) -``` + ```ts + medusa.admin.uploads.create(file) // file is an instance of File + .then(({ uploads }) => { + const key = uploads[0].key + }) + ``` - - + + -```tsx -import { useAdminUploadFile } from "medusa-react" + ```tsx + import { useAdminUploadFile } from "medusa-react" -const ImportProducts = () => { - const uploadFile = useAdminUploadFile() - // ... + const ImportProducts = () => { + const uploadFile = useAdminUploadFile() + // ... - const handleFileUpload = (file: File) => { - uploadFile.mutate(file) - } + const handleFileUpload = (file: File) => { + uploadFile.mutate(file) + } - // ... -} + // ... + } -export default ImportProducts -``` + export default ImportProducts + ``` - - + + -```ts -const formData = new FormData() -formData.append("files", file) // file is an instance of File + ```ts + const formData = new FormData() + formData.append("files", file) // file is an instance of File -fetch(`/admin/uploads`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "multipart/form-data", - }, - body: formData, -}) -.then((response) => response.json()) -.then(({ uploads }) => { - const key = uploads[0].key -}) -``` + fetch(`/admin/uploads`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "multipart/form-data", + }, + body: formData, + }) + .then((response) => response.json()) + .then(({ uploads }) => { + const key = uploads[0].key + }) + ``` - - + + -```bash -curl -L -X POST '/admin/uploads' \ - -H 'Authorization: Bearer ' \ - -F 'files=@""' -``` + ```bash + curl -L -X POST '/admin/uploads' \ + -H 'Authorization: Bearer ' \ + -F 'files=@""' + ``` - + This request returns an array of uploads. Each item in the array is an object that includes the properties `url` and `key`. You’ll need the `key` to import the products next. @@ -946,89 +944,89 @@ To start a new product import, you must create a batch job. You can do that by sending the following request to the [Create a Batch Job API Route](https://docs.medusajs.com/api/admin#batch-jobs_postbatchjobs): - + -```ts -medusa.admin.batchJobs.create({ - type: "product-import", - context: { - fileKey: key, // obtained from previous step - }, - dry_run: true, -}) -.then(( batch_job ) => { - console.log(batch_job.status) -}) -``` - - - - -```tsx -import { useAdminCreateBatchJob } from "medusa-react" - -const ImportProducts = () => { - const createBatchJob = useAdminCreateBatchJob() - // ... - - const handleCreateBatchJob = () => { - createBatchJob.mutate({ + ```ts + medusa.admin.batchJobs.create({ type: "product-import", context: { fileKey: key, // obtained from previous step }, dry_run: true, }) - } + .then(( batch_job ) => { + console.log(batch_job.status) + }) + ``` - // ... -} + + -export default ImportProducts -``` + ```tsx + import { useAdminCreateBatchJob } from "medusa-react" - - + const ImportProducts = () => { + const createBatchJob = useAdminCreateBatchJob() + // ... -```ts -fetch(`/admin/batch-jobs`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - type: "product-import", - context: { - fileKey: key, // obtained from previous step - }, - dry_run: true, - }), -}) -.then((response) => response.json()) -.then(({ batch_job }) => { - console.log(batch_job.status) -}) -``` + const handleCreateBatchJob = () => { + createBatchJob.mutate({ + type: "product-import", + context: { + fileKey: key, // obtained from previous step + }, + dry_run: true, + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/batch-jobs' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "type": "product-import", - "context": { - "fileKey": "" - }, - "dry_run": true -}' -# is the key you obtained from the previous step -``` + export default ImportProducts + ``` - + + + + ```ts + fetch(`/admin/batch-jobs`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + type: "product-import", + context: { + fileKey: key, // obtained from previous step + }, + dry_run: true, + }), + }) + .then((response) => response.json()) + .then(({ batch_job }) => { + console.log(batch_job.status) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/batch-jobs' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "type": "product-import", + "context": { + "fileKey": "" + }, + "dry_run": true + }' + # is the key you obtained from the previous step + ``` + + In the body of the request, you must pass the following parameters: @@ -1054,65 +1052,65 @@ After creating the batch job, it will be pre-processed. At this point, the CSV f You can retrieve all the details of the batch job, including its status and the brief statistics related to the products by sending the following request: - + -```ts -medusa.admin.batchJobs.retrieve(batchJobId) -.then(( batch_job ) => { - console.log(batch_job.status, batch_job.result) -}) -``` + ```ts + medusa.admin.batchJobs.retrieve(batchJobId) + .then(( batch_job ) => { + console.log(batch_job.status, batch_job.result) + }) + ``` - - + + -```tsx -import { useAdminBatchJob } from "medusa-react" + ```tsx + import { useAdminBatchJob } from "medusa-react" -const ImportProducts = () => { - const { batch_job, isLoading } = useAdminBatchJob(batchJobId) - // ... + const ImportProducts = () => { + const { batch_job, isLoading } = useAdminBatchJob(batchJobId) + // ... - return ( -
- {/* ... */} - {isLoading && Loading} - {batch_job && ( - - Status: {batch_job.status}. - Number of Products: {batch_job.result.count} - - )} -
- ) -} + return ( +
+ {/* ... */} + {isLoading && Loading} + {batch_job && ( + + Status: {batch_job.status}. + Number of Products: {batch_job.result.count} + + )} +
+ ) + } -export default ImportProducts -``` + export default ImportProducts + ``` -
- + + -```ts -fetch(`/admin/batch-jobs/${batchJobId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ batch_job }) => { - console.log(batch_job.status, batch_job.result) -}) -``` + ```ts + fetch(`/admin/batch-jobs/${batchJobId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ batch_job }) => { + console.log(batch_job.status, batch_job.result) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/batch-jobs/' \ --H 'Authorization: Bearer ' -# is the ID of the batch job -``` + ```bash + curl -L -X GET '/admin/batch-jobs/' \ + -H 'Authorization: Bearer ' + # is the ID of the batch job + ``` - +
This request accepts the batch job’s ID as a parameter, which can be retrieved from the previous request. It returns the batch job in the response. @@ -1144,59 +1142,59 @@ A batch job can be confirmed only once the batch job has the status `pre_process To confirm a batch job send the following request: - + -```ts -medusa.admin.batchJobs.confirm(batchJobId) -.then(( batch_job ) => { - console.log(batch_job.status) -}) -``` + ```ts + medusa.admin.batchJobs.confirm(batchJobId) + .then(( batch_job ) => { + console.log(batch_job.status) + }) + ``` - - + + -```tsx -import { useAdminConfirmBatchJob } from "medusa-react" + ```tsx + import { useAdminConfirmBatchJob } from "medusa-react" -const ImportProducts = () => { - const confirmBatchJob = useAdminConfirmBatchJob(batchJobId) - // ... + const ImportProducts = () => { + const confirmBatchJob = useAdminConfirmBatchJob(batchJobId) + // ... - const handleConfirmJob = () => { - confirmBatchJob.mutate() - } - - // ... -} + const handleConfirmJob = () => { + confirmBatchJob.mutate() + } + + // ... + } -export default ImportProducts -``` + export default ImportProducts + ``` - - + + -```ts -fetch(`/admin/batch-jobs/${batchJobId}/confirm`, { - method: "POST", - credentials: "include", -}) -.then((response) => response.json()) -.then(({ batch_job }) => { - console.log(batch_job.status) -}) -``` + ```ts + fetch(`/admin/batch-jobs/${batchJobId}/confirm`, { + method: "POST", + credentials: "include", + }) + .then((response) => response.json()) + .then(({ batch_job }) => { + console.log(batch_job.status) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/batch-jobs//confirm' \ --H 'Authorization: Bearer ' -# is the ID of the batch job -``` + ```bash + curl -L -X POST '/admin/batch-jobs//confirm' \ + -H 'Authorization: Bearer ' + # is the ID of the batch job + ``` - + This request accepts the ID of the batch job as a path parameter and returns the updated batch job. The returned batch job should have the status `confirmed`, which indicates that the batch job will now start processing. diff --git a/www/apps/docs/content/modules/products/admin/manage-categories.mdx b/www/apps/docs/content/modules/products/admin/manage-categories.mdx index 48875ae456..a9745b63d8 100644 --- a/www/apps/docs/content/modules/products/admin/manage-categories.mdx +++ b/www/apps/docs/content/modules/products/admin/manage-categories.mdx @@ -54,73 +54,73 @@ You can learn more about [authenticating as an admin user in the API reference]( You can retrieve available categories by sending a request to the [List Categories API Route](https://docs.medusajs.com/api/admin#product-categories_getproductcategories): - + -```ts -medusa.admin.productCategories.list() -.then(({ product_categories, limit, offset, count }) => { - console.log(product_categories.length) - // display categories -}) -``` + ```ts + medusa.admin.productCategories.list() + .then(({ product_categories, limit, offset, count }) => { + console.log(product_categories.length) + // display categories + }) + ``` - - + + -```tsx -import { useAdminProductCategories } from "medusa-react" -import { ProductCategory } from "@medusajs/medusa" + ```tsx + import { useAdminProductCategories } from "medusa-react" + import { ProductCategory } from "@medusajs/medusa" -function Categories() { - const { - product_categories, - isLoading } = useAdminProductCategories() + function Categories() { + const { + product_categories, + isLoading } = useAdminProductCategories() - return ( -
- {isLoading && Loading...} - {product_categories && !product_categories.length && ( - No Categories - )} - {product_categories && product_categories.length > 0 && ( -
    - {product_categories.map( - (category: ProductCategory) => ( -
  • {category.name}
  • - ) + return ( +
    + {isLoading && Loading...} + {product_categories && !product_categories.length && ( + No Categories )} -
- )} -
- ) -} + {product_categories && product_categories.length > 0 && ( +
    + {product_categories.map( + (category: ProductCategory) => ( +
  • {category.name}
  • + ) + )} +
+ )} + + ) + } -export default Categories -``` + export default Categories + ``` -
- + + -```ts -fetch(`/admin/product-categories`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ product_categories, limit, offset, count }) => { - console.log(product_categories.length) - // display product categories -}) -``` + ```ts + fetch(`/admin/product-categories`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ product_categories, limit, offset, count }) => { + console.log(product_categories.length) + // display product categories + }) + ``` - - + + -```bash -curl -L -X GET '/admin/product-categories' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/product-categories' \ + -H 'Authorization: Bearer ' + ``` - +
This request returns an array of product categories, as well as [pagination fields](https://docs.medusajs.com/api/admin#pagination). @@ -134,72 +134,72 @@ You can also pass filters and other selection query parameters to the request. C You can create a category by sending a request to the [Create a Category API Route](https://docs.medusajs.com/api/admin#product-categories_postproductcategories): - + -```ts -medusa.admin.productCategories.create({ - name: "Skinny Jeans", -}) -.then(({ product_category }) => { - console.log(product_category.id) -}) -``` - - - - -```tsx -import { useAdminCreateProductCategory } from "medusa-react" - -const CreateCategory = () => { - const createCategory = useAdminCreateProductCategory() - // ... - - const handleCreate = () => { - createCategory.mutate({ + ```ts + medusa.admin.productCategories.create({ name: "Skinny Jeans", }) - } + .then(({ product_category }) => { + console.log(product_category.id) + }) + ``` - // ... -} + + -export default CreateCategory -``` + ```tsx + import { useAdminCreateProductCategory } from "medusa-react" - - + const CreateCategory = () => { + const createCategory = useAdminCreateProductCategory() + // ... -```ts -fetch(`/admin/product-categories`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - name: "Skinny Jeans", - }), -}) -.then((response) => response.json()) -.then(({ product_category }) => { - console.log(product_category.id) -}) -``` + const handleCreate = () => { + createCategory.mutate({ + name: "Skinny Jeans", + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/product-categories' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "name": "Skinny Jeans" -}' -``` + export default CreateCategory + ``` - + + + + ```ts + fetch(`/admin/product-categories`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + name: "Skinny Jeans", + }), + }) + .then((response) => response.json()) + .then(({ product_category }) => { + console.log(product_category.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/product-categories' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "name": "Skinny Jeans" + }' + ``` + + This request requires one body parameter `name`, which is the name of the category. The request also accepts the following optional body parameters: @@ -218,63 +218,63 @@ The request returns the newly created product category. You can retrieve a product category by sending a request to the [Get a Product Category API Route](https://docs.medusajs.com/api/admin#product-categories_getproductcategoriescategory): - + -```ts -medusa.admin.productCategories.retrieve(productCategoryId) -.then(({ product_category }) => { - console.log(product_category.id) -}) -``` + ```ts + medusa.admin.productCategories.retrieve(productCategoryId) + .then(({ product_category }) => { + console.log(product_category.id) + }) + ``` - - + + -```tsx -import { useAdminProductCategory } from "medusa-react" + ```tsx + import { useAdminProductCategory } from "medusa-react" -const Category = () => { - const { - product_category, - isLoading, - } = useAdminProductCategory(productCategoryId) - - return ( -
- {isLoading && Loading...} - {product_category && {product_category.name}} - -
- ) -} + const Category = () => { + const { + product_category, + isLoading, + } = useAdminProductCategory(productCategoryId) + + return ( +
+ {isLoading && Loading...} + {product_category && {product_category.name}} + +
+ ) + } -export default Category -``` + export default Category + ``` -
- + + -```ts -fetch(`/admin/product-categories/${productCategoryId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ product_category }) => { - console.log(product_category.id) -}) -``` + ```ts + fetch(`/admin/product-categories/${productCategoryId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ product_category }) => { + console.log(product_category.id) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/product-categories/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/product-categories/' \ + -H 'Authorization: Bearer ' + ``` - +
This request requires the ID of the category to be passed as a path parameter. @@ -288,76 +288,76 @@ It returns the full object of the product category. You can edit a product category by sending a request to the [Update a Product Category API Route](https://docs.medusajs.com/api/admin#product-categories_postproductcategoriescategory): - + -```ts -medusa.admin.productCategories.update(productCategoryId, { - name: "Skinny Jeans", -}) -.then(({ product_category }) => { - console.log(product_category.id) -}) -``` - - - - -```tsx -import { useAdminUpdateProductCategory } from "medusa-react" - -const UpdateCategory = () => { - const updateCategory = useAdminUpdateProductCategory( - productCategoryId - ) - // ... - - const handleUpdate = () => { - updateCategory.mutate({ - name: "Skinny Jeans", + ```ts + medusa.admin.productCategories.update(productCategoryId, { + name: "Skinny Jeans", }) - } + .then(({ product_category }) => { + console.log(product_category.id) + }) + ``` - // ... -} + + -export default UpdateCategory -``` + ```tsx + import { useAdminUpdateProductCategory } from "medusa-react" - - + const UpdateCategory = () => { + const updateCategory = useAdminUpdateProductCategory( + productCategoryId + ) + // ... + + const handleUpdate = () => { + updateCategory.mutate({ + name: "Skinny Jeans", + }) + } + + // ... + } + + export default UpdateCategory + ``` + + + -```ts -fetch(`/admin/product-categories/${productCategoryId}`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - name: "Skinny Jeans", - }), - }) - .then((response) => response.json()) - .then(({ product_category }) => { - console.log(product_category.id) - }) -``` + ```ts + fetch(`/admin/product-categories/${productCategoryId}`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + name: "Skinny Jeans", + }), + }) + .then((response) => response.json()) + .then(({ product_category }) => { + console.log(product_category.id) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/product-categories/' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "name": "Skinny Jeans", -}' -``` + ```bash + curl -L -X POST '/admin/product-categories/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "name": "Skinny Jeans", + }' + ``` - + This request requires the ID of the category to be passed as a path parameter. @@ -383,38 +383,10 @@ You can manage the categories of each product individually using the [product AP You can add more than one product to a category using the [Add Products to a Category API Route](https://docs.medusajs.com/api/admin#product-categories_postproductcategoriescategoryproductsbatch): - + -```ts -medusa.admin.productCategories.addProducts(productCategoryId, { - product_ids: [ - { - id: productId1, - }, - { - id: productId2, - }, - ], -}) -.then(({ product_category }) => { - console.log(product_category.id) -}) -``` - - - - -```tsx -import { useAdminAddProductsToCategory } from "medusa-react" - -const UpdateProductsInCategory = () => { - const addProductsToCategory = useAdminAddProductsToCategory( - productCategoryId - ) - // ... - - const handleAdd = () => { - addProductsToCategory.mutate({ + ```ts + medusa.admin.productCategories.addProducts(productCategoryId, { product_ids: [ { id: productId1, @@ -424,63 +396,91 @@ const UpdateProductsInCategory = () => { }, ], }) - } + .then(({ product_category }) => { + console.log(product_category.id) + }) + ``` - // ... -} + + -export default UpdateProductsInCategory -``` + ```tsx + import { useAdminAddProductsToCategory } from "medusa-react" - - + const UpdateProductsInCategory = () => { + const addProductsToCategory = useAdminAddProductsToCategory( + productCategoryId + ) + // ... + + const handleAdd = () => { + addProductsToCategory.mutate({ + product_ids: [ + { + id: productId1, + }, + { + id: productId2, + }, + ], + }) + } + + // ... + } + + export default UpdateProductsInCategory + ``` + + + -```ts -fetch(`/admin/product-categories/${productCategoryId}/products/batch`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - product_ids: [ - { - id: productId1, + ```ts + fetch(`/admin/product-categories/${productCategoryId}/products/batch`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", }, - { - id: productId2, - }, - ], - }), -}) -.then((response) => response.json()) -.then(({ product_category }) => { - console.log(product_category.id) -}) -``` + body: JSON.stringify({ + product_ids: [ + { + id: productId1, + }, + { + id: productId2, + }, + ], + }), + }) + .then((response) => response.json()) + .then(({ product_category }) => { + console.log(product_category.id) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/product-categories//products/batch' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "product_ids": [ - { - "id": "productId1" - }, - { - "id": "productId2" - } - ] -}' -``` + ```bash + curl -L -X POST '/admin/product-categories//products/batch' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "product_ids": [ + { + "id": "productId1" + }, + { + "id": "productId2" + } + ] + }' + ``` - + This request requires the ID of the category to be passed as a path parameter. @@ -494,108 +494,108 @@ The request returns the full object of the product category updated with the new You can remove products from a category by sending a request to the [Delete Products API Route](https://docs.medusajs.com/api/admin#product-categories_deleteproductcategoriescategoryproductsbatch): - + -```ts -medusa.admin.productCategories.removeProducts( - productCategoryId, - { - product_ids: [ + ```ts + medusa.admin.productCategories.removeProducts( + productCategoryId, { - id: productId1, - }, - { - id: productId2, - }, - ], - } -) -.then(({ product_category }) => { - console.log(product_category.id) -}) -``` - - - - -```tsx -import { - useAdminDeleteProductsFromCategory, -} from "medusa-react" - -const DeleteProductsFromCategory = () => { - const deleteProductsFromCategory = - useAdminDeleteProductsFromCategory(productCategoryId) - // ... - - const handleDelete = () => { - deleteProductsFromCategory.mutate({ - product_ids: [ - { - id: productId1, - }, - { - id: productId2, - }, - ], + product_ids: [ + { + id: productId1, + }, + { + id: productId2, + }, + ], + } + ) + .then(({ product_category }) => { + console.log(product_category.id) }) - } + ``` - // ... -} + + -export default DeleteProductsFromCategory -``` + ```tsx + import { + useAdminDeleteProductsFromCategory, + } from "medusa-react" - - + const DeleteProductsFromCategory = () => { + const deleteProductsFromCategory = + useAdminDeleteProductsFromCategory(productCategoryId) + // ... + + const handleDelete = () => { + deleteProductsFromCategory.mutate({ + product_ids: [ + { + id: productId1, + }, + { + id: productId2, + }, + ], + }) + } + + // ... + } + + export default DeleteProductsFromCategory + ``` + + + -```ts -fetch(`/admin/product-categories/${productCategoryId}/products/batch`, { - credentials: "include", - method: "DELETE", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - product_ids: [ - { - id: productId1, + ```ts + fetch(`/admin/product-categories/${productCategoryId}/products/batch`, { + credentials: "include", + method: "DELETE", + headers: { + "Content-Type": "application/json", }, - { - id: productId2, - }, - ], - }), -}) -.then((response) => response.json()) -.then(({ product_category }) => { - console.log(product_category.id) -}) -``` + body: JSON.stringify({ + product_ids: [ + { + id: productId1, + }, + { + id: productId2, + }, + ], + }), + }) + .then((response) => response.json()) + .then(({ product_category }) => { + console.log(product_category.id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/product-categories//products/batch' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "product_ids": [ - { - "id": "productId1" - }, - { - "id": "productId2" - } - ] -}' -``` + ```bash + curl -L -X DELETE '/admin/product-categories//products/batch' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "product_ids": [ + { + "id": "productId1" + }, + { + "id": "productId2" + } + ] + }' + ``` - + This request requires the ID of the category to be passed as a path parameter. @@ -611,62 +611,61 @@ The request returns the full object of the product category updated with the its You can delete a product category by sending a request to the [Delete a Product Category API Route](https://docs.medusajs.com/api/admin#product-categories_deleteproductcategoriescategory): - + -```ts -medusa.admin.productCategories.delete(productCategoryId) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + medusa.admin.productCategories.delete(productCategoryId) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```tsx -import { useAdminDeleteProductCategory } from "medusa-react" + ```tsx + import { useAdminDeleteProductCategory } from "medusa-react" -const Category = () => { - const deleteCategory = useAdminDeleteProductCategory( - productCategoryId - ) - // ... + const Category = () => { + const deleteCategory = useAdminDeleteProductCategory( + productCategoryId + ) + // ... - const handleDelete = () => { - deleteCategory.mutate() - } + const handleDelete = () => { + deleteCategory.mutate() + } - // ... -} + // ... + } -export default Category -``` + export default Category + ``` - - + + -```ts -fetch(`/admin/product-categories/${productCategoryId}`, { - credentials: "include", - method: "DELETE", -}) -.then((response) => response.json()) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + fetch(`/admin/product-categories/${productCategoryId}`, { + credentials: "include", + method: "DELETE", + }) + .then((response) => response.json()) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` + + - - + ```bash + curl -L -X DELETE '/admin/product-categories/' \ + -H 'Authorization: Bearer ' + ``` -```bash -curl -L -X DELETE '/admin/product-categories/' \ --H 'Authorization: Bearer ' -``` - - + This request requires the ID of the category to be passed as a path parameter. diff --git a/www/apps/docs/content/modules/products/admin/manage-products.mdx b/www/apps/docs/content/modules/products/admin/manage-products.mdx index 2954810623..ba0bdff372 100644 --- a/www/apps/docs/content/modules/products/admin/manage-products.mdx +++ b/www/apps/docs/content/modules/products/admin/manage-products.mdx @@ -55,64 +55,64 @@ You can learn more about [authenticating as an admin user in the API reference]( You can list products as an admin using the [List Products API Route](https://docs.medusajs.com/api/admin#products_getproducts): - + -```ts -medusa.admin.products.list() -.then(({ products, limit, offset, count }) => { - console.log(products.length) -}) -``` + ```ts + medusa.admin.products.list() + .then(({ products, limit, offset, count }) => { + console.log(products.length) + }) + ``` - - + + -```tsx -import { useAdminProducts } from "medusa-react" + ```tsx + import { useAdminProducts } from "medusa-react" -const Products = () => { - const { products, isLoading } = useAdminProducts() + const Products = () => { + const { products, isLoading } = useAdminProducts() - return ( -
- {isLoading && Loading...} - {products && !products.length && No Products} - {products && products.length > 0 && ( -
    - {products.map((product) => ( -
  • {product.title}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {products && !products.length && No Products} + {products && products.length > 0 && ( +
    + {products.map((product) => ( +
  • {product.title}
  • + ))} +
+ )} +
+ ) + } -export default Products -``` + export default Products + ``` -
- + + -```ts -fetch(`/admin/products`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ products, limit, offset, count }) => { - console.log(products.length) -}) -``` + ```ts + fetch(`/admin/products`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ products, limit, offset, count }) => { + console.log(products.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/products' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/products' \ + -H 'Authorization: Bearer ' + ``` - +
This API Route doesn't require any parameters. You can pass parameters to search and filter through the retrieved products. For example, you can pass the `q` parameter which searches through product titles, descriptions, and more. You can learn more about available parameters in the [API reference](https://docs.medusajs.com/api/admin#products_getproducts). @@ -128,72 +128,10 @@ The request returns an array of products along with [pagination parameters](http You can create a product by sending a request to the [Create a Product API Route](https://docs.medusajs.com/api/admin#products_postproducts): - + -```ts -medusa.admin.products.create({ - title: "Shirt", - is_giftcard: false, - discountable: true, - options: [ - { - title: "Color", - }, - { - title: "Size", - }, - ], - variants: [ - { - title: "White Small Shirt", - prices: [ - { - amount: 1000, - currency_code, - }, - ], - options: [ - { - value: "White", - }, - { - value: "Small", - }, - ], - }, - ], - collection_id, - categories: [ - { - id: categoryId, - }, - ], - type: { - value: typeValue, - }, - tags: [ - { - value: tagValue, - }, - ], -}) -.then(({ product }) => { - console.log(product.id) -}) -``` - - - - -```tsx -import { useAdminCreateProduct } from "medusa-react" - -const CreateProduct = () => { - const createProduct = useAdminCreateProduct() - // ... - - const handleCreate = () => { - createProduct.mutate({ + ```ts + medusa.admin.products.create({ title: "Shirt", is_giftcard: false, discountable: true, @@ -239,130 +177,192 @@ const CreateProduct = () => { }, ], }) - } + .then(({ product }) => { + console.log(product.id) + }) + ``` - // ... -} + + -export default CreateProduct -``` + ```tsx + import { useAdminCreateProduct } from "medusa-react" - - + const CreateProduct = () => { + const createProduct = useAdminCreateProduct() + // ... -```ts -fetch(`/admin/products`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - title: "Shirt", - options: [ - { - title: "Color", - }, - { - title: "Size", - }, - ], - variants: [ - { - title: "White Small Shirt", - prices: [ - { - amount: 1000, - currency_code, - }, - ], - options: [ - { - value: "White", - }, - { - value: "Small", - }, - ], - }, - ], - collection_id, - categories: [ - { - id: categoryId, - }, - ], - type: { - value: typeValue, - }, - tags: [ - { - value: tagValue, - }, - ], - }), -}) -.then((response) => response.json()) -.then(({ product }) => { - console.log(product.id) -}) -``` - - - - -```bash -curl -L -X POST '/admin/products' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "title": "Shirt 2", - "options": [ - { - "title": "Color" - }, - { - "title": "Size" - } - ], - "variants": [ - { - "title": "White Shirt", - "prices": [ + const handleCreate = () => { + createProduct.mutate({ + title: "Shirt", + is_giftcard: false, + discountable: true, + options: [ + { + title: "Color", + }, + { + title: "Size", + }, + ], + variants: [ + { + title: "White Small Shirt", + prices: [ { - "amount": 1000, - "currency_code": "USD" - } - ], - "options": [ + amount: 1000, + currency_code, + }, + ], + options: [ { - "value": "White" + value: "White", }, { - "value": "Small" - } - ] - } - ], + value: "Small", + }, + ], + }, + ], + collection_id, + categories: [ + { + id: categoryId, + }, + ], + type: { + value: typeValue, + }, + tags: [ + { + value: tagValue, + }, + ], + }) + } - "collection_id": "", - "categories": [ - { - "id": "" - } - ], - "type": { - "value": "" - }, - "tags": [ - { - "value": "" - } - ] -}' -``` + // ... + } - + export default CreateProduct + ``` + + + + + ```ts + fetch(`/admin/products`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + title: "Shirt", + options: [ + { + title: "Color", + }, + { + title: "Size", + }, + ], + variants: [ + { + title: "White Small Shirt", + prices: [ + { + amount: 1000, + currency_code, + }, + ], + options: [ + { + value: "White", + }, + { + value: "Small", + }, + ], + }, + ], + collection_id, + categories: [ + { + id: categoryId, + }, + ], + type: { + value: typeValue, + }, + tags: [ + { + value: tagValue, + }, + ], + }), + }) + .then((response) => response.json()) + .then(({ product }) => { + console.log(product.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/products' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "title": "Shirt 2", + "options": [ + { + "title": "Color" + }, + { + "title": "Size" + } + ], + "variants": [ + { + "title": "White Shirt", + "prices": [ + { + "amount": 1000, + "currency_code": "USD" + } + ], + "options": [ + { + "value": "White" + }, + { + "value": "Small" + } + ] + } + ], + + "collection_id": "", + "categories": [ + { + "id": "" + } + ], + "type": { + "value": "" + }, + "tags": [ + { + "value": "" + } + ] + }' + ``` + + This API Route only requires the `title` body parameter, which is the name of the product. Other parameters passed in the example are optional. They are: @@ -393,7 +393,7 @@ For currencies that are not zero-decimal, you must set the prices of product var So, in the example above, if the `amount` is set to `1000`, it means the price is actually `10`. -You can learn more about pricing and zero-decimal currencies [here](../products.md#storing-the-product-variants-price). +You can learn more about pricing and zero-decimal currencies [here](../products.mdx#storing-the-product-variants-price). --- @@ -402,61 +402,61 @@ You can learn more about pricing and zero-decimal currencies [here](../products. You can retrieve a single product as an admin by sending a request to the [Get a Product API Route](https://docs.medusajs.com/api/admin#products_getproductsproduct): - + -```ts -medusa.admin.products.retrieve(productId) -.then(({ product }) => { - console.log(product.id) -}) -``` + ```ts + medusa.admin.products.retrieve(productId) + .then(({ product }) => { + console.log(product.id) + }) + ``` - - + + -```tsx -import { useAdminProduct } from "medusa-react" + ```tsx + import { useAdminProduct } from "medusa-react" -const Product = () => { - const { - product, - isLoading, - } = useAdminProduct(productId) - - return ( -
- {isLoading && Loading...} - {product && {product.title}} - -
- ) -} + const Product = () => { + const { + product, + isLoading, + } = useAdminProduct(productId) + + return ( +
+ {isLoading && Loading...} + {product && {product.title}} + +
+ ) + } -export default Product -``` + export default Product + ``` -
- + + -```ts -fetch(`/admin/products/${productId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ product }) => { - console.log(product.id) -}) -``` + ```ts + fetch(`/admin/products/${productId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ product }) => { + console.log(product.id) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/products/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/products/' \ + -H 'Authorization: Bearer ' + ``` - +
This API Route requires the product ID to be passed as a path parameter. @@ -470,74 +470,74 @@ The request returns the product as an object. You can update a product by sending a request to the [Update Product API Route](https://docs.medusajs.com/api/admin#products_postproductsproduct): - + -```ts -medusa.admin.products.update(productId, { - title: "Shirt", -}) -.then(({ product }) => { - console.log(product.id) -}) -``` - - - - -```tsx -import { useAdminUpdateProduct } from "medusa-react" - -const UpdateProduct = () => { - const updateProduct = useAdminUpdateProduct( - productId - ) - // ... - - const handleUpdate = () => { - updateProduct.mutate({ + ```ts + medusa.admin.products.update(productId, { title: "Shirt", }) - } + .then(({ product }) => { + console.log(product.id) + }) + ``` - // ... -} + + -export default UpdateProduct -``` + ```tsx + import { useAdminUpdateProduct } from "medusa-react" - - + const UpdateProduct = () => { + const updateProduct = useAdminUpdateProduct( + productId + ) + // ... -```ts -fetch(`/admin/products/${productId}`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - title: "Shirt", - }), -}) -.then((response) => response.json()) -.then(({ product }) => { - console.log(product.id) -}) -``` + const handleUpdate = () => { + updateProduct.mutate({ + title: "Shirt", + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/products/' \ --H 'Authorization: Bearer ' \ ---header 'Content-Type: application/json' \ ---data-raw '{ - "title": "Shirt" -}' -``` + export default UpdateProduct + ``` - + + + + ```ts + fetch(`/admin/products/${productId}`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + title: "Shirt", + }), + }) + .then((response) => response.json()) + .then(({ product }) => { + console.log(product.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/products/' \ + -H 'Authorization: Bearer ' \ + --header 'Content-Type: application/json' \ + --data-raw '{ + "title": "Shirt" + }' + ``` + + This API Route requires the product ID as a path parameter. In the request’s body, you can pass any of the product’s fields to update. In the example above, you update the `title` of the product. @@ -561,74 +561,74 @@ You can retrieve a product’s options by retrieving the product either using th You can add a product option to a product by sending a request to the [Add Product Option API Route](https://docs.medusajs.com/api/admin#products_postproductsproductoptions): - + -```ts -medusa.admin.products.addOption(productId, { - title: "Size", -}) -.then(({ product }) => { - console.log(product.id) -}) -``` - - - - -```tsx -import { useAdminCreateProductOption } from "medusa-react" - -const CreateProductOption = () => { - const createOption = useAdminCreateProductOption( - productId - ) - // ... - - const handleCreate = () => { - createOption.mutate({ + ```ts + medusa.admin.products.addOption(productId, { title: "Size", }) - } + .then(({ product }) => { + console.log(product.id) + }) + ``` - // ... -} + + -export default CreateProductOption -``` + ```tsx + import { useAdminCreateProductOption } from "medusa-react" - - + const CreateProductOption = () => { + const createOption = useAdminCreateProductOption( + productId + ) + // ... -```ts -fetch(`/admin/products/${productId}/options`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - title: "Size", - }), -}) -.then((response) => response.json()) -.then(({ product }) => { - console.log(product.id) -}) -``` + const handleCreate = () => { + createOption.mutate({ + title: "Size", + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/products//options' \ --H 'Authorization: Bearer ' \ ---header 'Content-Type: application/json' \ ---data-raw '{ - "title": "Size" -}' -``` + export default CreateProductOption + ``` - + + + + ```ts + fetch(`/admin/products/${productId}/options`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + title: "Size", + }), + }) + .then((response) => response.json()) + .then(({ product }) => { + console.log(product.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/products//options' \ + -H 'Authorization: Bearer ' \ + --header 'Content-Type: application/json' \ + --data-raw '{ + "title": "Size" + }' + ``` + + This API Route requires the product’s ID as a path parameter. In the request body parameter, it requires passing the `title` of the option. @@ -640,77 +640,77 @@ The request returns the updated product as an option. You can view available opt You can update a product option by sending a request to the [Update Product Option API Route](https://docs.medusajs.com/api/admin#products_postproductsproductoptionsoption): - + -```ts -medusa.admin.products.updateOption(productId, optionId, { - title: "Size", -}) -.then(({ product }) => { - console.log(product.id) -}) -``` - - - - -```tsx -import { useAdminUpdateProductOption } from "medusa-react" - -const UpdateProductOption = () => { - const updateOption = useAdminUpdateProductOption( - productId - ) - // ... - - const handleUpdate = () => { - updateOption.mutate({ - option_id, + ```ts + medusa.admin.products.updateOption(productId, optionId, { title: "Size", }) - } + .then(({ product }) => { + console.log(product.id) + }) + ``` - // ... -} + + -export default UpdateProductOption -``` + ```tsx + import { useAdminUpdateProductOption } from "medusa-react" - - + const UpdateProductOption = () => { + const updateOption = useAdminUpdateProductOption( + productId + ) + // ... + + const handleUpdate = () => { + updateOption.mutate({ + option_id, + title: "Size", + }) + } + + // ... + } + + export default UpdateProductOption + ``` + + + -```ts -fetch(`/admin/products/${productId}/options/${optionId}`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - title: "Size", - }), -}) -.then((response) => response.json()) -.then(({ product }) => { - console.log(product.id) -}) -``` + ```ts + fetch(`/admin/products/${productId}/options/${optionId}`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + title: "Size", + }), + }) + .then((response) => response.json()) + .then(({ product }) => { + console.log(product.id) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/products//options/' \ --H 'Authorization: Bearer ' \ ---header 'Content-Type: application/json' \ ---data-raw '{ - "title": "Size" -}' -``` + ```bash + curl -L -X POST '/admin/products//options/' \ + -H 'Authorization: Bearer ' \ + --header 'Content-Type: application/json' \ + --data-raw '{ + "title": "Size" + }' + ``` - + This API Route requires the product’s ID and the product option’s ID to be passed as a path parameter. @@ -724,62 +724,62 @@ The request returns the updated product as an option. You can view available opt You can delete a product option by sending a request to the [Delete Product Option API Route](https://docs.medusajs.com/api/admin#products_deleteproductsproductoptionsoption): - + -```ts -medusa.admin.products.deleteOption(productId, optionId) -.then(({ option_id, object, deleted, product }) => { - console.log(product.options) -}) -``` + ```ts + medusa.admin.products.deleteOption(productId, optionId) + .then(({ option_id, object, deleted, product }) => { + console.log(product.options) + }) + ``` - - + + -```tsx -import { useAdminDeleteProductOption } from "medusa-react" + ```tsx + import { useAdminDeleteProductOption } from "medusa-react" -const DeleteProductOption = () => { - const deleteOption = useAdminDeleteProductOption( - productId - ) - // ... + const DeleteProductOption = () => { + const deleteOption = useAdminDeleteProductOption( + productId + ) + // ... - const handleDelete = () => { - deleteOption.mutate(option_id) - } + const handleDelete = () => { + deleteOption.mutate(option_id) + } - // ... -} + // ... + } -export default DeleteProductOption -``` + export default DeleteProductOption + ``` - - + + -```ts -fetch(`/admin/products/${productId}/options/${optionId}`, { - credentials: "include", - method: "DELETE", -}) -.then((response) => response.json()) -.then(({ option_id, object, deleted, product }) => { - console.log(product.options) -}) -``` + ```ts + fetch(`/admin/products/${productId}/options/${optionId}`, { + credentials: "include", + method: "DELETE", + }) + .then((response) => response.json()) + .then(({ option_id, object, deleted, product }) => { + console.log(product.options) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/products//options/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/products//options/' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the product’s ID and the product option’s ID to be passed as a path parameter. @@ -806,43 +806,10 @@ You can retrieve a product’s variants by retrieving the product either using t You can create a product variant by sending a request to the [Create Product Variant API Route](https://docs.medusajs.com/api/admin#products_postproductsproductvariants): - + -```ts -medusa.admin.products.createVariant(product_id, { - title: "White Shirt", - prices: [ - { - amount: 1000, - currency_code: "USD", - }, - ], - options: [ - { - option_id, - value: "White", - }, - ], -}) -.then(({ product }) => { - console.log(product.id) -}) -``` - - - - -```tsx -import { useAdminCreateVariant } from "medusa-react" - -const CreateProductVariant = () => { - const createVariant = useAdminCreateVariant( - productId - ) - // ... - - const handleCreate = () => { - createVariant.mutate({ + ```ts + medusa.admin.products.createVariant(product_id, { title: "White Shirt", prices: [ { @@ -857,71 +824,104 @@ const CreateProductVariant = () => { }, ], }) - } + .then(({ product }) => { + console.log(product.id) + }) + ``` - // ... -} + + -export default CreateProductVariant -``` + ```tsx + import { useAdminCreateVariant } from "medusa-react" - - + const CreateProductVariant = () => { + const createVariant = useAdminCreateVariant( + productId + ) + // ... -```ts -fetch(`/admin/products/${productId}/variants`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - title: "White Shirt", - prices: [ - { - amount: 1000, - currency_code: "USD", - }, - ], - options: [ - { - option_id, - value: "White", - }, - ], - }), -}) -.then((response) => response.json()) -.then(({ product }) => { - console.log(product.id) -}) -``` + const handleCreate = () => { + createVariant.mutate({ + title: "White Shirt", + prices: [ + { + amount: 1000, + currency_code: "USD", + }, + ], + options: [ + { + option_id, + value: "White", + }, + ], + }) + } - - - -```bash -curl -L -X POST '/admin/products//variants' \ --H 'Authorization: Bearer ' \ ---header 'Content-Type: application/json' \ ---data-raw '{ - "title": "White Shirt", - "prices": [ - { - "amount": 1000, - "currency_code": "USD" + // ... } - ], - "options": [ - { - "option_id": "", - "value": "White" - } - ] -}' -``` - + export default CreateProductVariant + ``` + + + + + ```ts + fetch(`/admin/products/${productId}/variants`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + title: "White Shirt", + prices: [ + { + amount: 1000, + currency_code: "USD", + }, + ], + options: [ + { + option_id, + value: "White", + }, + ], + }), + }) + .then((response) => response.json()) + .then(({ product }) => { + console.log(product.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/products//variants' \ + -H 'Authorization: Bearer ' \ + --header 'Content-Type: application/json' \ + --data-raw '{ + "title": "White Shirt", + "prices": [ + { + "amount": 1000, + "currency_code": "USD" + } + ], + "options": [ + { + "option_id": "", + "value": "White" + } + ] + }' + ``` + + This API Route requires the ID of the product as a path parameter. In the request body parameters, the following parameters are required: @@ -941,77 +941,77 @@ The request returns the updated product. You can access the product’s variants You can update a product variant by sending a request to the [Update a Product Variant API Route](https://docs.medusajs.com/api/admin#products_postproductsproductvariantsvariant): - + -```ts -medusa.admin.products.updateVariant(productId, variantId, { - title: "White Shirt", -}) -.then(({ product }) => { - console.log(product.id) -}) -``` - - - - -```tsx -import { useAdminUpdateVariant } from "medusa-react" - -const UpdateProductVariant = () => { - const updateVariant = useAdminUpdateVariant( - productId - ) - // ... - - const handleUpdate = () => { - updateVariant.mutate({ - variant_id, + ```ts + medusa.admin.products.updateVariant(productId, variantId, { title: "White Shirt", }) - } + .then(({ product }) => { + console.log(product.id) + }) + ``` - // ... -} + + -export default UpdateProductVariant -``` + ```tsx + import { useAdminUpdateVariant } from "medusa-react" - - + const UpdateProductVariant = () => { + const updateVariant = useAdminUpdateVariant( + productId + ) + // ... + + const handleUpdate = () => { + updateVariant.mutate({ + variant_id, + title: "White Shirt", + }) + } + + // ... + } + + export default UpdateProductVariant + ``` + + + -```ts -fetch(`/admin/products/${productId}/variants/${variantId}`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - title: "White Shirt", - }), -}) -.then((response) => response.json()) -.then(({ product }) => { - console.log(product.id) -}) -``` + ```ts + fetch(`/admin/products/${productId}/variants/${variantId}`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + title: "White Shirt", + }), + }) + .then((response) => response.json()) + .then(({ product }) => { + console.log(product.id) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/products//variants/' \ --H 'Authorization: Bearer ' \ ---header 'Content-Type: application/json' \ ---data-raw '{ - "title": "White Shirt" -}' -``` + ```bash + curl -L -X POST '/admin/products//variants/' \ + -H 'Authorization: Bearer ' \ + --header 'Content-Type: application/json' \ + --data-raw '{ + "title": "White Shirt" + }' + ``` - + This API Route requires the product ID and variant ID to be passed as a path parameter. @@ -1025,62 +1025,62 @@ The request returns the updated product. You can access the product’s variants You can delete a product variant by sending a request to the [Delete a Product Variant API Route](https://docs.medusajs.com/api/admin#products_deleteproductsproductvariantsvariant): - + -```ts -medusa.admin.products.deleteVariant(productId, variantId) -.then(({ variant_id, object, deleted, product }) => { - console.log(product.id) -}) -``` + ```ts + medusa.admin.products.deleteVariant(productId, variantId) + .then(({ variant_id, object, deleted, product }) => { + console.log(product.id) + }) + ``` - - + + -```tsx -import { useAdminDeleteVariant } from "medusa-react" + ```tsx + import { useAdminDeleteVariant } from "medusa-react" -const DeleteProductVariant = () => { - const deleteVariant = useAdminDeleteVariant( - productId - ) - // ... + const DeleteProductVariant = () => { + const deleteVariant = useAdminDeleteVariant( + productId + ) + // ... - const handleDelete = () => { - deleteVariant.mutate(variant_id) - } + const handleDelete = () => { + deleteVariant.mutate(variant_id) + } - // ... -} + // ... + } -export default DeleteProductVariant -``` + export default DeleteProductVariant + ``` - - + + -```ts -fetch(`/admin/products/${productId}/variants/${variantId}`, { - credentials: "include", - method: "DELETE", -}) -.then((response) => response.json()) -.then(({ variant_id, object, deleted, product }) => { - console.log(product.id) -}) -``` + ```ts + fetch(`/admin/products/${productId}/variants/${variantId}`, { + credentials: "include", + method: "DELETE", + }) + .then((response) => response.json()) + .then(({ variant_id, object, deleted, product }) => { + console.log(product.id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/products//variants/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/products//variants/' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the product ID and variant ID to be passed as a path parameter. @@ -1099,60 +1099,60 @@ The request returns the following fields: You can delete a product by sending a request to the [Delete a Product API Route](https://docs.medusajs.com/api/admin#products_deleteproductsproduct): - + -```ts -medusa.admin.products.delete(productId) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + medusa.admin.products.delete(productId) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```tsx -import { useAdminDeleteProduct } from "medusa-react" + ```tsx + import { useAdminDeleteProduct } from "medusa-react" -const DeleteProduct = () => { - const deleteProduct = useAdminDeleteProduct( - productId - ) - // ... + const DeleteProduct = () => { + const deleteProduct = useAdminDeleteProduct( + productId + ) + // ... - const handleDelete = () => { - deleteProduct.mutate() - } + const handleDelete = () => { + deleteProduct.mutate() + } - // ... -} + // ... + } -export default DeleteProduct -``` + export default DeleteProduct + ``` - - + + -```ts -fetch(`/admin/products/${productId}`, { - credentials: "include", - method: "DELETE", -}) -.then((response) => response.json()) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + fetch(`/admin/products/${productId}`, { + credentials: "include", + method: "DELETE", + }) + .then((response) => response.json()) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/products/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/products/' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires passing the product ID as a path parameter. diff --git a/www/apps/docs/content/modules/products/products.md b/www/apps/docs/content/modules/products/products.mdx similarity index 99% rename from www/apps/docs/content/modules/products/products.md rename to www/apps/docs/content/modules/products/products.mdx index 18db956eed..0df8bb7e7c 100644 --- a/www/apps/docs/content/modules/products/products.md +++ b/www/apps/docs/content/modules/products/products.mdx @@ -111,8 +111,8 @@ For example, if a variant's price is 10 USD, it's stored is `1000`, as in 1,000 For zero-decimal currencies, the amount is still stored as an integer without multiplying by a 100. For example, if a variant's price is ¥500, it's stored as `500`. -
- Zero-decimal Currencies +
+ Zero-decimal Currencies - BIF - CLP @@ -131,7 +131,7 @@ For zero-decimal currencies, the amount is still stored as an integer without mu - XOF - XPF -
+
This logic of formatting the price is not handled in the backend. So, when you add a product variant using the Admin APIs, you must format the price as explained earlier. The backend stores the price as received from API requests. diff --git a/www/apps/docs/content/modules/products/serverless-module.md b/www/apps/docs/content/modules/products/serverless-module.mdx similarity index 99% rename from www/apps/docs/content/modules/products/serverless-module.md rename to www/apps/docs/content/modules/products/serverless-module.mdx index 8ab08666e0..fc5a321672 100644 --- a/www/apps/docs/content/modules/products/serverless-module.md +++ b/www/apps/docs/content/modules/products/serverless-module.mdx @@ -100,8 +100,8 @@ Migrations are used to create your database schema. Before you can run migration The first command runs the migrations, and the second command allows you to optionally seed your database with demo products. However, you’d need the following seed file added in the root of your Next.js directory: -
- Seed file +
+ Seed file ```js title=seed-data.js const productCategoriesData = [ @@ -194,7 +194,7 @@ The first command runs the migrations, and the second command allows you to opti } ``` -
+
Then run the first and optionally second commands to migrate the database schema: diff --git a/www/apps/docs/content/modules/products/storefront/show-products.mdx b/www/apps/docs/content/modules/products/storefront/show-products.mdx index a63835421f..585e2c2442 100644 --- a/www/apps/docs/content/modules/products/storefront/show-products.mdx +++ b/www/apps/docs/content/modules/products/storefront/show-products.mdx @@ -50,7 +50,7 @@ If you follow the Medusa React code blocks, it's assumed you already have [Medus This guide also includes code snippets to utilize the `@medusajs/product` module in your storefront, among other methods. -If you follow the `@medusajs/product` code blocks, it's assumed you already have the [@medusajs/product](../serverless-module.md) installed. +If you follow the `@medusajs/product` code blocks, it's assumed you already have the [@medusajs/product](../serverless-module.mdx) installed. --- @@ -59,88 +59,88 @@ If you follow the `@medusajs/product` code blocks, it's assumed you already have You can list available products using the [List Products API Route](https://docs.medusajs.com/api/store#products_getproducts): - + -```ts -medusa.products.list() -.then(({ products, limit, offset, count }) => { - console.log(products.length) -}) -``` + ```ts + medusa.products.list() + .then(({ products, limit, offset, count }) => { + console.log(products.length) + }) + ``` - - + + -```tsx -import { useProducts } from "medusa-react" + ```tsx + import { useProducts } from "medusa-react" -const Products = () => { - const { products, isLoading } = useProducts() + const Products = () => { + const { products, isLoading } = useProducts() - return ( -
- {isLoading && Loading...} - {products && !products.length && No Products} - {products && products.length > 0 && ( -
    - {products.map((product) => ( -
  • {product.title}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {products && !products.length && No Products} + {products && products.length > 0 && ( +
    + {products.map((product) => ( +
  • {product.title}
  • + ))} +
+ )} +
+ ) + } -export default Products -``` + export default Products + ``` -
- - @medusajs/product - beta - -)} attributes={{ - badge: true -}}> + + + @medusajs/product + beta + + )} attributes={{ + badge: true + }}> -```ts -import { - initialize as initializeProductModule, -} from "@medusajs/product" + ```ts + import { + initialize as initializeProductModule, + } from "@medusajs/product" -// in an async function, or you can use promises -async () => { - // ... - const productService = await initializeProductModule() - const products = await productService.list() + // in an async function, or you can use promises + async () => { + // ... + const productService = await initializeProductModule() + const products = await productService.list() - console.log(products.length) -} -``` + console.log(products.length) + } + ``` - - + + -```ts -fetch(`/store/products`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ products, limit, offset, count }) => { - console.log(products.length) -}) -``` + ```ts + fetch(`/store/products`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ products, limit, offset, count }) => { + console.log(products.length) + }) + ``` - - + + -```bash -curl -L -X GET '/store/products' -``` + ```bash + curl -L -X GET '/store/products' + ``` - +
This API Route doesn't require any parameters. You can pass it parameters related to pagination, filtering, and more as explained in the [API reference](https://docs.medusajs.com/api/store#tag/Products/operation/GetProducts). @@ -154,95 +154,95 @@ The List Products API Route accepts different query parameters that allow you to For example, you can filter products by a category ID: - + -```ts -medusa.products.list({ - category_id: ["cat_123"], -}) -.then(({ products, limit, offset, count }) => { - console.log(products.length) -}) -``` + ```ts + medusa.products.list({ + category_id: ["cat_123"], + }) + .then(({ products, limit, offset, count }) => { + console.log(products.length) + }) + ``` - - + + -```tsx -import { useProducts } from "medusa-react" -import { Product } from "@medusajs/medusa" + ```tsx + import { useProducts } from "medusa-react" + import { Product } from "@medusajs/medusa" -const Products = () => { - const { products, isLoading } = useProducts({ - category_id: ["cat_123"], - }) + const Products = () => { + const { products, isLoading } = useProducts({ + category_id: ["cat_123"], + }) - return ( -
- {isLoading && Loading...} - {products && !products.length && No Products} - {products && products.length > 0 && ( -
    - {products.map((product: Product) => ( -
  • {product.title}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {products && !products.length && No Products} + {products && products.length > 0 && ( +
    + {products.map((product: Product) => ( +
  • {product.title}
  • + ))} +
+ )} +
+ ) + } -export default Products -``` + export default Products + ``` -
- - @medusajs/product - beta - -)} attributes={{ - badge: true -}}> + + + @medusajs/product + beta + + )} attributes={{ + badge: true + }}> -```ts -import { - initialize as initializeProductModule, -} from "@medusajs/product" + ```ts + import { + initialize as initializeProductModule, + } from "@medusajs/product" -// in an async function, or you can use promises -async () => { - // ... - const productService = await initializeProductModule() - const products = await productService.list({ - category_ids: ["cat_123"], - }) + // in an async function, or you can use promises + async () => { + // ... + const productService = await initializeProductModule() + const products = await productService.list({ + category_ids: ["cat_123"], + }) - console.log(products) -} -``` + console.log(products) + } + ``` - - + + -```ts -fetch(`/store/products?category_id[]=cat_123`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ products, limit, offset, count }) => { - console.log(products.length) -}) -``` + ```ts + fetch(`/store/products?category_id[]=cat_123`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ products, limit, offset, count }) => { + console.log(products.length) + }) + ``` - - + + -```bash -curl -L -X GET '/store/products?category_id[]=cat_123' -``` + ```bash + curl -L -X GET '/store/products?category_id[]=cat_123' + ``` - +
This will retrieve only products that belong to that category. @@ -252,95 +252,95 @@ This will retrieve only products that belong to that category. To expand the categories of each product, you can pass `categories` to the `expand` query parameter: - + -```ts -medusa.products.list({ - expand: "categories", -}) -.then(({ products, limit, offset, count }) => { - console.log(products.length) -}) -``` + ```ts + medusa.products.list({ + expand: "categories", + }) + .then(({ products, limit, offset, count }) => { + console.log(products.length) + }) + ``` - - + + -```tsx -import { useProducts } from "medusa-react" -import { Product } from "@medusajs/medusa" + ```tsx + import { useProducts } from "medusa-react" + import { Product } from "@medusajs/medusa" -const Products = () => { - const { products, isLoading } = useProducts({ - expand: "categories", - }) + const Products = () => { + const { products, isLoading } = useProducts({ + expand: "categories", + }) - return ( -
- {isLoading && Loading...} - {products && !products.length && No Products} - {products && products.length > 0 && ( -
    - {products.map((product: Product) => ( -
  • {product.title}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {products && !products.length && No Products} + {products && products.length > 0 && ( +
    + {products.map((product: Product) => ( +
  • {product.title}
  • + ))} +
+ )} +
+ ) + } -export default Products -``` + export default Products + ``` -
- - @medusajs/product - beta - -)} attributes={{ - badge: true -}}> + + + @medusajs/product + beta + + )} attributes={{ + badge: true + }}> -```ts -import { - initialize as initializeProductModule, -} from "@medusajs/product" + ```ts + import { + initialize as initializeProductModule, + } from "@medusajs/product" -// in an async function, or you can use promises -async () => { - // ... - const productService = await initializeProductModule() - const products = await productService.list({}, { - relations: ["categories"], - }) + // in an async function, or you can use promises + async () => { + // ... + const productService = await initializeProductModule() + const products = await productService.list({}, { + relations: ["categories"], + }) - console.log(products) -} -``` + console.log(products) + } + ``` - - + + -```ts -fetch(`/store/products?expand=categories`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ products, limit, offset, count }) => { - console.log(products.length) -}) -``` + ```ts + fetch(`/store/products?expand=categories`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ products, limit, offset, count }) => { + console.log(products.length) + }) + ``` - - + + -```bash -curl -L -X GET '/store/products?expand=categories' -``` + ```bash + curl -L -X GET '/store/products?expand=categories' + ``` - +
You can learn more about the [expand parameter in the API reference](https://docs.medusajs.com/api/store#section/Expanding-Fields) @@ -358,72 +358,72 @@ It’s recommended to always include the cart and region’s IDs when you’re l For example: - + -```ts -medusa.products.list({ - cart_id, - region_id, -}) -.then(({ products, limit, offset, count }) => { - console.log(products.length) -}) -``` + ```ts + medusa.products.list({ + cart_id, + region_id, + }) + .then(({ products, limit, offset, count }) => { + console.log(products.length) + }) + ``` - - + + -```tsx -import { useProducts } from "medusa-react" -import { Product } from "@medusajs/medusa" + ```tsx + import { useProducts } from "medusa-react" + import { Product } from "@medusajs/medusa" -const Products = () => { - const { products, isLoading } = useProducts({ - cart_id, - region_id, - }) + const Products = () => { + const { products, isLoading } = useProducts({ + cart_id, + region_id, + }) - return ( -
- {isLoading && Loading...} - {products && !products.length && No Products} - {products && products.length > 0 && ( -
    - {products.map((product: Product) => ( -
  • {product.title}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {products && !products.length && No Products} + {products && products.length > 0 && ( +
    + {products.map((product: Product) => ( +
  • {product.title}
  • + ))} +
+ )} +
+ ) + } -export default Products -``` + export default Products + ``` -
- + + -```ts -fetch(`/store/products?cart_id=${cartId}®ion_id=${regionId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ products, limit, offset, count }) => { - console.log(products.length) -}) -``` + ```ts + fetch(`/store/products?cart_id=${cartId}®ion_id=${regionId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ products, limit, offset, count }) => { + console.log(products.length) + }) + ``` - - + + -```bash -curl -L -X GET '/store/products?cart_id=®ion_id=' -``` + ```bash + curl -L -X GET '/store/products?cart_id=®ion_id=' + ``` - +
### Display Product Price @@ -447,7 +447,7 @@ You must pass one of the [pricing parameters](#product-pricing-parameters) to th ::: -Prices in Medusa are stored as the currency's smallest unit. So, for currencies that are not zero-decimal, the amount is stored multiplied by a `100`. You can learn more about this in the [Product conceptual guide](../products.md#storing-the-product-variants-price). +Prices in Medusa are stored as the currency's smallest unit. So, for currencies that are not zero-decimal, the amount is stored multiplied by a `100`. You can learn more about this in the [Product conceptual guide](../products.mdx#storing-the-product-variants-price). So, to show the correct price, you would need to convert it to its actual price with a method like this: @@ -477,105 +477,105 @@ Medusa React provides utility methods such as `formatVariantPrice` that handles Here’s an example of how you can calculate the price with and without Medusa React: - + -```tsx -import React, { useEffect, useState } from "react" -import Medusa from "@medusajs/medusa-js" + ```tsx + import React, { useEffect, useState } from "react" + import Medusa from "@medusajs/medusa-js" -const medusa = new Medusa({ - baseUrl: "", - maxRetries: 3, -}) - -function Products() { - const [products, setProducts] = useState([]) - - useEffect(() => { - medusa.products.list({ - // TODO assuming region is already defined somewhere - region_id: region.id, + const medusa = new Medusa({ + baseUrl: "", + maxRetries: 3, }) - .then(({ products, limit, offset, count }) => { - // ignore pagination for sake of example - setProducts(products) - }) - }) - const convertToDecimal = (amount) => { - return Math.floor(amount) / 100 - } + function Products() { + const [products, setProducts] = useState([]) - const formatPrice = (amount) => { - return new Intl.NumberFormat("en-US", { - style: "currency", - // TODO assuming region is already defined somewhere - currency: region.currency_code, - }).format(convertToDecimal(amount)) - } - - return ( -
    - {products.map((product) => ( - <> - {product.variants.map((variant) => ( -
  • { - formatPrice(variant.calculated_price_incl_tax) - }
  • - ))} - - ))} -
- ) -} + useEffect(() => { + medusa.products.list({ + // TODO assuming region is already defined somewhere + region_id: region.id, + }) + .then(({ products, limit, offset, count }) => { + // ignore pagination for sake of example + setProducts(products) + }) + }) -export default Products -``` + const convertToDecimal = (amount) => { + return Math.floor(amount) / 100 + } -
- - -```tsx -import { formatVariantPrice, useProducts } from "medusa-react" -import { Product, ProductVariant } from "@medusajs/medusa" - -const Products = () => { - const { products, isLoading } = useProducts({ - region_id: region.id, // assuming already defined somewhere - }) - - return ( -
- {isLoading && Loading...} - {products && !products.length && ( - No Products - )} - {products && products.length > 0 && ( + const formatPrice = (amount) => { + return new Intl.NumberFormat("en-US", { + style: "currency", + // TODO assuming region is already defined somewhere + currency: region.currency_code, + }).format(convertToDecimal(amount)) + } + + return (
    - {products.map((product: Product) => ( + {products.map((product) => ( <> - {product.variants.map( - (variant: ProductVariant) => ( -
  • - {formatVariantPrice({ - variant, - // assuming already defined somewhere - region, - })} -
  • - ))} + {product.variants.map((variant) => ( +
  • { + formatPrice(variant.calculated_price_incl_tax) + }
  • + ))} ))}
- )} -
- ) -} + ) + } -export default Products -``` + export default Products + ``` -
+
+ + + ```tsx + import { formatVariantPrice, useProducts } from "medusa-react" + import { Product, ProductVariant } from "@medusajs/medusa" + + const Products = () => { + const { products, isLoading } = useProducts({ + region_id: region.id, // assuming already defined somewhere + }) + + return ( +
+ {isLoading && Loading...} + {products && !products.length && ( + No Products + )} + {products && products.length > 0 && ( +
    + {products.map((product: Product) => ( + <> + {product.variants.map( + (variant: ProductVariant) => ( +
  • + {formatVariantPrice({ + variant, + // assuming already defined somewhere + region, + })} +
  • + ))} + + ))} +
+ )} +
+ ) + } + + export default Products + ``` + +
--- @@ -591,49 +591,49 @@ The Search functionality requires either installing a [search plugin](../../../p You can search products using the [Search Products API Route](https://docs.medusajs.com/api/store#tag/Products/operation/PostProductsSearch): - + -```ts -medusa.products.search({ - q: "Shirt", -}) -.then(({ hits }) => { - console.log(hits.length) -}) -``` + ```ts + medusa.products.search({ + q: "Shirt", + }) + .then(({ hits }) => { + console.log(hits.length) + }) + ``` - - + + -```ts -fetch(`/store/products/search`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - q: "Shirt", - }), -}) -.then((response) => response.json()) -.then(({ hits }) => { - console.log(hits.length) -}) -``` + ```ts + fetch(`/store/products/search`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + q: "Shirt", + }), + }) + .then((response) => response.json()) + .then(({ hits }) => { + console.log(hits.length) + }) + ``` - - + + -```bash -curl -L -X POST '/store/products/search?q=Shirt' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "q": "Shirt" -}' -``` + ```bash + curl -L -X POST '/store/products/search?q=Shirt' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "q": "Shirt" + }' + ``` - + This API Route requires the query parameter `q` being the term to search products for. The search plugin or service you’re using determine how `q` will be used to search the products. It also accepts pagination parameters as explained in the [API reference](https://docs.medusajs.com/api/store#products_postproductssearch). @@ -647,83 +647,83 @@ The request returns a `hits` array holding the result items. The structure of th You can retrieve the details of a single product by its ID using the [Get a Product API Route](https://docs.medusajs.com/api/store#products_getproductsproduct): - + -```ts -medusa.products.retrieve(productId) -.then(({ product }) => { - console.log(product.id) -}) -``` + ```ts + medusa.products.retrieve(productId) + .then(({ product }) => { + console.log(product.id) + }) + ``` - - + + -```tsx -import { useProduct } from "medusa-react" + ```tsx + import { useProduct } from "medusa-react" -const Products = () => { - const { product, isLoading } = useProduct(productId) + const Products = () => { + const { product, isLoading } = useProduct(productId) - return ( -
- {isLoading && Loading...} - {product && {product.title}} -
- ) -} + return ( +
+ {isLoading && Loading...} + {product && {product.title}} +
+ ) + } -export default Products -``` + export default Products + ``` -
- - @medusajs/product - beta - -)} attributes={{ - badge: true -}}> + + + @medusajs/product + beta + + )} attributes={{ + badge: true + }}> -```ts -import { - initialize as initializeProductModule, -} from "@medusajs/product" + ```ts + import { + initialize as initializeProductModule, + } from "@medusajs/product" -// in an async function, or you can use promises -async () => { - // ... - const productService = await initializeProductModule() - const products = await productService.list({ - id: productId, - }) + // in an async function, or you can use promises + async () => { + // ... + const productService = await initializeProductModule() + const products = await productService.list({ + id: productId, + }) - console.log(products[0]) -} -``` + console.log(products[0]) + } + ``` - - + + -```ts -fetch(`/store/products/${productId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ product }) => { - console.log(product.id) -}) -``` + ```ts + fetch(`/store/products/${productId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ product }) => { + console.log(product.id) + }) + ``` - - + + -```bash -curl -L -X GET '/store/products/' -``` + ```bash + curl -L -X GET '/store/products/' + ``` - +
This API Route requires the product’s ID to be passed as a path parameter. You can also pass query parameters such as `cart_id` and `region_id` which are relevant for pricing as explained in the [Product Pricing Parameters section](#product-pricing-parameters). You can check the full list of accepted parameters in the [API reference](https://docs.medusajs.com/api/store#products_getproductsproduct). @@ -741,96 +741,96 @@ On the storefront, you may use the handle of a product as its page’s path. For You can retrieve the details of a product by its handle by sending a request to the List Products API Route, passing the `handle` as a filter: - + -```ts -medusa.products.list({ - handle, -}) -.then(({ products }) => { - if (!products.length) { - // product does not exist - } - const product = products[0] -}) -``` + ```ts + medusa.products.list({ + handle, + }) + .then(({ products }) => { + if (!products.length) { + // product does not exist + } + const product = products[0] + }) + ``` - - + + -```tsx -import { useProducts } from "medusa-react" + ```tsx + import { useProducts } from "medusa-react" -const Products = () => { - const { products, isLoading } = useProducts({ - handle, - }) + const Products = () => { + const { products, isLoading } = useProducts({ + handle, + }) - return ( -
- {isLoading && Loading...} - {products && !products.length && ( - Product does not exist - )} - {products && products.length > 0 && products[0].title} -
- ) -} + return ( +
+ {isLoading && Loading...} + {products && !products.length && ( + Product does not exist + )} + {products && products.length > 0 && products[0].title} +
+ ) + } -export default Products -``` + export default Products + ``` -
- - @medusajs/product - beta - -)} attributes={{ - badge: true -}}> + + + @medusajs/product + beta + + )} attributes={{ + badge: true + }}> -```ts -import { - initialize as initializeProductModule, -} from "@medusajs/product" + ```ts + import { + initialize as initializeProductModule, + } from "@medusajs/product" -// in an async function, or you can use promises -async () => { - // ... - const productService = await initializeProductModule() - const products = await productService.list({ - handle, - }) + // in an async function, or you can use promises + async () => { + // ... + const productService = await initializeProductModule() + const products = await productService.list({ + handle, + }) - console.log(products[0]) -} -``` + console.log(products[0]) + } + ``` - - + + -```ts -fetch(`/store/products?handle=${handle}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ products }) => { - if (!products.length) { - // product does not exist - } - const product = products[0] -}) -``` + ```ts + fetch(`/store/products?handle=${handle}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ products }) => { + if (!products.length) { + // product does not exist + } + const product = products[0] + }) + ``` - - + + -```bash -curl -L -X GET '/store/products?handle=' -``` + ```bash + curl -L -X GET '/store/products?handle=' + ``` - +
As the `handle` of each product is unique, when you pass the handle as a filter you’ll either: diff --git a/www/apps/docs/content/modules/products/storefront/use-categories.mdx b/www/apps/docs/content/modules/products/storefront/use-categories.mdx index 11208c6077..a866231bba 100644 --- a/www/apps/docs/content/modules/products/storefront/use-categories.mdx +++ b/www/apps/docs/content/modules/products/storefront/use-categories.mdx @@ -48,7 +48,7 @@ If you follow the Medusa React code blocks, it's assumed you already have [Medus This guide also includes code snippets to utilize the `@medusajs/product` module in your storefront, among other methods. -If you follow the `@medusajs/product` code blocks, it's assumed you already have the [@medusajs/product](../serverless-module.md) installed. +If you follow the `@medusajs/product` code blocks, it's assumed you already have the [@medusajs/product](../serverless-module.mdx) installed. --- @@ -57,95 +57,95 @@ If you follow the `@medusajs/product` code blocks, it's assumed you already have You can list product categories by sending a request to the [List Product Categories API Route](https://docs.medusajs.com/api/store#product-categories_getproductcategories): - + -```ts -medusa.productCategories.list() -.then(({ product_categories, limit, offset, count }) => { - console.log(product_categories.length) -}) -``` + ```ts + medusa.productCategories.list() + .then(({ product_categories, limit, offset, count }) => { + console.log(product_categories.length) + }) + ``` - - + + -```tsx -import { useProductCategories } from "medusa-react" -import { ProductCategory } from "@medusajs/medusa" + ```tsx + import { useProductCategories } from "medusa-react" + import { ProductCategory } from "@medusajs/medusa" -function Categories() { - const { - product_categories, - isLoading, - } = useProductCategories() + function Categories() { + const { + product_categories, + isLoading, + } = useProductCategories() - return ( -
- {isLoading && Loading...} - {product_categories && !product_categories.length && ( - No Categories - )} - {product_categories && product_categories.length > 0 && ( -
    - {product_categories.map( - (category: ProductCategory) => ( -
  • {category.name}
  • - ) + return ( +
    + {isLoading && Loading...} + {product_categories && !product_categories.length && ( + No Categories )} -
- )} -
- ) -} + {product_categories && product_categories.length > 0 && ( +
    + {product_categories.map( + (category: ProductCategory) => ( +
  • {category.name}
  • + ) + )} +
+ )} + + ) + } -export default Categories -``` + export default Categories + ``` -
- - @medusajs/product - beta - -)}> + + + @medusajs/product + beta + + )}> -```ts -import { - initialize as initializeProductModule, -} from "@medusajs/product" + ```ts + import { + initialize as initializeProductModule, + } from "@medusajs/product" -// in an async function, or you can use promises -async () => { - // ... - const productService = await initializeProductModule() - const categories = await productService.listCategories() + // in an async function, or you can use promises + async () => { + // ... + const productService = await initializeProductModule() + const categories = await productService.listCategories() - console.log(categories) -} -``` + console.log(categories) + } + ``` - - + + -```ts -fetch(`/store/product-categories`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ product_categories, limit, offset, count }) => { - console.log(product_categories.length) -}) -``` + ```ts + fetch(`/store/product-categories`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ product_categories, limit, offset, count }) => { + console.log(product_categories.length) + }) + ``` - - + + -```bash -curl -L -X GET '/store/product-categories' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/store/product-categories' \ + -H 'Authorization: Bearer ' + ``` - +
This request does not require any query parameters. You can, however, pass query parameters to filter the list of categories, such as the passing the `q` query parameter to search categories by title or handle. You can learn about available query parameters in the [API reference](https://docs.medusajs.com/api/store#product-categories_getproductcategories). @@ -163,84 +163,84 @@ By default, the categories are not retrieved along with their nested children. T You can retrieve a single product category by its ID using the [Get a Product Category API Route](https://docs.medusajs.com/api/store#product-categories_getproductcategoriescategory): - + -```ts -medusa.productCategories.retrieve(productCategoryId) -.then(({ product_category }) => { - console.log(product_category.name) -}) -``` + ```ts + medusa.productCategories.retrieve(productCategoryId) + .then(({ product_category }) => { + console.log(product_category.name) + }) + ``` - - + + -```tsx -import { useProductCategory } from "medusa-react" + ```tsx + import { useProductCategory } from "medusa-react" -function Category() { - const { product_category, isLoading } = useProductCategory() + function Category() { + const { product_category, isLoading } = useProductCategory() - return ( -
- {isLoading && Loading...} - {product_category && {product_category.name}} -
- ) -} + return ( +
+ {isLoading && Loading...} + {product_category && {product_category.name}} +
+ ) + } -export default Category -``` + export default Category + ``` -
- - @medusajs/product - beta - -)}> + + + @medusajs/product + beta + + )}> -```ts -import { - initialize as initializeProductModule, -} from "@medusajs/product" + ```ts + import { + initialize as initializeProductModule, + } from "@medusajs/product" -// in an async function, or you can use promises -async () => { - // ... - const productService = await initializeProductModule() - const categories = await productService.listCategories({ - id: productCategoryId, - }) + // in an async function, or you can use promises + async () => { + // ... + const productService = await initializeProductModule() + const categories = await productService.listCategories({ + id: productCategoryId, + }) - console.log(categories[0]) -} -``` + console.log(categories[0]) + } + ``` - - + + -```ts -fetch(`/store/product-categories/${productCategoryId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ product_category }) => { - console.log(product_category.name) -}) -``` + ```ts + fetch(`/store/product-categories/${productCategoryId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ product_category }) => { + console.log(product_category.name) + }) + ``` - - + + -```bash -curl -L -X GET '/store/product-categories/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/store/product-categories/' \ + -H 'Authorization: Bearer ' + ``` - +
This request requires the product category ID as a path parameter. You can also pass query parameters such as `expand` and `fields` as explained in the [API reference](https://docs.medusajs.com/api/store#product-categories_getproductcategoriescategory). @@ -256,107 +256,107 @@ On the storefront, you may use the handle of a category as its page’s path. Fo You can retrieve the details of a category by its handle by sending a request to the List Categories API Route, passing the `handle` as a filter: - + -```ts -medusa.productCategories.list({ - handle: "women", -}) -.then(({ product_categories, limit, offset, count }) => { - if (!product_categories.length) { - // category does not exist - } - const category = product_categories[0] -}) -``` + ```ts + medusa.productCategories.list({ + handle: "women", + }) + .then(({ product_categories, limit, offset, count }) => { + if (!product_categories.length) { + // category does not exist + } + const category = product_categories[0] + }) + ``` - - + + -```tsx -import { useProductCategories } from "medusa-react" -import { ProductCategory } from "@medusajs/medusa" + ```tsx + import { useProductCategories } from "medusa-react" + import { ProductCategory } from "@medusajs/medusa" -function Categories() { - const { - product_categories, - isLoading, - } = useProductCategories({ - handle: "women", - }) + function Categories() { + const { + product_categories, + isLoading, + } = useProductCategories({ + handle: "women", + }) - return ( -
- {isLoading && Loading...} - {product_categories && !product_categories.length && ( - No Categories - )} - {product_categories && product_categories.length > 0 && ( -
    - {product_categories.map( - (category: ProductCategory) => ( -
  • {category.name}
  • - ) + return ( +
    + {isLoading && Loading...} + {product_categories && !product_categories.length && ( + No Categories )} -
- )} -
- ) -} + {product_categories && product_categories.length > 0 && ( +
    + {product_categories.map( + (category: ProductCategory) => ( +
  • {category.name}
  • + ) + )} +
+ )} + + ) + } -export default Categories -``` + export default Categories + ``` -
- - @medusajs/product - beta - -)}> + + + @medusajs/product + beta + + )}> -```ts -import { - initialize as initializeProductModule, -} from "@medusajs/product" + ```ts + import { + initialize as initializeProductModule, + } from "@medusajs/product" -// in an async function, or you can use promises -async () => { - // ... - const productService = await initializeProductModule() - const categories = await productService.listCategories({ - handle, - }) + // in an async function, or you can use promises + async () => { + // ... + const productService = await initializeProductModule() + const categories = await productService.listCategories({ + handle, + }) - console.log(categories[0]) -} -``` + console.log(categories[0]) + } + ``` - - + + -```ts -fetch(`/store/product-categories?handle=women`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ product_categories, limit, offset, count }) => { - if (!product_categories.length) { - // category does not exist - } - const category = product_categories[0] -}) -``` + ```ts + fetch(`/store/product-categories?handle=women`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ product_categories, limit, offset, count }) => { + if (!product_categories.length) { + // category does not exist + } + const category = product_categories[0] + }) + ``` - - + + -```bash -curl -L -X GET '/store/product-categories?handle=women' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/store/product-categories?handle=women' \ + -H 'Authorization: Bearer ' + ``` - +
As the `handle` of each category is unique, when you pass the handle as a filter you’ll either: diff --git a/www/apps/docs/content/modules/regions-and-currencies/admin/manage-currencies.mdx b/www/apps/docs/content/modules/regions-and-currencies/admin/manage-currencies.mdx index 676cc247f8..8ce5c4dac3 100644 --- a/www/apps/docs/content/modules/regions-and-currencies/admin/manage-currencies.mdx +++ b/www/apps/docs/content/modules/regions-and-currencies/admin/manage-currencies.mdx @@ -63,67 +63,67 @@ You can learn more about [authenticating as an admin user in the API reference]( You can list all available currencies in your system by sending a request to the [List Currencies API Route](https://docs.medusajs.com/api/admin#currencies_getcurrencies): - + -```ts -medusa.admin.currencies.list() -.then(({ currencies, count, offset, limit }) => { - console.log(currencies.length) -}) -``` + ```ts + medusa.admin.currencies.list() + .then(({ currencies, count, offset, limit }) => { + console.log(currencies.length) + }) + ``` - - + + -```tsx -import { Currency } from "@medusajs/medusa" -import { useAdminCurrencies } from "medusa-react" + ```tsx + import { Currency } from "@medusajs/medusa" + import { useAdminCurrencies } from "medusa-react" -const Currencies = () => { - const { currencies, isLoading } = useAdminCurrencies() + const Currencies = () => { + const { currencies, isLoading } = useAdminCurrencies() - return ( -
- {isLoading && Loading...} - {currencies && !currencies.length && ( - No Currencies - )} - {currencies && currencies.length > 0 && ( -
    - {currencies.map((currency: Currency) => ( -
  • {currency.name}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {currencies && !currencies.length && ( + No Currencies + )} + {currencies && currencies.length > 0 && ( +
    + {currencies.map((currency: Currency) => ( +
  • {currency.name}
  • + ))} +
+ )} +
+ ) + } -export default Currencies -``` + export default Currencies + ``` -
- + + -```ts -fetch(`/admin/currencies`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ currencies, count, offset, limit }) => { - console.log(currencies.length) -}) -``` + ```ts + fetch(`/admin/currencies`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ currencies, count, offset, limit }) => { + console.log(currencies.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/currencies' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/currencies' \ + -H 'Authorization: Bearer ' + ``` - +
This API Route accepts optional filter and search query parameters. For example, you can pass the `code` query parameter to search the list of currencies by a code. You can learn about available query parameters in the [API reference](https://docs.medusajs.com/api/admin#currencies_getcurrencies). @@ -137,72 +137,72 @@ This request returns an array of currencies along with pagination parameters. You can update a currency by sending a request to the [Update Currency API Route](https://docs.medusajs.com/api/admin#currencies_postcurrenciescurrency): - + -```ts -medusa.admin.currencies.update(code, { - includes_tax: true, -}) -.then(({ currency }) => { - console.log(currency.code) -}) -``` - - - - -```tsx -import { useAdminUpdateCurrency } from "medusa-react" - -const UpdateCode = () => { - const updateCode = useAdminUpdateCurrency(code) - // ... - - const handleUpdate = () => { - updateCode.mutate({ - includes_tax, + ```ts + medusa.admin.currencies.update(code, { + includes_tax: true, }) - } + .then(({ currency }) => { + console.log(currency.code) + }) + ``` - // ... -} + + -export default UpdateCode -``` + ```tsx + import { useAdminUpdateCurrency } from "medusa-react" - - + const UpdateCode = () => { + const updateCode = useAdminUpdateCurrency(code) + // ... -```ts -fetch(`/admin/currencies/${code}`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - includes_tax, - }), - }) - .then((response) => response.json()) - .then(({ currency }) => { - console.log(currency.code) - }) -``` + const handleUpdate = () => { + updateCode.mutate({ + includes_tax, + }) + } - - + // ... + } -```bash -curl -L -X GET '/admin/currencies/' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "includes_tax": true -}' -``` + export default UpdateCode + ``` - + + + + ```ts + fetch(`/admin/currencies/${code}`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + includes_tax, + }), + }) + .then((response) => response.json()) + .then(({ currency }) => { + console.log(currency.code) + }) + ``` + + + + + ```bash + curl -L -X GET '/admin/currencies/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "includes_tax": true + }' + ``` + + This API Route requires the currency code as a path parameter. @@ -228,72 +228,72 @@ This section explains how you can manage the currencies of a store. You can list currencies in a store by sending a request to the [Get Store Details API Route](https://docs.medusajs.com/api/admin#store_getstore): - + -```ts -medusa.admin.store.retrieve() -.then(({ store }) => { - console.log(store.currencies, store.default_currency) -}) -``` + ```ts + medusa.admin.store.retrieve() + .then(({ store }) => { + console.log(store.currencies, store.default_currency) + }) + ``` - - + + -```tsx -import { Currency } from "@medusajs/medusa" -import { useAdminStore } from "medusa-react" + ```tsx + import { Currency } from "@medusajs/medusa" + import { useAdminStore } from "medusa-react" -const StoreCurrencies = () => { - const { store, isLoading } = useAdminStore() + const StoreCurrencies = () => { + const { store, isLoading } = useAdminStore() - return ( -
- {isLoading && Loading...} - {store && store.default_currency && ( - - Default Currency: {store.default_currency.code} - - )} - {store && !store.currencies.length && ( - No Currencies - )} - {store?.currencies && store.currencies.length > 0 && ( -
    - {store.currencies.map((currency: Currency) => ( -
  • {currency.name}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {store && store.default_currency && ( + + Default Currency: {store.default_currency.code} + + )} + {store && !store.currencies.length && ( + No Currencies + )} + {store?.currencies && store.currencies.length > 0 && ( +
    + {store.currencies.map((currency: Currency) => ( +
  • {currency.name}
  • + ))} +
+ )} +
+ ) + } -export default StoreCurrencies -``` + export default StoreCurrencies + ``` -
- + + -```ts -fetch(`/admin/store`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ store }) => { - console.log(store.currencies, store.default_currency) -}) -``` + ```ts + fetch(`/admin/store`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ store }) => { + console.log(store.currencies, store.default_currency) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/store' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X POST '/admin/store' \ + -H 'Authorization: Bearer ' + ``` - +
This request returns the store as an object. In that object, there are two properties related to currencies: @@ -306,58 +306,58 @@ This request returns the store as an object. In that object, there are two prope You can add a currency to a store using the [Add a Currency Code API Route](https://docs.medusajs.com/api/admin#store_poststorecurrenciescode): - + -```ts -medusa.admin.store.addCurrency(code) -.then(({ store }) => { - console.log(store.currencies) -}) -``` + ```ts + medusa.admin.store.addCurrency(code) + .then(({ store }) => { + console.log(store.currencies) + }) + ``` - - + + -```tsx -import { useAdminAddStoreCurrency } from "medusa-react" + ```tsx + import { useAdminAddStoreCurrency } from "medusa-react" -const AddCurrency = () => { - const addCode = useAdminAddStoreCurrency() - // ... + const AddCurrency = () => { + const addCode = useAdminAddStoreCurrency() + // ... - const handleAdd = () => { - addCode.mutate(code) - } + const handleAdd = () => { + addCode.mutate(code) + } - // ... -} + // ... + } -export default AddCurrency -``` + export default AddCurrency + ``` - - + + -```ts -fetch(`/admin/store/currencies/${code}`, { - credentials: "include", - method: "POST", -}) -.then((response) => response.json()) -.then(({ store }) => { - console.log(store.currencies) -}) -``` + ```ts + fetch(`/admin/store/currencies/${code}`, { + credentials: "include", + method: "POST", + }) + .then((response) => response.json()) + .then(({ store }) => { + console.log(store.currencies) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/store/currencies/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X POST '/admin/store/currencies/' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the currency code to be passed as a path parameter. @@ -369,58 +369,58 @@ The request returns the updated store as an object. You can access the new list You can remove a currency from a store by sending a request to the [Delete Currency Code API Route](https://docs.medusajs.com/api/admin#store_deletestorecurrenciescode): - + -```ts -medusa.admin.store.deleteCurrency(code) -.then(({ store }) => { - console.log(store.currencies) -}) -``` + ```ts + medusa.admin.store.deleteCurrency(code) + .then(({ store }) => { + console.log(store.currencies) + }) + ``` - - + + -```tsx -import { useAdminDeleteStoreCurrency } from "medusa-react" + ```tsx + import { useAdminDeleteStoreCurrency } from "medusa-react" -const DeleteCurrency = () => { - const deleteCurrency = useAdminDeleteStoreCurrency() - // ... + const DeleteCurrency = () => { + const deleteCurrency = useAdminDeleteStoreCurrency() + // ... - const handleDelete = () => { - deleteCurrency.mutate(code) - } + const handleDelete = () => { + deleteCurrency.mutate(code) + } - // ... -} + // ... + } -export default DeleteCurrency -``` + export default DeleteCurrency + ``` - - + + -```ts -fetch(`/admin/store/currencies/${code}`, { - credentials: "include", - method: "DELETE", -}) -.then((response) => response.json()) -.then(({ store }) => { - console.log(store.currencies) -}) -``` + ```ts + fetch(`/admin/store/currencies/${code}`, { + credentials: "include", + method: "DELETE", + }) + .then((response) => response.json()) + .then(({ store }) => { + console.log(store.currencies) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/store/currencies/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/store/currencies/' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the currency code to be passed as a path parameter. diff --git a/www/apps/docs/content/modules/regions-and-currencies/admin/manage-regions.mdx b/www/apps/docs/content/modules/regions-and-currencies/admin/manage-regions.mdx index 6c46a1c987..e8295eee4a 100644 --- a/www/apps/docs/content/modules/regions-and-currencies/admin/manage-regions.mdx +++ b/www/apps/docs/content/modules/regions-and-currencies/admin/manage-regions.mdx @@ -63,67 +63,67 @@ You can learn more about [authenticating as an admin user in the API reference]( You can retrieve regions available on your backend using the [List Regions API Route](https://docs.medusajs.com/api/admin#regions_getregions): - + -```ts -medusa.admin.regions.list() -.then(({ regions, limit, offset, count }) => { - console.log(regions.length) - // display regions -}) -``` + ```ts + medusa.admin.regions.list() + .then(({ regions, limit, offset, count }) => { + console.log(regions.length) + // display regions + }) + ``` - - + + -```tsx -import { Region } from "@medusajs/medusa" -import { useAdminRegions } from "medusa-react" + ```tsx + import { Region } from "@medusajs/medusa" + import { useAdminRegions } from "medusa-react" -const Regions = () => { - const { regions, isLoading } = useAdminRegions() + const Regions = () => { + const { regions, isLoading } = useAdminRegions() - return ( -
- {isLoading && Loading...} - {regions && !regions.length && No Regions} - {regions && regions.length > 0 && ( -
    - {regions.map((region: Region) => ( -
  • {region.name}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {regions && !regions.length && No Regions} + {regions && regions.length > 0 && ( +
    + {regions.map((region: Region) => ( +
  • {region.name}
  • + ))} +
+ )} +
+ ) + } -export default Regions -``` + export default Regions + ``` -
- + + -```ts -fetch(`/admin/regions`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ regions, limit, offset, count }) => { - console.log(regions.length) - // display regions -}) -``` + ```ts + fetch(`/admin/regions`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ regions, limit, offset, count }) => { + console.log(regions.length) + // display regions + }) + ``` - - + + -```bash -curl -L -X GET '/admin/regions' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/regions' \ + -H 'Authorization: Bearer ' + ``` - +
This request returns an array of regions, as well as [pagination fields](https://docs.medusajs.com/api/admin#pagination). @@ -137,40 +137,10 @@ You can also pass filters and other selection query parameters to the request. C You can create a region by sending a request to the [Create a Region API Route](https://docs.medusajs.com/api/admin#regions_postregions): - + -```ts -medusa.admin.regions.create({ - name: "Europe", - currency_code: "eur", - tax_rate: 0, - payment_providers: [ - "manual", - ], - fulfillment_providers: [ - "manual", - ], - countries: [ - "DK", - ], -}) -.then(({ region }) => { - console.log(region.id) -}) -``` - - - - -```tsx -import { useAdminCreateRegion } from "medusa-react" - -const CreateRegion = () => { - const createRegion = useAdminCreateRegion() - // ... - - const handleCreate = () => { - createRegion.mutate({ + ```ts + medusa.admin.regions.create({ name: "Europe", currency_code: "eur", tax_rate: 0, @@ -184,69 +154,99 @@ const CreateRegion = () => { "DK", ], }) - } + .then(({ region }) => { + console.log(region.id) + }) + ``` - // ... -} + + -export default CreateRegion -``` + ```tsx + import { useAdminCreateRegion } from "medusa-react" - - + const CreateRegion = () => { + const createRegion = useAdminCreateRegion() + // ... -```ts -fetch(`/admin/regions`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - name: "Europe", - currency_code: "eur", - tax_rate: 0, - payment_providers: [ - "manual", - ], - fulfillment_providers: [ - "manual", - ], - countries: [ - "DK", - ], - }), -}) -.then((response) => response.json()) -.then(({ region }) => { - console.log(region.id) -}) -``` + const handleCreate = () => { + createRegion.mutate({ + name: "Europe", + currency_code: "eur", + tax_rate: 0, + payment_providers: [ + "manual", + ], + fulfillment_providers: [ + "manual", + ], + countries: [ + "DK", + ], + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/regions' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "name": "Europe", - "currency_code": "eur", - "tax_rate": 0, - "payment_providers": [ - "manual" - ], - "fulfillment_providers": [ - "manual" - ], - "countries": [ - "DK" - ] -}' -``` + export default CreateRegion + ``` - + + + + ```ts + fetch(`/admin/regions`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + name: "Europe", + currency_code: "eur", + tax_rate: 0, + payment_providers: [ + "manual", + ], + fulfillment_providers: [ + "manual", + ], + countries: [ + "DK", + ], + }), + }) + .then((response) => response.json()) + .then(({ region }) => { + console.log(region.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/regions' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "name": "Europe", + "currency_code": "eur", + "tax_rate": 0, + "payment_providers": [ + "manual" + ], + "fulfillment_providers": [ + "manual" + ], + "countries": [ + "DK" + ] + }' + ``` + + This request requires the following body parameters: @@ -271,84 +271,84 @@ You can update any of the region’s fields and configurations. The REST APIs of Alternatively, you can update the details of a region using the [Update a Region API Route](https://docs.medusajs.com/api/admin#regions_postregionsregion): - + -```ts -medusa.admin.regions.update(regionId, { - countries: [ - "DK", - "DE", - ], -}) -.then(({ region }) => { - console.log(region.id) -}) -``` - - - - -```tsx -import { useAdminUpdateRegion } from "medusa-react" - -const UpdateRegion = () => { - const updateRegion = useAdminUpdateRegion(regionId) - // ... - - const handleUpdate = () => { - updateRegion.mutate({ + ```ts + medusa.admin.regions.update(regionId, { countries: [ "DK", "DE", ], }) - } + .then(({ region }) => { + console.log(region.id) + }) + ``` - // ... -} + + -export default UpdateRegion -``` + ```tsx + import { useAdminUpdateRegion } from "medusa-react" - - + const UpdateRegion = () => { + const updateRegion = useAdminUpdateRegion(regionId) + // ... -```ts -fetch(`/admin/regions/${regionId}`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - countries: [ - "DK", - "DE", - ], - }), -}) -.then((response) => response.json()) -.then(({ region }) => { - console.log(region.id) -}) -``` + const handleUpdate = () => { + updateRegion.mutate({ + countries: [ + "DK", + "DE", + ], + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/regions/' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "countries": [ - "DK", - "DE" - ] -}' -``` + export default UpdateRegion + ``` - + + + + ```ts + fetch(`/admin/regions/${regionId}`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + countries: [ + "DK", + "DE", + ], + }), + }) + .then((response) => response.json()) + .then(({ region }) => { + console.log(region.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/regions/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "countries": [ + "DK", + "DE" + ] + }' + ``` + + This request accepts in its body parameters any of the region’s fields that you want to update. In the example above, you update the list of countries that are included in that region. @@ -370,35 +370,10 @@ In the example above, the list of countries replace any countries that were prev You can add a shipping option to a region by sending a request to the [Create Shipping Option API Route](https://docs.medusajs.com/api/admin#shipping-options_postshippingoptions): - + -```ts -medusa.admin.shippingOptions.create({ - name: "PostFake", - region_id: regionId, - provider_id: "manual", - data: { - }, - price_type: "flat_rate", - amount: 1000, -}) -.then(({ shipping_option }) => { - console.log(shipping_option.id) -}) -``` - - - - -```tsx -import { useAdminCreateShippingOption } from "medusa-react" - -const Region = () => { - const createShippingOption = useAdminCreateShippingOption() - // ... - - const handleCreate = () => { - createShippingOption.mutate({ + ```ts + medusa.admin.shippingOptions.create({ name: "PostFake", region_id: regionId, provider_id: "manual", @@ -407,58 +382,83 @@ const Region = () => { price_type: "flat_rate", amount: 1000, }) - } + .then(({ shipping_option }) => { + console.log(shipping_option.id) + }) + ``` - // ... -} + + -export default Region -``` + ```tsx + import { useAdminCreateShippingOption } from "medusa-react" - - + const Region = () => { + const createShippingOption = useAdminCreateShippingOption() + // ... -```ts -fetch(`/admin/shipping-options`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - name: "PostFake", - region_id: regionId, - provider_id: "manual", - price_type: "flat_rate", - data: { - }, - amount: 1000, - }), -}) -.then((response) => response.json()) -.then(({ shipping_option }) => { - console.log(shipping_option.id) -}) -``` + const handleCreate = () => { + createShippingOption.mutate({ + name: "PostFake", + region_id: regionId, + provider_id: "manual", + data: { + }, + price_type: "flat_rate", + amount: 1000, + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/shipping-options' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "name": "PostFake", - "region_id": "", - "provider_id": "manual", - "price_type": "flat_rate", - "data": {}, - "amount": 1000 -}' -``` + export default Region + ``` - + + + + ```ts + fetch(`/admin/shipping-options`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + name: "PostFake", + region_id: regionId, + provider_id: "manual", + price_type: "flat_rate", + data: { + }, + amount: 1000, + }), + }) + .then((response) => response.json()) + .then(({ shipping_option }) => { + console.log(shipping_option.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/shipping-options' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "name": "PostFake", + "region_id": "", + "provider_id": "manual", + "price_type": "flat_rate", + "data": {}, + "amount": 1000 + }' + ``` + + This request requires the following body parameters: @@ -489,58 +489,58 @@ You can also manage shipping options such as list, update, and delete. You can l You can delete a region by sending a request to the [Delete a Region API Route](https://docs.medusajs.com/api/admin#regions_deleteregionsregion): - + -```ts -medusa.admin.regions.delete(regionId) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + medusa.admin.regions.delete(regionId) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```tsx -import { useAdminDeleteRegion } from "medusa-react" + ```tsx + import { useAdminDeleteRegion } from "medusa-react" -const Region = () => { - const deleteRegion = useAdminDeleteRegion(regionId) - // ... + const Region = () => { + const deleteRegion = useAdminDeleteRegion(regionId) + // ... - const handleDelete = () => { - deleteRegion.mutate() - } + const handleDelete = () => { + deleteRegion.mutate() + } - // ... -} + // ... + } -export default Region -``` + export default Region + ``` - - + + -```ts -fetch(`/admin/regions/${regionId}`, { - credentials: "include", - method: "DELETE", -}) -.then((response) => response.json()) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + fetch(`/admin/regions/${regionId}`, { + credentials: "include", + method: "DELETE", + }) + .then((response) => response.json()) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/regions/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/regions/' \ + -H 'Authorization: Bearer ' + ``` - + This request requires the region ID as a path parameter. It deletes the region and returns the following fields: diff --git a/www/apps/docs/content/modules/regions-and-currencies/storefront/use-regions.mdx b/www/apps/docs/content/modules/regions-and-currencies/storefront/use-regions.mdx index 88697869f9..423a38c4a1 100644 --- a/www/apps/docs/content/modules/regions-and-currencies/storefront/use-regions.mdx +++ b/www/apps/docs/content/modules/regions-and-currencies/storefront/use-regions.mdx @@ -55,60 +55,60 @@ Customers should be able to see the list of available regions and select their r You can retrieve available regions by sending a request to the [List Regions API Route](https://docs.medusajs.com/api/store#regions_getregions): - + -```ts -medusa.regions.list() -.then(({ regions }) => { - console.log(regions.length) - // show customers available regions -}) -``` + ```ts + medusa.regions.list() + .then(({ regions }) => { + console.log(regions.length) + // show customers available regions + }) + ``` - - + + -```tsx -import { Region } from "@medusajs/medusa" -import { useRegions } from "medusa-react" + ```tsx + import { Region } from "@medusajs/medusa" + import { useRegions } from "medusa-react" -const Regions = () => { - const { regions, isLoading } = useRegions() + const Regions = () => { + const { regions, isLoading } = useRegions() - return ( -
- {isLoading && Loading...} - {regions?.length && ( -
    - {regions.map((region: Region) => ( -
  • - {region.name} -
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {regions?.length && ( +
    + {regions.map((region: Region) => ( +
  • + {region.name} +
  • + ))} +
+ )} +
+ ) + } -export default Regions -``` + export default Regions + ``` -
- + + -```ts -fetch(`/store/regions`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ regions }) => { - console.log(regions.length) - // show customers available regions -}) -``` + ```ts + fetch(`/store/regions`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ regions }) => { + console.log(regions.length) + // show customers available regions + }) + ``` - +
This request returns the list of available regions. You can show them to your customers to select their region. @@ -124,56 +124,56 @@ To retrieve products with the prices based on the selected regions, you can pass For example: - + -```ts -medusa.products.list({ - region_id: regionId, -}) -.then(({ products, limit, offset, count }) => { - console.log(products.length) - // show customer the products -}) -``` + ```ts + medusa.products.list({ + region_id: regionId, + }) + .then(({ products, limit, offset, count }) => { + console.log(products.length) + // show customer the products + }) + ``` - - + + -```tsx -import { formatVariantPrice } from "medusa-react" + ```tsx + import { formatVariantPrice } from "medusa-react" -const Product = () => { - // retrieve the region and variant(s) - // ... + const Product = () => { + // retrieve the region and variant(s) + // ... - return ( - - {formatVariantPrice({ - variant, // ProductVariant - region, // Region - })} - - ) -} + return ( + + {formatVariantPrice({ + variant, // ProductVariant + region, // Region + })} + + ) + } -export default Product -``` + export default Product + ``` - - + + -```ts -fetch(`/store/products?region_id=${regionId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ products, limit, offset, count }) => { - console.log(products.length) - // show customer the products -}) -``` + ```ts + fetch(`/store/products?region_id=${regionId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ products, limit, offset, count }) => { + console.log(products.length) + // show customer the products + }) + ``` - + In this example, you send a request to the List Products API Route, passing it the `region_id` query parameter. It is assumed that you have the ID of the region stored in the variable `regionId`. @@ -197,58 +197,58 @@ You can learn how to implement cart functionalities in your storefront in [this For example: - + -```ts -medusa.carts.update(cartId, { - region_id: regionId, -}) -.then(({ cart }) => { - console.log(cart.id) -}) -``` - - - - -```tsx -import { useCart } from "medusa-react" - -const Cart = () => { - // ... - - const { updateCart } = useCart() - - const changeRegionId = (region_id: string) => { - updateCart.mutate({ - region_id, + ```ts + medusa.carts.update(cartId, { + region_id: regionId, }) - } + .then(({ cart }) => { + console.log(cart.id) + }) + ``` - // ... -} + + -export default Cart -``` + ```tsx + import { useCart } from "medusa-react" - - + const Cart = () => { + // ... -```ts -fetch(`/store/carts/${cartId}`, { - method: "POST", - credentials: "include", - body: JSON.stringify({ - region_id: regionId, - }), -}) -.then((response) => response.json()) -.then(({ cart }) => { - console.log(cart.id) -}) -``` + const { updateCart } = useCart() - + const changeRegionId = (region_id: string) => { + updateCart.mutate({ + region_id, + }) + } + + // ... + } + + export default Cart + ``` + + + + + ```ts + fetch(`/store/carts/${cartId}`, { + method: "POST", + credentials: "include", + body: JSON.stringify({ + region_id: regionId, + }), + }) + .then((response) => response.json()) + .then(({ cart }) => { + console.log(cart.id) + }) + ``` + + In this example, you send a request to the [Update Cart API Route](https://docs.medusajs.com/api/store#carts_postcartscart). In the request’s body, you pass the parameter `region_id` and set its value to the selected region’s ID. It is assumed that you have the ID of the region stored in the variable `regionId`. diff --git a/www/apps/docs/content/modules/sales-channels/admin/manage.mdx b/www/apps/docs/content/modules/sales-channels/admin/manage.mdx index 8234682180..215a305bf7 100644 --- a/www/apps/docs/content/modules/sales-channels/admin/manage.mdx +++ b/www/apps/docs/content/modules/sales-channels/admin/manage.mdx @@ -55,76 +55,76 @@ You can learn more about [authenticating as an admin user in the API reference]( You can create a sales channel by sending a request to the Create a Sales Channel API Route: - + -```ts -medusa.admin.salesChannels.create({ - name: "App", - description: "Mobile app", -}) -.then(({ sales_channel }) => { - console.log(sales_channel.id) -}) -``` - - - - -```tsx -import { useAdminCreateSalesChannel } from "medusa-react" - -const CreateSalesChannel = () => { - const createSalesChannel = useAdminCreateSalesChannel() - // ... - - const handleCreate = (name: string, description: string) => { - createSalesChannel.mutate({ - name, - description, + ```ts + medusa.admin.salesChannels.create({ + name: "App", + description: "Mobile app", }) - } + .then(({ sales_channel }) => { + console.log(sales_channel.id) + }) + ``` - // ... -} + + -export default CreateSalesChannel -``` + ```tsx + import { useAdminCreateSalesChannel } from "medusa-react" - - + const CreateSalesChannel = () => { + const createSalesChannel = useAdminCreateSalesChannel() + // ... -```ts -fetch(`/admin/sales-channels`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - name: "App", - description: "Mobile app", - }), -}) -.then((response) => response.json()) -.then(({ sales_channel }) => { - console.log(sales_channel.id) -}) -``` + const handleCreate = (name: string, description: string) => { + createSalesChannel.mutate({ + name, + description, + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/sales-channels' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - name: 'App', - description: 'Mobile app' -}' -``` + export default CreateSalesChannel + ``` - + + + + ```ts + fetch(`/admin/sales-channels`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + name: "App", + description: "Mobile app", + }), + }) + .then((response) => response.json()) + .then(({ sales_channel }) => { + console.log(sales_channel.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/sales-channels' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + name: 'App', + description: 'Mobile app' + }' + ``` + + This request requires the request body parameters `name`, and optionally accepts the `description` and `is_disabled` request body parameters. @@ -138,67 +138,67 @@ It returns the created sales channel. You can list all sales channels by sending a request to the List Sales Channels API Route: - + -```ts -medusa.admin.salesChannels.list() -.then(({ sales_channels, limit, offset, count }) => { - console.log(sales_channels.length) -}) -``` + ```ts + medusa.admin.salesChannels.list() + .then(({ sales_channels, limit, offset, count }) => { + console.log(sales_channels.length) + }) + ``` - - + + -```tsx -import { SalesChannel } from "@medusajs/medusa" -import { useAdminSalesChannels } from "medusa-react" + ```tsx + import { SalesChannel } from "@medusajs/medusa" + import { useAdminSalesChannels } from "medusa-react" -const SalesChannels = () => { - const { sales_channels, isLoading } = useAdminSalesChannels() + const SalesChannels = () => { + const { sales_channels, isLoading } = useAdminSalesChannels() - return ( -
- {isLoading && Loading...} - {sales_channels && !sales_channels.length && ( - No Sales Channels - )} - {sales_channels && sales_channels.length > 0 && ( -
    - {sales_channels.map((salesChannel: SalesChannel) => ( -
  • {salesChannel.name}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {sales_channels && !sales_channels.length && ( + No Sales Channels + )} + {sales_channels && sales_channels.length > 0 && ( +
    + {sales_channels.map((salesChannel: SalesChannel) => ( +
  • {salesChannel.name}
  • + ))} +
+ )} +
+ ) + } -export default SalesChannels -``` + export default SalesChannels + ``` -
- + + -```ts -fetch(`/admin/sales-channels`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ sales_channels, limit, offset, count }) => { - console.log(sales_channels.length) -}) -``` + ```ts + fetch(`/admin/sales-channels`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ sales_channels, limit, offset, count }) => { + console.log(sales_channels.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/sales-channels' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/sales-channels' \ + -H 'Authorization: Bearer ' + ``` - +
This request returns an array of all sales channels in your store. You can also pass query parameters to filter or customize the pagination of the results. Check out [the API Reference for a full list of query parameters.](https://docs.medusajs.com/api/admin#sales-channels_getsaleschannels) @@ -210,60 +210,60 @@ This request returns an array of all sales channels in your store. You can also You can retrieve a sales channel’s details by its ID using the Get Sales Channel API Route: - + -```ts -medusa.admin.salesChannels.retrieve(salesChannelId) -.then(({ sales_channel }) => { - console.log(sales_channel.id) -}) -``` + ```ts + medusa.admin.salesChannels.retrieve(salesChannelId) + .then(({ sales_channel }) => { + console.log(sales_channel.id) + }) + ``` - - + + -```tsx -import { useAdminSalesChannel } from "medusa-react" + ```tsx + import { useAdminSalesChannel } from "medusa-react" -const SalesChannel = () => { - const { - sales_channel, - isLoading, - } = useAdminSalesChannel(salesChannelId) + const SalesChannel = () => { + const { + sales_channel, + isLoading, + } = useAdminSalesChannel(salesChannelId) - return ( -
- {isLoading && Loading...} - {sales_channel && {sales_channel.name}} -
- ) -} + return ( +
+ {isLoading && Loading...} + {sales_channel && {sales_channel.name}} +
+ ) + } -export default SalesChannel -``` + export default SalesChannel + ``` -
- + + -```ts -fetch(`/admin/sales-channels/${salesChannelId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ sales_channels, limit, offset, count }) => { - console.log(sales_channels.length) -}) -``` + ```ts + fetch(`/admin/sales-channels/${salesChannelId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ sales_channels, limit, offset, count }) => { + console.log(sales_channels.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/sales-channels/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/sales-channels/' \ + -H 'Authorization: Bearer ' + ``` - +
This request returns the sales channel with the specified ID. @@ -275,74 +275,74 @@ This request returns the sales channel with the specified ID. You can update a Sales Channel’s details and attributes by sending a request to the Update Sales Channel API Route: - + -```ts -medusa.admin.salesChannels.update(salesChannelId, { - is_disabled: false, -}) -.then(({ sales_channel }) => { - console.log(sales_channel.id) -}) -``` - - - - -```tsx -import { useAdminUpdateSalesChannel } from "medusa-react" - -const UpdateSalesChannel = () => { - const updateSalesChannel = useAdminUpdateSalesChannel( - salesChannelId - ) - // ... - - const handleUpdate = () => { - updateSalesChannel.mutate({ + ```ts + medusa.admin.salesChannels.update(salesChannelId, { is_disabled: false, }) - } + .then(({ sales_channel }) => { + console.log(sales_channel.id) + }) + ``` - // ... -} + + -export default UpdateSalesChannel -``` + ```tsx + import { useAdminUpdateSalesChannel } from "medusa-react" - - + const UpdateSalesChannel = () => { + const updateSalesChannel = useAdminUpdateSalesChannel( + salesChannelId + ) + // ... -```ts -fetch(`/admin/sales-channels/${salesChannelId}`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - is_disabled: false, - }), -}) -.then((response) => response.json()) -.then(({ sales_channel }) => { - console.log(sales_channel.id) -}) -``` + const handleUpdate = () => { + updateSalesChannel.mutate({ + is_disabled: false, + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/sales-channels/' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "is_disabled": false -}' -``` + export default UpdateSalesChannel + ``` - + + + + ```ts + fetch(`/admin/sales-channels/${salesChannelId}`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + is_disabled: false, + }), + }) + .then((response) => response.json()) + .then(({ sales_channel }) => { + console.log(sales_channel.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/sales-channels/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "is_disabled": false + }' + ``` + + In this example, you enable a sales channel by changing the value of the `is_disabled` attribute. @@ -358,60 +358,60 @@ You can check out [the API Reference for a full list of body parameters](https:/ You can delete a sales channel by sending a request to the Delete Sales Channel API Route with the ID of the sales channel to delete: - + -```ts -medusa.admin.salesChannels.delete(salesChannelId) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + medusa.admin.salesChannels.delete(salesChannelId) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```tsx -import { useAdminDeleteSalesChannel } from "medusa-react" + ```tsx + import { useAdminDeleteSalesChannel } from "medusa-react" -const SalesChannel = () => { - const deleteSalesChannel = useAdminDeleteSalesChannel( - salesChannelId - ) - // ... + const SalesChannel = () => { + const deleteSalesChannel = useAdminDeleteSalesChannel( + salesChannelId + ) + // ... - const handleDelete = () => { - deleteSalesChannel.mutate() - } + const handleDelete = () => { + deleteSalesChannel.mutate() + } - // ... -} + // ... + } -export default SalesChannel -``` + export default SalesChannel + ``` - - + + -```ts -fetch(`/admin/sales-channels/${salesChannelId}`, { - method: "DELETE", - credentials: "include", -}) -.then((response) => response.json()) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + fetch(`/admin/sales-channels/${salesChannelId}`, { + method: "DELETE", + credentials: "include", + }) + .then((response) => response.json()) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/sales-channels/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/sales-channels/' \ + -H 'Authorization: Bearer ' + ``` - + The ID of the deleted sales channel is returned in the response. @@ -425,95 +425,95 @@ The ID of the deleted sales channel is returned in the response. To add a product to a sales channel, send a request to the Sales Channel’s Add Products API Route: - + -```ts -medusa.admin.salesChannels.addProducts(salesChannelId, { - product_ids: [ - { - id: productId, - }, - ], -}) -.then(({ sales_channel }) => { - console.log(sales_channel.id) -}) -``` - - - - -```tsx -import { useAdminAddProductsToSalesChannel } from "medusa-react" - -const SalesChannel = () => { - const addProducts = useAdminAddProductsToSalesChannel( - salesChannelId - ) - // ... - - const handleAddProducts = (productId: string) => { - addProducts.mutate({ + ```ts + medusa.admin.salesChannels.addProducts(salesChannelId, { product_ids: [ { id: productId, }, ], }) - } + .then(({ sales_channel }) => { + console.log(sales_channel.id) + }) + ``` - // ... -} + + -export default SalesChannel -``` + ```tsx + import { useAdminAddProductsToSalesChannel } from "medusa-react" - - + const SalesChannel = () => { + const addProducts = useAdminAddProductsToSalesChannel( + salesChannelId + ) + // ... + + const handleAddProducts = (productId: string) => { + addProducts.mutate({ + product_ids: [ + { + id: productId, + }, + ], + }) + } + + // ... + } + + export default SalesChannel + ``` + + + -```ts -fetch( - `/admin/sales-channels/${salesChannelId}/products/batch`, - { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - product_ids: [ - { - id: productId, - }, - ], - }), - } -) -.then((response) => response.json()) -.then(({ sales_channel }) => { - console.log(sales_channel.id) -}) -``` - - - - -```bash -curl -L -X POST '/admin/sales-channels//products/batch' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "product_ids": [ + ```ts + fetch( + `/admin/sales-channels/${salesChannelId}/products/batch`, { - "id": "" + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + product_ids: [ + { + id: productId, + }, + ], + }), } - ] -}' -``` + ) + .then((response) => response.json()) + .then(({ sales_channel }) => { + console.log(sales_channel.id) + }) + ``` - + + + + ```bash + curl -L -X POST '/admin/sales-channels//products/batch' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "product_ids": [ + { + "id": "" + } + ] + }' + ``` + + This request accepts the `product_ids` body parameter, which is an array of objects. Each object in the array must have an `id` property with the ID of the product to add as a value. @@ -525,83 +525,83 @@ This request returns the sales channel. You can list the products available in a sales channel by sending a request to the List Products API Route and passing the `sales_channel_id` query parameter to filter by a specific sales channel: - + -```ts -medusa.admin.products.list({ - sales_channel_id: [ - salesChannelId, - ], -}) -.then(({ products, limit, offset, count }) => { - console.log(products.length) -}) -``` + ```ts + medusa.admin.products.list({ + sales_channel_id: [ + salesChannelId, + ], + }) + .then(({ products, limit, offset, count }) => { + console.log(products.length) + }) + ``` - - + + -```tsx -import { Product } from "@medusajs/medusa" -import { - PricedProduct, -} from "@medusajs/medusa/dist/types/pricing" -import { useAdminProducts } from "medusa-react" + ```tsx + import { Product } from "@medusajs/medusa" + import { + PricedProduct, + } from "@medusajs/medusa/dist/types/pricing" + import { useAdminProducts } from "medusa-react" -const SalesChannelProducts = () => { - const { products, isLoading } = useAdminProducts({ - sales_channel_id: [salesChannelId], - }) + const SalesChannelProducts = () => { + const { products, isLoading } = useAdminProducts({ + sales_channel_id: [salesChannelId], + }) - return ( -
- {isLoading && Loading...} - {products && products.length > 0 && ( -
    - {products.map( - (product: (Product | PricedProduct)) => ( -
  • {product.title}
  • - ) + return ( +
    + {isLoading && Loading...} + {products && products.length > 0 && ( +
      + {products.map( + (product: (Product | PricedProduct)) => ( +
    • {product.title}
    • + ) + )} +
    )} -
- )} - {products && !products.length && ( - No Products - )} -
- ) -} + {products && !products.length && ( + No Products + )} + + ) + } -export default SalesChannelProducts -``` + export default SalesChannelProducts + ``` -
- + + -```ts -fetch( - `/admin/products?sales_channel_id[0]=${salesChannelId}`, - { - credentials: "include", - } -) -.then((response) => response.json()) -.then(({ products, limit, offset, count }) => { - console.log(products.length) -}) -``` + ```ts + fetch( + `/admin/products?sales_channel_id[0]=${salesChannelId}`, + { + credentials: "include", + } + ) + .then((response) => response.json()) + .then(({ products, limit, offset, count }) => { + console.log(products.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/products?sales_channel_id[0]=' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/products?sales_channel_id[0]=' \ + -H 'Authorization: Bearer ' + ``` - +
The request returns an array of products that are available in the specified sales channel. @@ -617,99 +617,99 @@ Deleting a product from a sales channel doesn't delete it completely. It only ma You can delete a product from a sales channel by sending a request to the Sales Channel’s Delete Products API Route: - + -```ts -medusa.admin.salesChannels.removeProducts(salesChannelId, { - product_ids: [ - { - id: productId, - }, - ], -}) -.then(({ sales_channel }) => { - console.log(sales_channel.id) -}) -``` - - - - -```tsx -import { - useAdminDeleteProductsFromSalesChannel, -} from "medusa-react" - -const SalesChannel = () => { - const deleteProducts = useAdminDeleteProductsFromSalesChannel( - salesChannelId - ) - // ... - - const handleDeleteProducts = (productId: string) => { - deleteProducts.mutate({ + ```ts + medusa.admin.salesChannels.removeProducts(salesChannelId, { product_ids: [ { id: productId, }, ], }) - } + .then(({ sales_channel }) => { + console.log(sales_channel.id) + }) + ``` - // ... -} + + -export default SalesChannel -``` + ```tsx + import { + useAdminDeleteProductsFromSalesChannel, + } from "medusa-react" - - + const SalesChannel = () => { + const deleteProducts = useAdminDeleteProductsFromSalesChannel( + salesChannelId + ) + // ... + + const handleDeleteProducts = (productId: string) => { + deleteProducts.mutate({ + product_ids: [ + { + id: productId, + }, + ], + }) + } + + // ... + } + + export default SalesChannel + ``` + + + -```ts -fetch( - `/admin/sales-channels/${salesChannelId}/products/batch`, - { - method: "DELETE", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - product_ids: [ - { - id: productId, - }, - ], - }), - } -) -.then((response) => response.json()) -.then(({ sales_channel }) => { - console.log(sales_channel.id) -}) -``` - - - - -```bash -curl -L -X DELETE '/admin/sales-channels//products/batch' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "product_ids": [ + ```ts + fetch( + `/admin/sales-channels/${salesChannelId}/products/batch`, { - "id": "" + method: "DELETE", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + product_ids: [ + { + id: productId, + }, + ], + }), } - ] -}' -``` + ) + .then((response) => response.json()) + .then(({ sales_channel }) => { + console.log(sales_channel.id) + }) + ``` - + + + + ```bash + curl -L -X DELETE '/admin/sales-channels//products/batch' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "product_ids": [ + { + "id": "" + } + ] + }' + ``` + + This request accepts the `product_ids` body parameter, which is an array of objects. Each object in the array must have an `id` property with the ID of the product to delete as a value. @@ -723,77 +723,77 @@ This request returns the sales channel. You can filter orders by a specific sales channel by sending a request to the List Orders API Route and passing the `sales_channel_id` query parameter to filter by a specific sales channel: - + -```ts -medusa.admin.orders.list({ - sales_channel_id: [ - salesChannelId, - ], - limit: 50, - offset: 0, -}) -.then(({ orders, limit, offset, count }) => { - console.log(orders.length) -}) -``` + ```ts + medusa.admin.orders.list({ + sales_channel_id: [ + salesChannelId, + ], + limit: 50, + offset: 0, + }) + .then(({ orders, limit, offset, count }) => { + console.log(orders.length) + }) + ``` - - + + -```tsx -import { Order } from "@medusajs/medusa" -import { useAdminOrders } from "medusa-react" + ```tsx + import { Order } from "@medusajs/medusa" + import { useAdminOrders } from "medusa-react" -const SalesChannelOrders = () => { - const { orders, isLoading } = useAdminOrders({ - sales_channel_id: [salesChannelId], - offset: 0, - limit: 50, - }) + const SalesChannelOrders = () => { + const { orders, isLoading } = useAdminOrders({ + sales_channel_id: [salesChannelId], + offset: 0, + limit: 50, + }) - return ( -
- {isLoading && Loading...} - {orders && orders.length > 0 && ( -
    - {orders.map((order: Order) => ( -
  • {order.display_id}
  • - ))} -
- )} - {orders && !orders.length && No Orders} -
- ) -} + return ( +
+ {isLoading && Loading...} + {orders && orders.length > 0 && ( +
    + {orders.map((order: Order) => ( +
  • {order.display_id}
  • + ))} +
+ )} + {orders && !orders.length && No Orders} +
+ ) + } -export default SalesChannelOrders -``` + export default SalesChannelOrders + ``` -
- + + -```ts -fetch(`/admin/orders?sales_channel_id[0]=${salesChannelId}`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ orders, limit, offset, count }) => { - console.log(orders.length) -}) -``` + ```ts + fetch(`/admin/orders?sales_channel_id[0]=${salesChannelId}`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ orders, limit, offset, count }) => { + console.log(orders.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/orders?sales_channel_id[0]=' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/orders?sales_channel_id[0]=' \ + -H 'Authorization: Bearer ' + ``` - +
The request returns an array of orders that are associated with the specified sales channel. \ No newline at end of file diff --git a/www/apps/docs/content/modules/sales-channels/storefront/use-sales-channels.mdx b/www/apps/docs/content/modules/sales-channels/storefront/use-sales-channels.mdx index 269ff74540..2c353d4c61 100644 --- a/www/apps/docs/content/modules/sales-channels/storefront/use-sales-channels.mdx +++ b/www/apps/docs/content/modules/sales-channels/storefront/use-sales-channels.mdx @@ -56,65 +56,65 @@ For requests that use the cart, it's also assumed you already have [used CartPro To filter products by a specific sales channel, pass the `sales_channel_id` query parameter to the List Products API Route: - + -```ts -medusa.products.list({ - sales_channel_id: [ - salesChannelId, - ], -}) -.then(({ products, limit, offset, count }) => { - console.log(products.length) -}) -``` + ```ts + medusa.products.list({ + sales_channel_id: [ + salesChannelId, + ], + }) + .then(({ products, limit, offset, count }) => { + console.log(products.length) + }) + ``` - - + + -```tsx -import { Product } from "@medusajs/medusa" -import { useProducts } from "medusa-react" + ```tsx + import { Product } from "@medusajs/medusa" + import { useProducts } from "medusa-react" -const Products = () => { - const { products, isLoading } = useProducts({ - sales_channel_id: [ - salesChannelId, - ], - }) + const Products = () => { + const { products, isLoading } = useProducts({ + sales_channel_id: [ + salesChannelId, + ], + }) - return ( -
- {isLoading && Loading...} - {products && products.length > 0 && ( -
    - {products.map((product: Product) => ( -
  • {product.title}
  • - ))} -
- )} - {products && !products.length && No Products} -
- ) -} + return ( +
+ {isLoading && Loading...} + {products && products.length > 0 && ( +
    + {products.map((product: Product) => ( +
  • {product.title}
  • + ))} +
+ )} + {products && !products.length && No Products} +
+ ) + } -export default Products -``` + export default Products + ``` -
- + + -```ts -fetch(`/store/products?sales_channel_id[0]=${salesChannelId}`) -.then((response) => response.json()) -.then(({ products, limit, offset, count }) => { - console.log(products.length) -}) -``` + ```ts + fetch(`/store/products?sales_channel_id[0]=${salesChannelId}`) + .then((response) => response.json()) + .then(({ products, limit, offset, count }) => { + console.log(products.length) + }) + ``` - +
The `sales_channel_id` query parameter is an array of sales channel IDs. You can pass more than one sales channel. @@ -130,66 +130,65 @@ The request returns an array of products. These are the products that are availa To associate a sales channel with a cart while creating it, you can pass the `sales_channel_id` request body parameter with the ID of the sales channel: - + + ```ts + medusa.carts.create({ + sales_channel_id: salesChannelId, + }) + .then(({ cart }) => { + console.log(cart.id) + }) + ``` -```ts -medusa.carts.create({ - sales_channel_id: salesChannelId, -}) -.then(({ cart }) => { - console.log(cart.id) -}) -``` + + - - + ```tsx + import { useCart } from "medusa-react" -```tsx -import { useCart } from "medusa-react" + const Cart = () => { + const { cart, createCart } = useCart() -const Cart = () => { - const { cart, createCart } = useCart() - - const handleCreateCart = () => { - createCart.mutate( - { - sales_channel_id: salesChannelId, - }, - { - onSuccess: ({ cart }) => { - localStorage.setItem("cart_id", cart.id) - }, + const handleCreateCart = () => { + createCart.mutate( + { + sales_channel_id: salesChannelId, + }, + { + onSuccess: ({ cart }) => { + localStorage.setItem("cart_id", cart.id) + }, + } + ) } - ) - } - - // ... -} + + // ... + } -export default Cart -``` + export default Cart + ``` - - + + -```ts -fetch(`/store/carts`, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - sales_channel_id: salesChannelId, - }), -}) -.then((response) => response.json()) -.then(({ cart }) => { - console.log(cart.id) -}) -``` + ```ts + fetch(`/store/carts`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + sales_channel_id: salesChannelId, + }), + }) + .then((response) => response.json()) + .then(({ cart }) => { + console.log(cart.id) + }) + ``` - + The request returns the created cart. @@ -199,58 +198,58 @@ The request returns the created cart. You can update the sales channel of an existing cart by passing the `sales_channel_id` request body parameter with the ID of the sales channel: - + -```ts -medusa.carts.update(cartId, { - sales_channel_id: salesChannelId, -}) -.then(({ cart }) => { - console.log(cart.id) -}) -``` - - - - -```tsx -import { useCart } from "medusa-react" - -const Cart = () => { - // ... - - const { updateCart } = useCart() - - const changeSalesChannel = (salesChannelId: string) => { - updateCart.mutate({ + ```ts + medusa.carts.update(cartId, { sales_channel_id: salesChannelId, }) - } + .then(({ cart }) => { + console.log(cart.id) + }) + ``` - // ... -} + + -export default Cart -``` + ```tsx + import { useCart } from "medusa-react" - - + const Cart = () => { + // ... -```ts -fetch(`/store/carts/${cartId}`, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - sales_channel_id: salesChannelId, - }), -}) -.then((response) => response.json()) -.then(({ cart }) => console.log(cart.id)) -``` + const { updateCart } = useCart() - + const changeSalesChannel = (salesChannelId: string) => { + updateCart.mutate({ + sales_channel_id: salesChannelId, + }) + } + + // ... + } + + export default Cart + ``` + + + + + ```ts + fetch(`/store/carts/${cartId}`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + sales_channel_id: salesChannelId, + }), + }) + .then((response) => response.json()) + .then(({ cart }) => console.log(cart.id)) + ``` + + The request returns the updated cart. \ No newline at end of file diff --git a/www/apps/docs/content/modules/taxes/admin/manage-tax-rates.mdx b/www/apps/docs/content/modules/taxes/admin/manage-tax-rates.mdx index c9da76a803..3099f3b994 100644 --- a/www/apps/docs/content/modules/taxes/admin/manage-tax-rates.mdx +++ b/www/apps/docs/content/modules/taxes/admin/manage-tax-rates.mdx @@ -54,66 +54,66 @@ You can learn more about [authenticating as an admin user in the API reference]( You can list the tax rates by sending a request to the [List Tax Rates API Route](https://docs.medusajs.com/api/admin#tax-rates_gettaxrates): - + -```ts -medusa.admin.taxRates.list() -.then(({ tax_rates, limit, offset, count }) => { - console.log(tax_rates.length) -}) -``` + ```ts + medusa.admin.taxRates.list() + .then(({ tax_rates, limit, offset, count }) => { + console.log(tax_rates.length) + }) + ``` - - + + -```tsx -import { useAdminTaxRates } from "medusa-react" + ```tsx + import { useAdminTaxRates } from "medusa-react" -const TaxRates = () => { - const { tax_rates, isLoading } = useAdminTaxRates() + const TaxRates = () => { + const { tax_rates, isLoading } = useAdminTaxRates() - return ( -
- {isLoading && Loading...} - {tax_rates && !tax_rates.length && ( - No Tax Rates - )} - {tax_rates && tax_rates.length > 0 && ( -
    - {tax_rates.map((tax_rate) => ( -
  • {tax_rate.code}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {tax_rates && !tax_rates.length && ( + No Tax Rates + )} + {tax_rates && tax_rates.length > 0 && ( +
    + {tax_rates.map((tax_rate) => ( +
  • {tax_rate.code}
  • + ))} +
+ )} +
+ ) + } -export default TaxRates -``` + export default TaxRates + ``` -
- + + -```ts -fetch(`/admin/tax-rates`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ tax_rates, limit, offset, count }) => { - console.log(tax_rates.length) -}) -``` + ```ts + fetch(`/admin/tax-rates`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ tax_rates, limit, offset, count }) => { + console.log(tax_rates.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/tax-rates' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/tax-rates' \ + -H 'Authorization: Bearer ' + ``` - +
You can pass to this API Route filter and search parameters as explained in the [API reference](https://docs.medusajs.com/api/admin#tax-rates_gettaxrates). @@ -125,70 +125,70 @@ The API Route returns an array of tax rate objects along with [pagination parame You can retrieve the tax rate of a region by passing the `region_id` query parameter: - + -```ts -medusa.admin.taxRates.list({ - region_id: "reg_123", -}) -.then(({ tax_rates, limit, offset, count }) => { - console.log(tax_rates.length) -}) -``` + ```ts + medusa.admin.taxRates.list({ + region_id: "reg_123", + }) + .then(({ tax_rates, limit, offset, count }) => { + console.log(tax_rates.length) + }) + ``` - - + + -```tsx -import { useAdminTaxRates } from "medusa-react" + ```tsx + import { useAdminTaxRates } from "medusa-react" -const TaxRates = () => { - const { tax_rates, isLoading } = useAdminTaxRates({ - region_id: "reg_123", - }) + const TaxRates = () => { + const { tax_rates, isLoading } = useAdminTaxRates({ + region_id: "reg_123", + }) - return ( -
- {isLoading && Loading...} - {tax_rates && !tax_rates.length && ( - No Tax Rates - )} - {tax_rates && tax_rates.length > 0 && ( -
    - {tax_rates.map((tax_rate) => ( -
  • {tax_rate.code}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {tax_rates && !tax_rates.length && ( + No Tax Rates + )} + {tax_rates && tax_rates.length > 0 && ( +
    + {tax_rates.map((tax_rate) => ( +
  • {tax_rate.code}
  • + ))} +
+ )} +
+ ) + } -export default TaxRates -``` + export default TaxRates + ``` -
- + + -```ts -fetch(`/admin/tax-rates?region_id=reg_123`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ tax_rates, limit, offset, count }) => { - console.log(tax_rates.length) -}) -``` + ```ts + fetch(`/admin/tax-rates?region_id=reg_123`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ tax_rates, limit, offset, count }) => { + console.log(tax_rates.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/tax-rates?region_id=reg_123' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/tax-rates?region_id=reg_123' \ + -H 'Authorization: Bearer ' + ``` - +
In the example above, you pass the region’s ID as the value of the `region_id` query parameter. @@ -196,72 +196,72 @@ In the example above, you pass the region’s ID as the value of the `region_id` This query parameter also accepts an array of strings, allowing you to filter the tax rates by more than one region: - + -```ts -medusa.admin.taxRates.list({ - region_id: ["reg_123", "reg_456"], -}) -.then(({ tax_rates, limit, offset, count }) => { - console.log(tax_rates.length) -}) -``` + ```ts + medusa.admin.taxRates.list({ + region_id: ["reg_123", "reg_456"], + }) + .then(({ tax_rates, limit, offset, count }) => { + console.log(tax_rates.length) + }) + ``` - - + + -```tsx -import { useAdminTaxRates } from "medusa-react" + ```tsx + import { useAdminTaxRates } from "medusa-react" -const TaxRates = () => { - const { tax_rates, isLoading } = useAdminTaxRates({ - region_id: ["reg_123", "reg_456"], - }) + const TaxRates = () => { + const { tax_rates, isLoading } = useAdminTaxRates({ + region_id: ["reg_123", "reg_456"], + }) - return ( -
- {isLoading && Loading...} - {tax_rates && !tax_rates.length && ( - No Tax Rates - )} - {tax_rates && tax_rates.length > 0 && ( -
    - {tax_rates.map((tax_rate) => ( -
  • {tax_rate.code}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {tax_rates && !tax_rates.length && ( + No Tax Rates + )} + {tax_rates && tax_rates.length > 0 && ( +
    + {tax_rates.map((tax_rate) => ( +
  • {tax_rate.code}
  • + ))} +
+ )} +
+ ) + } -export default TaxRates -``` + export default TaxRates + ``` -
- + + -```ts -fetch(`/admin/tax-rates?region_id[]=reg_123®ion_id[]=reg_456`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ tax_rates, limit, offset, count }) => { - console.log(tax_rates.length) -}) -``` + ```ts + fetch(`/admin/tax-rates?region_id[]=reg_123®ion_id[]=reg_456`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ tax_rates, limit, offset, count }) => { + console.log(tax_rates.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/tax-rates?region_id[]=reg_123®ion_id[]=reg_456' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/tax-rates?region_id[]=reg_123®ion_id[]=reg_456' \ + -H 'Authorization: Bearer ' + ``` - +
--- @@ -271,84 +271,84 @@ curl -L -X GET '/admin/tax-rates?region_id[]=reg_123®ion_id[]=re You can create a tax rate by sending a request to the [Create Tax Rate API Route](https://docs.medusajs.com/api/admin#tax-rates_posttaxrates): - + -```ts -medusa.admin.taxRates.create({ - code: "TEST", - name: "New Tax Rate", - region_id, - rate: 10, -}) -.then(({ tax_rate }) => { - console.log(tax_rate.id) -}) -``` - - - - -```tsx -import { useAdminCreateTaxRate } from "medusa-react" - -const CreateTaxRate = () => { - const createTaxRate = useAdminCreateTaxRate() - // ... - - const handleCreate = () => { - createTaxRate.mutate({ + ```ts + medusa.admin.taxRates.create({ code: "TEST", name: "New Tax Rate", region_id, rate: 10, }) - } + .then(({ tax_rate }) => { + console.log(tax_rate.id) + }) + ``` - // ... -} + + -export default CreateTaxRate -``` + ```tsx + import { useAdminCreateTaxRate } from "medusa-react" - - + const CreateTaxRate = () => { + const createTaxRate = useAdminCreateTaxRate() + // ... -```ts -fetch(`/admin/tax-rates`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - code: "TEST", - name: "New Tax Rate", - region_id, - rate: 10, - }), -}) -.then((response) => response.json()) -.then(({ tax_rate }) => { - console.log(tax_rate.id) -}) -``` + const handleCreate = () => { + createTaxRate.mutate({ + code: "TEST", + name: "New Tax Rate", + region_id, + rate: 10, + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/tax-rates' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "code": "TEST", - "name": "New Tax Rate", - "region_id": "", - "rate": 10 -}' -``` + export default CreateTaxRate + ``` - + + + + ```ts + fetch(`/admin/tax-rates`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + code: "TEST", + name: "New Tax Rate", + region_id, + rate: 10, + }), + }) + .then((response) => response.json()) + .then(({ tax_rate }) => { + console.log(tax_rate.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/tax-rates' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "code": "TEST", + "name": "New Tax Rate", + "region_id": "", + "rate": 10 + }' + ``` + + This API Route requires the following body parameters: @@ -374,72 +374,72 @@ The request returns the created tax rate as an object. You can update a tax rate by sending a request to the [Update Tax Rate API Route](https://docs.medusajs.com/api/admin#tax-rates_posttaxratestaxrate): - + -```ts -medusa.admin.taxRates.update(taxRateId, { - name: "New Tax Rate", -}) -.then(({ tax_rate }) => { - console.log(tax_rate.id) -}) -``` - - - - -```tsx -import { useAdminUpdateTaxRate } from "medusa-react" - -const UpdateTaxRate = () => { - const updateTaxRate = useAdminUpdateTaxRate(taxRateId) - // ... - - const handleUpdate = () => { - updateTaxRate.mutate({ + ```ts + medusa.admin.taxRates.update(taxRateId, { name: "New Tax Rate", }) - } + .then(({ tax_rate }) => { + console.log(tax_rate.id) + }) + ``` - // ... -} + + -export default UpdateTaxRate -``` + ```tsx + import { useAdminUpdateTaxRate } from "medusa-react" - - + const UpdateTaxRate = () => { + const updateTaxRate = useAdminUpdateTaxRate(taxRateId) + // ... -```ts -fetch(`/admin/tax-rates/${taxRateId}`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - name: "New Tax Rate", - }), -}) -.then((response) => response.json()) -.then(({ tax_rate }) => { - console.log(tax_rate.id) -}) -``` + const handleUpdate = () => { + updateTaxRate.mutate({ + name: "New Tax Rate", + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/tax-rates/' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "name": "New Tax Rate" -}' -``` + export default UpdateTaxRate + ``` - + + + + ```ts + fetch(`/admin/tax-rates/${taxRateId}`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + name: "New Tax Rate", + }), + }) + .then((response) => response.json()) + .then(({ tax_rate }) => { + console.log(tax_rate.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/tax-rates/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "name": "New Tax Rate" + }' + ``` + + This API Route requires the tax rate ID to be passed as a path parameter. @@ -459,82 +459,82 @@ This section explains how you can add and remove products from a tax rate. You can add a product to a tax rate by sending a request to the [Add Products API Route](https://docs.medusajs.com/api/admin#tax-rates_posttaxratestaxrateproducts): - + -```ts -medusa.admin.taxRates.addProducts(taxRateId, { - products: [ - productId1, - ], -}) -.then(({ tax_rate }) => { - console.log(tax_rate.products) -}) -``` - - - - -```tsx -import { useAdminCreateProductTaxRates } from "medusa-react" - -const AddProduct = () => { - const addProduct = useAdminCreateProductTaxRates(taxRateId) - // ... - - const handleAdd = () => { - addProduct.mutate({ + ```ts + medusa.admin.taxRates.addProducts(taxRateId, { products: [ productId1, ], }) - } + .then(({ tax_rate }) => { + console.log(tax_rate.products) + }) + ``` - // ... -} + + -export default AddProduct -``` + ```tsx + import { useAdminCreateProductTaxRates } from "medusa-react" - - + const AddProduct = () => { + const addProduct = useAdminCreateProductTaxRates(taxRateId) + // ... + + const handleAdd = () => { + addProduct.mutate({ + products: [ + productId1, + ], + }) + } + + // ... + } + + export default AddProduct + ``` + + + -```ts -fetch(`/admin/tax-rates/${taxRateId}/products/batch`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - products: [ - productId1, - ], - }), -}) -.then((response) => response.json()) -.then(({ tax_rate }) => { - console.log(tax_rate.products) -}) -``` + ```ts + fetch(`/admin/tax-rates/${taxRateId}/products/batch`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + products: [ + productId1, + ], + }), + }) + .then((response) => response.json()) + .then(({ tax_rate }) => { + console.log(tax_rate.products) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/tax-rates//products/batch' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "products": [ - "" - ] -}' -``` + ```bash + curl -L -X POST '/admin/tax-rates//products/batch' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "products": [ + "" + ] + }' + ``` - + This API Route requires the tax rate’s ID as a path parameter. @@ -548,82 +548,82 @@ The request returns the updated tax rate as an object. You can access the tax ra You can remove a product from a tax rate by sending a request to the [Delete Products API Route](https://docs.medusajs.com/api/admin#tax-rates_deletetaxratestaxrateproducts): - + -```ts -medusa.admin.taxRates.removeProducts(taxRateId, { - products: [ - productId1, - ], -}) -.then(({ tax_rate }) => { - console.log(tax_rate.products) -}) -``` - - - - -```tsx -import { useAdminDeleteProductTaxRates } from "medusa-react" - -const RemoveProduct = () => { - const removeProduct = useAdminDeleteProductTaxRates(taxRateId) - // ... - - const handleRemove = () => { - removeProduct.mutate({ + ```ts + medusa.admin.taxRates.removeProducts(taxRateId, { products: [ productId1, ], }) - } + .then(({ tax_rate }) => { + console.log(tax_rate.products) + }) + ``` - // ... -} + + -export default RemoveProduct -``` + ```tsx + import { useAdminDeleteProductTaxRates } from "medusa-react" - - + const RemoveProduct = () => { + const removeProduct = useAdminDeleteProductTaxRates(taxRateId) + // ... + + const handleRemove = () => { + removeProduct.mutate({ + products: [ + productId1, + ], + }) + } + + // ... + } + + export default RemoveProduct + ``` + + + -```ts -fetch(`/admin/tax-rates/${taxRateId}/products/batch`, { - credentials: "include", - method: "DELETE", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - products: [ - productId1, - ], - }), -}) -.then((response) => response.json()) -.then(({ tax_rate }) => { - console.log(tax_rate.products) -}) -``` + ```ts + fetch(`/admin/tax-rates/${taxRateId}/products/batch`, { + credentials: "include", + method: "DELETE", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + products: [ + productId1, + ], + }), + }) + .then((response) => response.json()) + .then(({ tax_rate }) => { + console.log(tax_rate.products) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/tax-rates//products/batch' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "products": [ - "" - ] -}' -``` + ```bash + curl -L -X DELETE '/admin/tax-rates//products/batch' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "products": [ + "" + ] + }' + ``` - + This API Route requires the tax rate’s ID as a path parameter. @@ -643,86 +643,86 @@ This section explains how you can add and remove product types from a tax rate. You can add a product type to a tax rate by sending a request to the [Add Product Types API Route](https://docs.medusajs.com/api/admin#tax-rates_posttaxratestaxrateproducttypes): - + -```ts -medusa.admin.taxRates.addProductTypes(taxRateId, { - product_types: [ - productTypeId, - ], -}) -.then(({ tax_rate }) => { - console.log(tax_rate.product_types) -}) -``` - - - - -```tsx -import { - useAdminCreateProductTypeTaxRates, -} from "medusa-react" - -const AddProductTypes = () => { - const addProductTypes = useAdminCreateProductTypeTaxRates( - taxRateId - ) - // ... - - const handleAdd = () => { - addProductTypes.mutate({ + ```ts + medusa.admin.taxRates.addProductTypes(taxRateId, { product_types: [ productTypeId, ], }) - } + .then(({ tax_rate }) => { + console.log(tax_rate.product_types) + }) + ``` - // ... -} + + -export default AddProductTypes -``` + ```tsx + import { + useAdminCreateProductTypeTaxRates, + } from "medusa-react" - - + const AddProductTypes = () => { + const addProductTypes = useAdminCreateProductTypeTaxRates( + taxRateId + ) + // ... + + const handleAdd = () => { + addProductTypes.mutate({ + product_types: [ + productTypeId, + ], + }) + } + + // ... + } + + export default AddProductTypes + ``` + + + -```ts -fetch(`/admin/tax-rates/${taxRateId}/product-types/batch`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - product_types: [ - productTypeId, - ], - }), -}) -.then((response) => response.json()) -.then(({ tax_rate }) => { - console.log(tax_rate.product_types) -}) -``` + ```ts + fetch(`/admin/tax-rates/${taxRateId}/product-types/batch`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + product_types: [ + productTypeId, + ], + }), + }) + .then((response) => response.json()) + .then(({ tax_rate }) => { + console.log(tax_rate.product_types) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/tax-rates//product-types/batch' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "product_types": [ - "" - ] -}' -``` + ```bash + curl -L -X POST '/admin/tax-rates//product-types/batch' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "product_types": [ + "" + ] + }' + ``` - + This API Route requires the tax rate’s ID as a path parameter. @@ -736,86 +736,86 @@ The request returns the updated tax rate as an object. You can access the tax ra You can remove a product type from a tax rate by sending a request to the [Delete Product Types API Route](https://docs.medusajs.com/api/admin#tax-rates_deletetaxratestaxrateproducttypes): - + -```ts -medusa.admin.taxRates.removeProductTypes(taxRateId, { - product_types: [ - productTypeId, - ], -}) -.then(({ tax_rate }) => { - console.log(tax_rate.product_types) -}) -``` - - - - -```tsx -import { - useAdminDeleteProductTypeTaxRates, -} from "medusa-react" - -const RemoveProductTypes = () => { - const removeProductTypes = useAdminDeleteProductTypeTaxRates( - taxRateId - ) - // ... - - const handleRemove = () => { - removeProductTypes.mutate({ + ```ts + medusa.admin.taxRates.removeProductTypes(taxRateId, { product_types: [ productTypeId, ], }) - } + .then(({ tax_rate }) => { + console.log(tax_rate.product_types) + }) + ``` - // ... -} + + -export default RemoveProductTypes -``` + ```tsx + import { + useAdminDeleteProductTypeTaxRates, + } from "medusa-react" - - + const RemoveProductTypes = () => { + const removeProductTypes = useAdminDeleteProductTypeTaxRates( + taxRateId + ) + // ... + + const handleRemove = () => { + removeProductTypes.mutate({ + product_types: [ + productTypeId, + ], + }) + } + + // ... + } + + export default RemoveProductTypes + ``` + + + -```ts -fetch(`/admin/tax-rates/${taxRateId}/product-types/batch`, { - credentials: "include", - method: "DELETE", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - product_types: [ - productTypeId, - ], - }), -}) -.then((response) => response.json()) -.then(({ tax_rate }) => { - console.log(tax_rate.id) -}) -``` + ```ts + fetch(`/admin/tax-rates/${taxRateId}/product-types/batch`, { + credentials: "include", + method: "DELETE", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + product_types: [ + productTypeId, + ], + }), + }) + .then((response) => response.json()) + .then(({ tax_rate }) => { + console.log(tax_rate.id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/tax-rates//product-types/batch' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "product_types": [ - "" - ] -}' -``` + ```bash + curl -L -X DELETE '/admin/tax-rates//product-types/batch' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "product_types": [ + "" + ] + }' + ``` - + This API Route requires the tax rate’s ID as a path parameter. @@ -835,84 +835,84 @@ This section explains how you can add and remove shipping options from a tax rat You can add a shipping option to a tax rate by sending a request to the [Add Shipping Option API Route](https://docs.medusajs.com/api/admin#tax-rates_posttaxratestaxrateshippingoptions): - + -```ts -medusa.admin.taxRates.addShippingOptions(taxRateId, { - shipping_options: [ - shippingOptionId, - ], -}) -.then(({ tax_rate }) => { - console.log(tax_rate.shipping_options) -}) -``` - - - - -```tsx -import { useAdminCreateShippingTaxRates } from "medusa-react" - -const AddShippingOptions = () => { - const addShippingOption = useAdminCreateShippingTaxRates( - taxRateId - ) - // ... - - const handleAdd = () => { - addShippingOption.mutate({ + ```ts + medusa.admin.taxRates.addShippingOptions(taxRateId, { shipping_options: [ shippingOptionId, ], }) - } + .then(({ tax_rate }) => { + console.log(tax_rate.shipping_options) + }) + ``` - // ... -} + + -export default AddShippingOptions -``` + ```tsx + import { useAdminCreateShippingTaxRates } from "medusa-react" - - + const AddShippingOptions = () => { + const addShippingOption = useAdminCreateShippingTaxRates( + taxRateId + ) + // ... + + const handleAdd = () => { + addShippingOption.mutate({ + shipping_options: [ + shippingOptionId, + ], + }) + } + + // ... + } + + export default AddShippingOptions + ``` + + + -```ts -fetch(`/admin/tax-rates/${taxRateId}/shipping-options/batch`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - shipping_options: [ - shippingOptionId, - ], - }), -}) -.then((response) => response.json()) -.then(({ tax_rate }) => { - console.log(tax_rate.shipping_options) -}) -``` + ```ts + fetch(`/admin/tax-rates/${taxRateId}/shipping-options/batch`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + shipping_options: [ + shippingOptionId, + ], + }), + }) + .then((response) => response.json()) + .then(({ tax_rate }) => { + console.log(tax_rate.shipping_options) + }) + ``` - - + + -```bash -curl -L -X POST '/admin/tax-rates//shipping-options/batch' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "shipping_options": [ - "" - ] -}' -``` + ```bash + curl -L -X POST '/admin/tax-rates//shipping-options/batch' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "shipping_options": [ + "" + ] + }' + ``` - + This API Route requires the tax rate’s ID as a path parameter. @@ -926,84 +926,84 @@ The request returns the updated tax rate as an object. You can access the tax ra You can remove a shipping option from a tax rate by sending a request to the [Delete Shipping Options API Route](https://docs.medusajs.com/api/admin#tax-rates_deletetaxratestaxrateshippingoptions): - + -```ts -medusa.admin.taxRates.removeShippingOptions(taxRateId, { - shipping_options: [ - shippingOptionId, - ], -}) -.then(({ tax_rate }) => { - console.log(tax_rate.shipping_options) -}) -``` - - - - -```tsx -import { useAdminDeleteShippingTaxRates } from "medusa-react" - -const RemoveShippingOptions = () => { - const removeShippingOptions = useAdminDeleteShippingTaxRates( - taxRateId - ) - // ... - - const handleRemove = () => { - removeShippingOptions.mutate({ + ```ts + medusa.admin.taxRates.removeShippingOptions(taxRateId, { shipping_options: [ shippingOptionId, ], }) - } + .then(({ tax_rate }) => { + console.log(tax_rate.shipping_options) + }) + ``` - // ... -} + + -export default RemoveShippingOptions -``` + ```tsx + import { useAdminDeleteShippingTaxRates } from "medusa-react" - - + const RemoveShippingOptions = () => { + const removeShippingOptions = useAdminDeleteShippingTaxRates( + taxRateId + ) + // ... + + const handleRemove = () => { + removeShippingOptions.mutate({ + shipping_options: [ + shippingOptionId, + ], + }) + } + + // ... + } + + export default RemoveShippingOptions + ``` + + + -```ts -fetch(`/admin/tax-rates/${taxRateId}/shipping-options/batch`, { - credentials: "include", - method: "DELETE", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - shipping_options: [ - shippingOptionId, - ], - }), -}) -.then((response) => response.json()) -.then(({ tax_rate }) => { - console.log(tax_rate.shipping_options) -}) -``` + ```ts + fetch(`/admin/tax-rates/${taxRateId}/shipping-options/batch`, { + credentials: "include", + method: "DELETE", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + shipping_options: [ + shippingOptionId, + ], + }), + }) + .then((response) => response.json()) + .then(({ tax_rate }) => { + console.log(tax_rate.shipping_options) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/tax-rates//shipping-options/batch' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "shipping_options": [ - "" - ] -}' -``` + ```bash + curl -L -X DELETE '/admin/tax-rates//shipping-options/batch' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "shipping_options": [ + "" + ] + }' + ``` - + This API Route requires the tax rate’s ID as a path parameter. @@ -1019,58 +1019,58 @@ The request returns the updated tax rate as an object. You can access the tax ra You can delete a tax rate by sending a request to the [Delete Tax Rate API Route](https://docs.medusajs.com/api/admin#tax-rates_deletetaxratestaxrate): - + -```ts -medusa.admin.taxRates.delete(taxRateId) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + medusa.admin.taxRates.delete(taxRateId) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```tsx -import { useAdminDeleteTaxRate } from "medusa-react" + ```tsx + import { useAdminDeleteTaxRate } from "medusa-react" -const DeleteTaxRate = () => { - const deleteTaxRate = useAdminDeleteTaxRate(taxRateId) - // ... + const DeleteTaxRate = () => { + const deleteTaxRate = useAdminDeleteTaxRate(taxRateId) + // ... - const handleDelete = () => { - deleteTaxRate.mutate() - } + const handleDelete = () => { + deleteTaxRate.mutate() + } - // ... -} + // ... + } -export default DeleteTaxRate -``` + export default DeleteTaxRate + ``` - - + + -```ts -fetch(`/admin/tax-rates/${taxRateId}`, { - credentials: "include", - method: "DELETE", -}) -.then((response) => response.json()) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + fetch(`/admin/tax-rates/${taxRateId}`, { + credentials: "include", + method: "DELETE", + }) + .then((response) => response.json()) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/tax-rates/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/tax-rates/' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the tax rate’s ID as a path parameter. diff --git a/www/apps/docs/content/modules/taxes/admin/manage-tax-settings.mdx b/www/apps/docs/content/modules/taxes/admin/manage-tax-settings.mdx index af59a5037a..37855134d7 100644 --- a/www/apps/docs/content/modules/taxes/admin/manage-tax-settings.mdx +++ b/www/apps/docs/content/modules/taxes/admin/manage-tax-settings.mdx @@ -55,69 +55,69 @@ You can learn more about [authenticating as an admin user in the API reference]( You can list all tax providers of a store using the [List Tax Providers API Route](https://docs.medusajs.com/api/admin#store_getstoretaxproviders): - + -```ts -medusa.admin.store.listTaxProviders() -.then(({ tax_providers }) => { - console.log(tax_providers.length) -}) -``` + ```ts + medusa.admin.store.listTaxProviders() + .then(({ tax_providers }) => { + console.log(tax_providers.length) + }) + ``` - - + + -```tsx -import { useAdminStoreTaxProviders } from "medusa-react" + ```tsx + import { useAdminStoreTaxProviders } from "medusa-react" -const TaxProviders = () => { - const { - tax_providers, - isLoading, - } = useAdminStoreTaxProviders() + const TaxProviders = () => { + const { + tax_providers, + isLoading, + } = useAdminStoreTaxProviders() - return ( -
- {isLoading && Loading...} - {tax_providers && !tax_providers.length && ( - No Tax Providers - )} - {tax_providers && tax_providers.length > 0 && ( -
    - {tax_providers.map((tax_provider) => ( -
  • {tax_provider.id}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {tax_providers && !tax_providers.length && ( + No Tax Providers + )} + {tax_providers && tax_providers.length > 0 && ( +
    + {tax_providers.map((tax_provider) => ( +
  • {tax_provider.id}
  • + ))} +
+ )} +
+ ) + } -export default TaxProviders -``` + export default TaxProviders + ``` -
- + + -```ts -fetch(`/admin/store/tax-providers`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ tax_providers }) => { - console.log(tax_providers.length) -}) -``` + ```ts + fetch(`/admin/store/tax-providers`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ tax_providers }) => { + console.log(tax_providers.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/store/tax-providers' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/store/tax-providers' \ + -H 'Authorization: Bearer ' + ``` - +
This API Route doesn't accept any parameters. @@ -131,72 +131,72 @@ The request returns an array of tax provider objects. You can change the tax provider of a region using the [Update Region API Route](https://docs.medusajs.com/api/admin#regions_postregionsregion): - + -```ts -medusa.admin.regions.update(regionId, { - tax_provider_id, -}) -.then(({ region }) => { - console.log(region.id) -}) -``` - - - - -```tsx -import { useAdminUpdateRegion } from "medusa-react" - -const UpdateRegion = () => { - const updateRegion = useAdminUpdateRegion(regionId) - // ... - - const handleUpdate = () => { - updateRegion.mutate({ + ```ts + medusa.admin.regions.update(regionId, { tax_provider_id, }) - } + .then(({ region }) => { + console.log(region.id) + }) + ``` - // ... -} + + -export default UpdateRegion -``` + ```tsx + import { useAdminUpdateRegion } from "medusa-react" - - + const UpdateRegion = () => { + const updateRegion = useAdminUpdateRegion(regionId) + // ... -```ts -fetch(`/admin/regions/${regionId}`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - tax_provider_id, - }), -}) -.then((response) => response.json()) -.then(({ region }) => { - console.log(region.id) -}) -``` + const handleUpdate = () => { + updateRegion.mutate({ + tax_provider_id, + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/regions/' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "tax_provider_id": "" -}' -``` + export default UpdateRegion + ``` - + + + + ```ts + fetch(`/admin/regions/${regionId}`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + tax_provider_id, + }), + }) + .then((response) => response.json()) + .then(({ region }) => { + console.log(region.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/regions/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "tax_provider_id": "" + }' + ``` + + This API Route requires the ID of the region to be passed as a path parameter. @@ -212,88 +212,88 @@ The request returns the updated region as an object. In addition to changing the tax provider, you can use the same [Update Region API Route](https://docs.medusajs.com/api/admin#regions_postregionsregion) to update the region’s other tax settings: - + -```ts -medusa.admin.regions.update(regionId, { - tax_provider_id, - automatic_taxes, - gift_cards_taxable, - tax_code, - tax_rate, -}) -.then(({ region }) => { - console.log(region.id) -}) -``` - - - - -```tsx -import { useAdminUpdateRegion } from "medusa-react" - -const UpdateRegion = () => { - const updateRegion = useAdminUpdateRegion(regionId) - // ... - - const handleUpdate = () => { - updateRegion.mutate({ + ```ts + medusa.admin.regions.update(regionId, { tax_provider_id, automatic_taxes, gift_cards_taxable, tax_code, tax_rate, }) - } + .then(({ region }) => { + console.log(region.id) + }) + ``` - // ... -} + + -export default UpdateRegion -``` + ```tsx + import { useAdminUpdateRegion } from "medusa-react" - - + const UpdateRegion = () => { + const updateRegion = useAdminUpdateRegion(regionId) + // ... -```ts -fetch(`/admin/regions/${regionId}`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - tax_provider_id, - automatic_taxes, - gift_cards_taxable, - tax_code, - tax_rate, - }), -}) -.then((response) => response.json()) -.then(({ region }) => { - console.log(region.id) -}) -``` + const handleUpdate = () => { + updateRegion.mutate({ + tax_provider_id, + automatic_taxes, + gift_cards_taxable, + tax_code, + tax_rate, + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/regions/' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "tax_provider_id": "", - "automatic_taxes": true, - "gift_cards_taxable": true, - "tax_code": "", - "tax_rate": 10 -}' -``` + export default UpdateRegion + ``` - + + + + ```ts + fetch(`/admin/regions/${regionId}`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + tax_provider_id, + automatic_taxes, + gift_cards_taxable, + tax_code, + tax_rate, + }), + }) + .then((response) => response.json()) + .then(({ region }) => { + console.log(region.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/regions/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "tax_provider_id": "", + "automatic_taxes": true, + "gift_cards_taxable": true, + "tax_code": "", + "tax_rate": 10 + }' + ``` + + You can pass the following parameters in the body of the request that are related to tax settings: diff --git a/www/apps/docs/content/modules/users/admin/manage-invites.mdx b/www/apps/docs/content/modules/users/admin/manage-invites.mdx index af023d81d8..a79a2259fe 100644 --- a/www/apps/docs/content/modules/users/admin/manage-invites.mdx +++ b/www/apps/docs/content/modules/users/admin/manage-invites.mdx @@ -57,64 +57,64 @@ You can learn more about [authenticating as an admin user in the API reference]( You can list invites by sending a request to the [List Invite API Route](https://docs.medusajs.com/api/admin#invites_getinvites): - + -```ts -medusa.admin.invites.list() -.then(({ invites }) => { - console.log(invites.length) -}) -``` + ```ts + medusa.admin.invites.list() + .then(({ invites }) => { + console.log(invites.length) + }) + ``` - - + + -```tsx -import { useAdminInvites } from "medusa-react" + ```tsx + import { useAdminInvites } from "medusa-react" -const Invites = () => { - const { invites, isLoading } = useAdminInvites() + const Invites = () => { + const { invites, isLoading } = useAdminInvites() - return ( -
- {isLoading && Loading...} - {invites && !invites.length && No Invites} - {invites && invites.length > 0 && ( -
    - {invites.map((invite) => ( -
  • {invite.user_email}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {invites && !invites.length && No Invites} + {invites && invites.length > 0 && ( +
    + {invites.map((invite) => ( +
  • {invite.user_email}
  • + ))} +
+ )} +
+ ) + } -export default Invites -``` + export default Invites + ``` -
- + + -```ts -fetch(`/admin/invites`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ invites }) => { - console.log(invites.length) -}) -``` + ```ts + fetch(`/admin/invites`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ invites }) => { + console.log(invites.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/invites' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/invites' \ + -H 'Authorization: Bearer ' + ``` - +
This API Route doesn't accept any parameters. @@ -128,76 +128,76 @@ The request returns an array of invite objects. You can create an invite by sending a request to the [Create Invite API Route](https://docs.medusajs.com/api/admin#invites_postinvites): - + -```ts -medusa.admin.invites.create({ - user: "user@example.com", - role: "admin", -}) -.then(() => { - // successful -}) -``` - - - - -```tsx -import { useAdminCreateInvite } from "medusa-react" - -const CreateInvite = () => { - const createInvite = useAdminCreateInvite() - // ... - - const handleCreate = () => { - createInvite.mutate({ + ```ts + medusa.admin.invites.create({ user: "user@example.com", role: "admin", }) - } + .then(() => { + // successful + }) + ``` - // ... -} + + -export default CreateInvite -``` + ```tsx + import { useAdminCreateInvite } from "medusa-react" - - + const CreateInvite = () => { + const createInvite = useAdminCreateInvite() + // ... -```ts -fetch(`/admin/invites`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - user: "user@example.com", - role: "admin", - }), -}) -.then((response) => response.json()) -.then(() => { - // successful -}) -``` + const handleCreate = () => { + createInvite.mutate({ + user: "user@example.com", + role: "admin", + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/invites' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "user": "user@example.com", - "role": "admin" -}' -``` + export default CreateInvite + ``` - + + + + ```ts + fetch(`/admin/invites`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + user: "user@example.com", + role: "admin", + }), + }) + .then((response) => response.json()) + .then(() => { + // successful + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/invites' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "user": "user@example.com", + "role": "admin" + }' + ``` + + This API Route requires the following body parameters: @@ -216,34 +216,10 @@ A logged-out user can accept an invite, which would create a user for that user. You can accept an invite by sending a request to the [Accept Invite API Route](https://docs.medusajs.com/api/admin#invites_postinvitesinviteaccept): - + -```ts -medusa.admin.invites.accept({ - token, - user: { - first_name: "Brigitte", - last_name: "Collier", - password: "supersecret", - }, -}) -.then(() => { - // successful -}) -``` - - - - -```tsx -import { useAdminAcceptInvite } from "medusa-react" - -const AcceptInvite = () => { - const acceptInvite = useAdminAcceptInvite() - // ... - - const handleAccept = () => { - acceptInvite.mutate({ + ```ts + medusa.admin.invites.accept({ token, user: { first_name: "Brigitte", @@ -251,56 +227,80 @@ const AcceptInvite = () => { password: "supersecret", }, }) - } + .then(() => { + // successful + }) + ``` - // ... -} + + -export default AcceptInvite -``` + ```tsx + import { useAdminAcceptInvite } from "medusa-react" - - + const AcceptInvite = () => { + const acceptInvite = useAdminAcceptInvite() + // ... -```ts -fetch(`/admin/invites/accept`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - token, - user: { - first_name: "Brigitte", - last_name: "Collier", - password: "supersecret", - }, - }), -}) -.then((response) => response.json()) -.then(() => { - // successful -}) -``` + const handleAccept = () => { + acceptInvite.mutate({ + token, + user: { + first_name: "Brigitte", + last_name: "Collier", + password: "supersecret", + }, + }) + } - - - -```bash -curl -L -X POST '/admin/invites/accept' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "token": "", - "user": { - "first_name": "Brigitte", - "last_name": "Collier", - "password": "supersecret" + // ... } -}' -``` - + export default AcceptInvite + ``` + + + + + ```ts + fetch(`/admin/invites/accept`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + token, + user: { + first_name: "Brigitte", + last_name: "Collier", + password: "supersecret", + }, + }), + }) + .then((response) => response.json()) + .then(() => { + // successful + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/invites/accept' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "token": "", + "user": { + "first_name": "Brigitte", + "last_name": "Collier", + "password": "supersecret" + } + }' + ``` + + This API Route requires the following request body parameters: @@ -320,58 +320,58 @@ The request does not return any data. If the invite was accepted successfully, t You can resend an invite if it’s not accepted yet. To resend an invite, send a request to the [Resend Invite API Route](https://docs.medusajs.com/api/admin#invites_postinvitesinviteresend): - + -```ts -medusa.admin.invites.resend(inviteId) -.then(() => { - // successful -}) -``` + ```ts + medusa.admin.invites.resend(inviteId) + .then(() => { + // successful + }) + ``` - - + + -```tsx -import { useAdminResendInvite } from "medusa-react" + ```tsx + import { useAdminResendInvite } from "medusa-react" -const ResendInvite = () => { - const resendInvite = useAdminResendInvite(inviteId) - // ... + const ResendInvite = () => { + const resendInvite = useAdminResendInvite(inviteId) + // ... - const handleResend = () => { - resendInvite.mutate() - } + const handleResend = () => { + resendInvite.mutate() + } - // ... -} + // ... + } -export default ResendInvite -``` + export default ResendInvite + ``` - - + + -```ts -fetch(`/admin/invites/${inviteId}/resend`, { - credentials: "include", - method: "POST", -}) -.then((response) => response.json()) -.then(() => { - // successful -}) -``` + ```ts + fetch(`/admin/invites/${inviteId}/resend`, { + credentials: "include", + method: "POST", + }) + .then((response) => response.json()) + .then(() => { + // successful + }) + ``` - - + + -```bash -curl -L -X POST '/admin/invites//resend' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X POST '/admin/invites//resend' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the invite ID as a path parameter. @@ -385,58 +385,58 @@ The request doesn't return any data. If the invite was resent successfully, the You can delete an invite by sending a request to the [Delete Invite API Route](https://docs.medusajs.com/api/admin#invites_deleteinvitesinvite): - + -```ts -medusa.admin.invites.delete(inviteId) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + medusa.admin.invites.delete(inviteId) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```tsx -import { useAdminDeleteInvite } from "medusa-react" + ```tsx + import { useAdminDeleteInvite } from "medusa-react" -const DeleteInvite = () => { - const deleteInvite = useAdminDeleteInvite(inviteId) - // ... + const DeleteInvite = () => { + const deleteInvite = useAdminDeleteInvite(inviteId) + // ... - const handleDelete = () => { - deleteInvite.mutate() - } + const handleDelete = () => { + deleteInvite.mutate() + } - // ... -} + // ... + } -export default DeleteInvite -``` + export default DeleteInvite + ``` - - + + -```ts -fetch(`/admin/invites/${inviteId}`, { - credentials: "include", - method: "DELETE", -}) -.then((response) => response.json()) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + fetch(`/admin/invites/${inviteId}`, { + credentials: "include", + method: "DELETE", + }) + .then((response) => response.json()) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/invites/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/invites/' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the invite ID as a path parameter. diff --git a/www/apps/docs/content/modules/users/admin/manage-profile.mdx b/www/apps/docs/content/modules/users/admin/manage-profile.mdx index a28d1c6657..96a8389c89 100644 --- a/www/apps/docs/content/modules/users/admin/manage-profile.mdx +++ b/www/apps/docs/content/modules/users/admin/manage-profile.mdx @@ -55,75 +55,75 @@ You can learn more about [authenticating as an admin user in the API reference]( You can log in a user by sending a request to the [User Login API Route](https://docs.medusajs.com/api/admin#auth_postauth): - + -```ts -medusa.admin.auth.createSession({ - email: "user@example.com", - password: "supersecret", -}) -.then(({ user }) => { - console.log(user.id) -}) -``` - - - - -```tsx -import { useAdminLogin } from "medusa-react" - -const Login = () => { - const adminLogin = useAdminLogin() - // ... - - const handleLogin = () => { - adminLogin.mutate({ + ```ts + medusa.admin.auth.createSession({ email: "user@example.com", password: "supersecret", }) - } + .then(({ user }) => { + console.log(user.id) + }) + ``` - // ... -} + + -export default Login -``` + ```tsx + import { useAdminLogin } from "medusa-react" - - + const Login = () => { + const adminLogin = useAdminLogin() + // ... -```ts -fetch(`/admin/auth`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email: "user@example.com", - password: "supersecret", - }), -}) -.then((response) => response.json()) -.then(({ user }) => { - console.log(user.id) -}) -``` + const handleLogin = () => { + adminLogin.mutate({ + email: "user@example.com", + password: "supersecret", + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/auth' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "email": "user@example.com", - "password": "supersecret" -}' -``` + export default Login + ``` - + + + + ```ts + fetch(`/admin/auth`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + email: "user@example.com", + password: "supersecret", + }), + }) + .then((response) => response.json()) + .then(({ user }) => { + console.log(user.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/auth' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "email": "user@example.com", + "password": "supersecret" + }' + ``` + + This API Route requires the following request body parameters: @@ -138,58 +138,58 @@ The request returns the logged-in user as an object. You can log out a user by sending a request to the [User Logout API Route](https://docs.medusajs.com/api/admin#auth_deleteauth): - + -```ts -medusa.admin.auth.deleteSession() -.then(() => { - // logged out successfully -}) -``` + ```ts + medusa.admin.auth.deleteSession() + .then(() => { + // logged out successfully + }) + ``` - - + + -```tsx -import { useAdminDeleteSession } from "medusa-react" + ```tsx + import { useAdminDeleteSession } from "medusa-react" -const Logout = () => { - const adminLogout = useAdminDeleteSession() - // ... + const Logout = () => { + const adminLogout = useAdminDeleteSession() + // ... - const handleLogout = () => { - adminLogout.mutate() - } + const handleLogout = () => { + adminLogout.mutate() + } - // ... -} + // ... + } -export default Logout -``` + export default Logout + ``` - - + + -```ts -fetch(`/admin/auth`, { - credentials: "include", - method: "DELETE", -}) -.then((response) => response.json()) -.then(() => { - // logged out successfully -}) -``` + ```ts + fetch(`/admin/auth`, { + credentials: "include", + method: "DELETE", + }) + .then((response) => response.json()) + .then(() => { + // logged out successfully + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/auth' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/auth' \ + -H 'Authorization: Bearer ' + ``` - + The API Route doesn't require any path or query parameters. @@ -203,57 +203,57 @@ The request doesn't return any data. The response code will be `200` for success You can retrieve the current user’s details for their profile by sending a request to the [Get Current User API Route](https://docs.medusajs.com/api/admin#auth_getauth): - + -```ts -medusa.admin.auth.getSession() -.then(({ user }) => { - console.log(user.id) -}) -``` + ```ts + medusa.admin.auth.getSession() + .then(({ user }) => { + console.log(user.id) + }) + ``` - - + + -```tsx -import { useAdminGetSession } from "medusa-react" + ```tsx + import { useAdminGetSession } from "medusa-react" -const Profile = () => { - const { user, isLoading } = useAdminGetSession() + const Profile = () => { + const { user, isLoading } = useAdminGetSession() - return ( -
- {isLoading && Loading...} - {user && {user.email}} -
- ) -} + return ( +
+ {isLoading && Loading...} + {user && {user.email}} +
+ ) + } -export default Profile -``` + export default Profile + ``` -
- + + -```ts -fetch(`/admin/auth`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ user }) => { - console.log(user.id) -}) -``` + ```ts + fetch(`/admin/auth`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ user }) => { + console.log(user.id) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/auth' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/auth' \ + -H 'Authorization: Bearer ' + ``` - +
This API Route doesn't require any parameters. @@ -267,75 +267,75 @@ The request returns the current user as an object. You can update a user’s details in their profile by sending a request to the [Update User API Route](https://docs.medusajs.com/api/admin#users_postusersuser): - + -```ts -medusa.admin.users.update(userId, { - first_name: "Marcellus", -}) -.then(({ user }) => { - console.log(user.id) -}) -``` - - - - -```tsx -import { - useAdminDeleteSession, - useAdminUpdateUser, -} from "medusa-react" - -const Profile = () => { - const updateUser = useAdminUpdateUser(userId) - // ... - - const handleUpdate = () => { - updateUser.mutate({ + ```ts + medusa.admin.users.update(userId, { first_name: "Marcellus", }) - } + .then(({ user }) => { + console.log(user.id) + }) + ``` - // ... -} + + -export default Profile -``` + ```tsx + import { + useAdminDeleteSession, + useAdminUpdateUser, + } from "medusa-react" - - + const Profile = () => { + const updateUser = useAdminUpdateUser(userId) + // ... -```ts -fetch(`/admin/users/${userId}`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - first_name: "Marcellus", - }), -}) -.then((response) => response.json()) -.then(({ user }) => { - console.log(user.id) -}) -``` + const handleUpdate = () => { + updateUser.mutate({ + first_name: "Marcellus", + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/users/' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "first_name": "Marcellus" -}' -``` + export default Profile + ``` - + + + + ```ts + fetch(`/admin/users/${userId}`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + first_name: "Marcellus", + }), + }) + .then((response) => response.json()) + .then(({ user }) => { + console.log(user.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/users/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "first_name": "Marcellus" + }' + ``` + + This API Route requires the ID of the user as a path parameter. @@ -363,71 +363,71 @@ Sending the password reset email is not handled by default in the Medusa backend You can request a password reset by sending a request to the [Request Password Reset API Route](https://docs.medusajs.com/api/admin#users_postusersuserpasswordtoken): - + -```ts -medusa.admin.users.sendResetPasswordToken({ - email: "user@example.com", -}) -.then(() => { - // successful -}) -``` - - - - -```tsx -import { useAdminSendResetPasswordToken } from "medusa-react" - -const Login = () => { - const requestPasswordReset = useAdminSendResetPasswordToken() - // ... - - const handleResetPassword = () => { - requestPasswordReset.mutate({ + ```ts + medusa.admin.users.sendResetPasswordToken({ email: "user@example.com", }) - } + .then(() => { + // successful + }) + ``` - // ... -} + + -export default Login -``` + ```tsx + import { useAdminSendResetPasswordToken } from "medusa-react" - - + const Login = () => { + const requestPasswordReset = useAdminSendResetPasswordToken() + // ... -```ts -fetch(`/admin/users/password-token`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email: "user@example.com", - }), -}) -.then((response) => response.json()) -.then(() => { - // successful -}) -``` + const handleResetPassword = () => { + requestPasswordReset.mutate({ + email: "user@example.com", + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/users/password-token' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "email": "user@example.com" -}' -``` + export default Login + ``` - + + + + ```ts + fetch(`/admin/users/password-token`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + email: "user@example.com", + }), + }) + .then((response) => response.json()) + .then(() => { + // successful + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/users/password-token' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "email": "user@example.com" + }' + ``` + + This API Route requires the `email` parameter in the request body, which is the email of the user requesting to reset their password. @@ -441,75 +441,75 @@ After the user resets their password and, typically, receives an email with a li You can reset the password by sending a request to the [Reset Password API Route](https://docs.medusajs.com/api/admin#users_postusersuserpassword): - + -```ts -medusa.admin.users.resetPassword({ - token: "supersecrettoken", - password: "supersecret", -}) -.then(({ user }) => { - console.log(user.id) -}) -``` - - - - -```tsx -import { useAdminResetPassword } from "medusa-react" - -const ResetPassword = () => { - const resetPassword = useAdminResetPassword() - // ... - - const handleResetPassword = () => { - resetPassword.mutate({ + ```ts + medusa.admin.users.resetPassword({ token: "supersecrettoken", password: "supersecret", }) - } + .then(({ user }) => { + console.log(user.id) + }) + ``` - // ... -} + + -export default ResetPassword -``` + ```tsx + import { useAdminResetPassword } from "medusa-react" - - + const ResetPassword = () => { + const resetPassword = useAdminResetPassword() + // ... -```ts -fetch(`/admin/users/reset-password`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - token: "supersecrettoken", - password: "supersecret", - }), -}) -.then((response) => response.json()) -.then(({ user }) => { - console.log(user.id) -}) -``` + const handleResetPassword = () => { + resetPassword.mutate({ + token: "supersecrettoken", + password: "supersecret", + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/users/reset-password' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "token": "supersecrettoken", - "password": "supersecret" -}' -``` + export default ResetPassword + ``` - + + + + ```ts + fetch(`/admin/users/reset-password`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + token: "supersecrettoken", + password: "supersecret", + }), + }) + .then((response) => response.json()) + .then(({ user }) => { + console.log(user.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/users/reset-password' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "token": "supersecrettoken", + "password": "supersecret" + }' + ``` + + This API Route requires the following request body parameters: diff --git a/www/apps/docs/content/modules/users/admin/manage-users.mdx b/www/apps/docs/content/modules/users/admin/manage-users.mdx index 1ada7c8363..0fe90037fd 100644 --- a/www/apps/docs/content/modules/users/admin/manage-users.mdx +++ b/www/apps/docs/content/modules/users/admin/manage-users.mdx @@ -56,64 +56,64 @@ You can learn more about [authenticating as an admin user in the API reference]( You can retrieve users in a store by sending a request to the [List Users API Route](https://docs.medusajs.com/api/admin#users_getusers): - + -```ts -medusa.admin.users.list() -.then(({ users }) => { - console.log(users.length) -}) -``` + ```ts + medusa.admin.users.list() + .then(({ users }) => { + console.log(users.length) + }) + ``` - - + + -```tsx -import { useAdminUsers } from "medusa-react" + ```tsx + import { useAdminUsers } from "medusa-react" -const Users = () => { - const { users, isLoading } = useAdminUsers() + const Users = () => { + const { users, isLoading } = useAdminUsers() - return ( -
- {isLoading && Loading...} - {users && !users.length && No Users} - {users && users.length > 0 && ( -
    - {users.map((user) => ( -
  • {user.email}
  • - ))} -
- )} -
- ) -} + return ( +
+ {isLoading && Loading...} + {users && !users.length && No Users} + {users && users.length > 0 && ( +
    + {users.map((user) => ( +
  • {user.email}
  • + ))} +
+ )} +
+ ) + } -export default Users -``` + export default Users + ``` -
- + + -```ts -fetch(`/admin/users`, { - credentials: "include", -}) -.then((response) => response.json()) -.then(({ users }) => { - console.log(users.length) -}) -``` + ```ts + fetch(`/admin/users`, { + credentials: "include", + }) + .then((response) => response.json()) + .then(({ users }) => { + console.log(users.length) + }) + ``` - - + + -```bash -curl -L -X GET '/admin/users' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X GET '/admin/users' \ + -H 'Authorization: Bearer ' + ``` - +
This API Route doesn't require any parameters. @@ -127,76 +127,76 @@ The request returns an array of user objects. You can create a user by sending a request to the [Create User API Route](https://docs.medusajs.com/api/admin#users_postusers): - + -```ts -medusa.admin.users.create({ - email: "user@example.com", - password: "supersecret", -}) -.then(({ user }) => { - console.log(user.id) -}) -``` - - - - -```tsx -import { useAdminCreateUser } from "medusa-react" - -const CreateUser = () => { - const createUser = useAdminCreateUser() - // ... - - const handleCreateUser = () => { - createUser.mutate({ + ```ts + medusa.admin.users.create({ email: "user@example.com", password: "supersecret", }) - } + .then(({ user }) => { + console.log(user.id) + }) + ``` - // ... -} + + -export default CreateUser -``` + ```tsx + import { useAdminCreateUser } from "medusa-react" - - + const CreateUser = () => { + const createUser = useAdminCreateUser() + // ... -```ts -fetch(`/admin/users`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email: "user@example.com", - password: "supersecret", - }), -}) -.then((response) => response.json()) -.then(({ user }) => { - console.log(user.id) -}) -``` + const handleCreateUser = () => { + createUser.mutate({ + email: "user@example.com", + password: "supersecret", + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/users' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "email": "user@example.com", - "password": "supersecret" -}' -``` + export default CreateUser + ``` - + + + + ```ts + fetch(`/admin/users`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + email: "user@example.com", + password: "supersecret", + }), + }) + .then((response) => response.json()) + .then(({ user }) => { + console.log(user.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/users' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "email": "user@example.com", + "password": "supersecret" + }' + ``` + + This API Route requires the following request body parameters: @@ -215,72 +215,72 @@ The request returns the created user as an object. You can update a user’s details by sending a request to the [Update User API Route](https://docs.medusajs.com/api/admin#users_postusersuser): - + -```ts -medusa.admin.users.update(userId, { - first_name: "Marcellus", -}) -.then(({ user }) => { - console.log(user.id) -}) -``` - - - - -```tsx -import { useAdminUpdateUser } from "medusa-react" - -const UpdateUser = () => { - const updateUser = useAdminUpdateUser(userId) - // ... - - const handleUpdateUser = () => { - updateUser.mutate({ + ```ts + medusa.admin.users.update(userId, { first_name: "Marcellus", }) - } + .then(({ user }) => { + console.log(user.id) + }) + ``` - // ... -} + + -export default UpdateUser -``` + ```tsx + import { useAdminUpdateUser } from "medusa-react" - - + const UpdateUser = () => { + const updateUser = useAdminUpdateUser(userId) + // ... -```ts -fetch(`/admin/users/${userId}`, { - credentials: "include", - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - first_name: "Marcellus", - }), -}) -.then((response) => response.json()) -.then(({ user }) => { - console.log(user.id) -}) -``` + const handleUpdateUser = () => { + updateUser.mutate({ + first_name: "Marcellus", + }) + } - - + // ... + } -```bash -curl -L -X POST '/admin/users/' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ ---data-raw '{ - "first_name": "Marcellus" -}' -``` + export default UpdateUser + ``` - + + + + ```ts + fetch(`/admin/users/${userId}`, { + credentials: "include", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + first_name: "Marcellus", + }), + }) + .then((response) => response.json()) + .then(({ user }) => { + console.log(user.id) + }) + ``` + + + + + ```bash + curl -L -X POST '/admin/users/' \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "first_name": "Marcellus" + }' + ``` + + This API Route requires the ID of the user as a path parameter. @@ -296,58 +296,58 @@ The request returns the updated user as an object. You can delete a user by sending a request to the [Delete User API Route](https://docs.medusajs.com/api/admin#users_deleteusersuser): - + -```ts -medusa.admin.users.delete(userId) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + medusa.admin.users.delete(userId) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```tsx -import { useAdminDeleteUser } from "medusa-react" + ```tsx + import { useAdminDeleteUser } from "medusa-react" -const DeleteUser = () => { - const deleteUser = useAdminDeleteUser(userId) - // ... + const DeleteUser = () => { + const deleteUser = useAdminDeleteUser(userId) + // ... - const handleDeleteUser = () => { - deleteUser.mutate() - } + const handleDeleteUser = () => { + deleteUser.mutate() + } - // ... -} + // ... + } -export default DeleteUser -``` + export default DeleteUser + ``` - - + + -```ts -fetch(`/admin/users/${userId}`, { - credentials: "include", - method: "DELETE", -}) -.then((response) => response.json()) -.then(({ id, object, deleted }) => { - console.log(id) -}) -``` + ```ts + fetch(`/admin/users/${userId}`, { + credentials: "include", + method: "DELETE", + }) + .then((response) => response.json()) + .then(({ id, object, deleted }) => { + console.log(id) + }) + ``` - - + + -```bash -curl -L -X DELETE '/admin/users/' \ --H 'Authorization: Bearer ' -``` + ```bash + curl -L -X DELETE '/admin/users/' \ + -H 'Authorization: Bearer ' + ``` - + This API Route requires the user ID as a path parameter. diff --git a/www/apps/docs/content/modules/users/backend/rbac.mdx b/www/apps/docs/content/modules/users/backend/rbac.mdx index a83bafaa8d..647a6fab90 100644 --- a/www/apps/docs/content/modules/users/backend/rbac.mdx +++ b/www/apps/docs/content/modules/users/backend/rbac.mdx @@ -47,287 +47,285 @@ So, the first step would be to create the `Role` and `Permission` entities to re }, ]} /> -
- -Example Implementation - +
+ Example Implementation -This is an example implementation of how you can create the Role and Permission entities, and extend the `User` and `Store` entities. + This is an example implementation of how you can create the Role and Permission entities, and extend the `User` and `Store` entities. -Creating an entity requires creating an entity class, a repository, and a migration. You can learn more [here](../../../development/entities/create.mdx). You’ll be creating the migration at the end of this example section. + Creating an entity requires creating an entity class, a repository, and a migration. You can learn more [here](../../../development/entities/create.mdx). You’ll be creating the migration at the end of this example section. -Create the file `src/models/role.ts` with the following content: + Create the file `src/models/role.ts` with the following content: -```ts title=src/models/role.ts -import { - BeforeInsert, - Column, - Entity, - Index, - JoinColumn, - JoinTable, - ManyToMany, - ManyToOne, - OneToMany, -} from "typeorm" -import { BaseEntity } from "@medusajs/medusa" -import { generateEntityId } from "@medusajs/medusa/dist/utils" -import { Permission } from "./permission" -import { User } from "./user" -import { Store } from "./store" + ```ts title=src/models/role.ts + import { + BeforeInsert, + Column, + Entity, + Index, + JoinColumn, + JoinTable, + ManyToMany, + ManyToOne, + OneToMany, + } from "typeorm" + import { BaseEntity } from "@medusajs/medusa" + import { generateEntityId } from "@medusajs/medusa/dist/utils" + import { Permission } from "./permission" + import { User } from "./user" + import { Store } from "./store" -@Entity() -export class Role extends BaseEntity { - @Column({ type: "varchar" }) - name: string + @Entity() + export class Role extends BaseEntity { + @Column({ type: "varchar" }) + name: string - // only helpful if you're integrating in a marketplace - @Index() - @Column({ nullable: true }) - store_id: string + // only helpful if you're integrating in a marketplace + @Index() + @Column({ nullable: true }) + store_id: string - @ManyToMany(() => Permission) - @JoinTable({ - name: "role_permissions", - joinColumn: { - name: "role_id", - referencedColumnName: "id", - }, - inverseJoinColumn: { - name: "permission_id", - referencedColumnName: "id", - }, - }) - permissions: Permission[] + @ManyToMany(() => Permission) + @JoinTable({ + name: "role_permissions", + joinColumn: { + name: "role_id", + referencedColumnName: "id", + }, + inverseJoinColumn: { + name: "permission_id", + referencedColumnName: "id", + }, + }) + permissions: Permission[] - @OneToMany(() => User, (user) => user.teamRole) - @JoinColumn({ name: "id", referencedColumnName: "role_id" }) - users: User[] + @OneToMany(() => User, (user) => user.teamRole) + @JoinColumn({ name: "id", referencedColumnName: "role_id" }) + users: User[] - @ManyToOne(() => Store, (store) => store.roles) - @JoinColumn({ name: "store_id" }) - store: Store + @ManyToOne(() => Store, (store) => store.roles) + @JoinColumn({ name: "store_id" }) + store: Store - @BeforeInsert() - private beforeInsert(): void { - this.id = generateEntityId(this.id, "role") + @BeforeInsert() + private beforeInsert(): void { + this.id = generateEntityId(this.id, "role") + } } -} -``` + ``` -This creates the `Role` entity. You’ll see errors in your editors, which you’ll resolve by following along the example. + This creates the `Role` entity. You’ll see errors in your editors, which you’ll resolve by following along the example. -The `Role` entity has the following attributes: + The `Role` entity has the following attributes: -- `id`: the ID of the role, which is available implicitly by extending `BaseEntity` -- `name`: the name of the role -- `store_id`: the ID of the store this role belongs to. This is only useful if you’re implementing RBAC in a marketplace. Otherwise, you may omit this relation. + - `id`: the ID of the role, which is available implicitly by extending `BaseEntity` + - `name`: the name of the role + - `store_id`: the ID of the store this role belongs to. This is only useful if you’re implementing RBAC in a marketplace. Otherwise, you may omit this relation. -It also has the following relations: + It also has the following relations: -- `permissions`: an array of permissions included in this role. -- `store`: the Store this role belongs to. -- `users`: the users associated with this role. + - `permissions`: an array of permissions included in this role. + - `store`: the Store this role belongs to. + - `users`: the users associated with this role. -Then, create the file `src/repositories/role.ts` with the following content: + Then, create the file `src/repositories/role.ts` with the following content: -```ts title=src/repositories/role.ts -import { Role } from "../models/role" -import { - dataSource, -} from "@medusajs/medusa/dist/loaders/database" + ```ts title=src/repositories/role.ts + import { Role } from "../models/role" + import { + dataSource, + } from "@medusajs/medusa/dist/loaders/database" -export const RoleRepository = dataSource - .getRepository(Role) + export const RoleRepository = dataSource + .getRepository(Role) -export default RoleRepository -``` + export default RoleRepository + ``` -Next, create the file `src/models/permission.ts` with the following content: + Next, create the file `src/models/permission.ts` with the following content: -```ts title=src/models/permission.ts -import { - BeforeInsert, - Column, - Entity, - JoinTable, - ManyToMany, -} from "typeorm" -import { BaseEntity } from "@medusajs/medusa" -import { - DbAwareColumn, - generateEntityId, -} from "@medusajs/medusa/dist/utils" -import { Role } from "./role" + ```ts title=src/models/permission.ts + import { + BeforeInsert, + Column, + Entity, + JoinTable, + ManyToMany, + } from "typeorm" + import { BaseEntity } from "@medusajs/medusa" + import { + DbAwareColumn, + generateEntityId, + } from "@medusajs/medusa/dist/utils" + import { Role } from "./role" -@Entity() -export class Permission extends BaseEntity { - @Column({ type: "varchar" }) - name: string + @Entity() + export class Permission extends BaseEntity { + @Column({ type: "varchar" }) + name: string - // holds the permissions - @DbAwareColumn({ type: "jsonb", nullable: true }) - metadata: Record + // holds the permissions + @DbAwareColumn({ type: "jsonb", nullable: true }) + metadata: Record - @BeforeInsert() - private beforeInsert(): void { - this.id = generateEntityId(this.id, "perm") + @BeforeInsert() + private beforeInsert(): void { + this.id = generateEntityId(this.id, "perm") + } } -} -``` + ``` -This creates a `Permission` entity that has the following attributes: + This creates a `Permission` entity that has the following attributes: -- `id`: the ID of the permission, which is implicitly available through extending `BaseEntity`. -- `name`: the name of the permission. -- `metadata`: an object that will include the permissions. The object keys will be an admin path in the backend, and the value will be a boolean indicating whether the user has access to that path or not. + - `id`: the ID of the permission, which is implicitly available through extending `BaseEntity`. + - `name`: the name of the permission. + - `metadata`: an object that will include the permissions. The object keys will be an admin path in the backend, and the value will be a boolean indicating whether the user has access to that path or not. -Then, create the file `src/repositories/permission.ts` with the following content: + Then, create the file `src/repositories/permission.ts` with the following content: -```ts title=src/repositories/permission.ts -import { Permission } from "../models/permission" -import { - dataSource, -} from "@medusajs/medusa/dist/loaders/database" + ```ts title=src/repositories/permission.ts + import { Permission } from "../models/permission" + import { + dataSource, + } from "@medusajs/medusa/dist/loaders/database" -export const PermissionRepository = dataSource - .getRepository(Permission) + export const PermissionRepository = dataSource + .getRepository(Permission) -export default PermissionRepository -``` + export default PermissionRepository + ``` -Next, you’ll extend the `User` and `Store` entities. As mentioned earlier, extending the `Store` entity and adding the relation is only useful if you’re implementing RBAC in a marketplace or similar use cases. So, if this doesn’t apply to you, you may skip it. + Next, you’ll extend the `User` and `Store` entities. As mentioned earlier, extending the `Store` entity and adding the relation is only useful if you’re implementing RBAC in a marketplace or similar use cases. So, if this doesn’t apply to you, you may skip it. -Create the file `src/models/user.ts` with the following content: + Create the file `src/models/user.ts` with the following content: -```ts title=src/models/user.ts -import { - Column, - Entity, - Index, - JoinColumn, - ManyToOne, -} from "typeorm" -import { - // alias the core entity to not cause a naming conflict - User as MedusaUser, -} from "@medusajs/medusa" -import { Role } from "./role" + ```ts title=src/models/user.ts + import { + Column, + Entity, + Index, + JoinColumn, + ManyToOne, + } from "typeorm" + import { + // alias the core entity to not cause a naming conflict + User as MedusaUser, + } from "@medusajs/medusa" + import { Role } from "./role" -@Entity() -export class User extends MedusaUser { - @Index() - @Column({ nullable: true }) - role_id: string | null + @Entity() + export class User extends MedusaUser { + @Index() + @Column({ nullable: true }) + role_id: string | null - @ManyToOne(() => Role, (role) => role.users) - @JoinColumn({ name: "role_id" }) - teamRole: Role | null -} -``` - -This adds a new attribute `role_id` to the core `User` entity and a `teamRole` relation that optionally associates the user with a role. - -Next, create the file `src/models/store.ts` with the following content: - -```ts title=src/models/store.ts -import { Entity, JoinColumn, OneToMany } from "typeorm" -import { - // alias the core entity to not cause a naming conflict - Store as MedusaStore, -} from "@medusajs/medusa" -import { Role } from "./role" - -@Entity() -export class Store extends MedusaStore { - @OneToMany(() => Role, (role) => role.store) - @JoinColumn({ name: "id", referencedColumnName: "store_id" }) - roles: Role[] -} -``` - -This adds a `roles` relation to the core `Store` entity. - -Optionally, if you’re using TypeScript, create the file `src/index.d.ts` with the following content: - -```ts title=src/index.d.ts -import { Role } from "./models/role" - -export declare module "@medusajs/medusa/dist/models/user" { - - declare interface User { - role_id: string | null; + @ManyToOne(() => Role, (role) => role.users) + @JoinColumn({ name: "role_id" }) teamRole: Role | null } + ``` - declare interface Store { + This adds a new attribute `role_id` to the core `User` entity and a `teamRole` relation that optionally associates the user with a role. + + Next, create the file `src/models/store.ts` with the following content: + + ```ts title=src/models/store.ts + import { Entity, JoinColumn, OneToMany } from "typeorm" + import { + // alias the core entity to not cause a naming conflict + Store as MedusaStore, + } from "@medusajs/medusa" + import { Role } from "./role" + + @Entity() + export class Store extends MedusaStore { + @OneToMany(() => Role, (role) => role.store) + @JoinColumn({ name: "id", referencedColumnName: "store_id" }) roles: Role[] } -} -``` + ``` -This ensures that your TypeScript validation and editor autocomplete recognize the new attributes and relations you added on the core entities. + This adds a `roles` relation to the core `Store` entity. -Finally, you need to create a migration to reflect these changes in the database. + Optionally, if you’re using TypeScript, create the file `src/index.d.ts` with the following content: -You can learn about creating migrations [here](../../../development/entities/migrations/create.md). An example of a migration file based on the entities created above: + ```ts title=src/index.d.ts + import { Role } from "./models/role" + + export declare module "@medusajs/medusa/dist/models/user" { + + declare interface User { + role_id: string | null; + teamRole: Role | null + } + + declare interface Store { + roles: Role[] + } + } + ``` + + This ensures that your TypeScript validation and editor autocomplete recognize the new attributes and relations you added on the core entities. + + Finally, you need to create a migration to reflect these changes in the database. + + You can learn about creating migrations [here](../../../development/entities/migrations/create.md). An example of a migration file based on the entities created above: -```ts title=src/migrations/1693225851284-AddRolesAndPermissions.ts -import { MigrationInterface, QueryRunner, Table, TableIndex } from "typeorm" + ```ts title=src/migrations/1693225851284-AddRolesAndPermissions.ts + import { MigrationInterface, QueryRunner, Table, TableIndex } from "typeorm" -export class AddRolesAndPermissions1693225851284 implements MigrationInterface { + export class AddRolesAndPermissions1693225851284 implements MigrationInterface { - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" ADD "role_id" character varying`) - await queryRunner.query(`CREATE TABLE "permission" ("id" character varying NOT NULL, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "name" character varying NOT NULL, "metadata" jsonb, CONSTRAINT "PK_3b8b97af9d9d8807e41e6f48362" PRIMARY KEY ("id"))`) - await queryRunner.query(`CREATE TABLE "role" ("id" character varying NOT NULL, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "name" character varying NOT NULL, "store_id" character varying, CONSTRAINT "PK_b36bcfe02fc8de3c57a8b2391c2" PRIMARY KEY ("id"))`) - await queryRunner.query(`CREATE INDEX "IDX_29259dd58b1052aef9be56941d" ON "role" ("store_id") `) - await queryRunner.query(`CREATE TABLE "role_permissions" ("role_id" character varying NOT NULL, "permission_id" character varying NOT NULL, CONSTRAINT "PK_25d24010f53bb80b78e412c9656" PRIMARY KEY ("role_id", "permission_id"))`) - await queryRunner.query(`CREATE INDEX "IDX_178199805b901ccd220ab7740e" ON "role_permissions" ("role_id") `) - await queryRunner.query(`CREATE INDEX "IDX_17022daf3f885f7d35423e9971" ON "role_permissions" ("permission_id") `) + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" ADD "role_id" character varying`) + await queryRunner.query(`CREATE TABLE "permission" ("id" character varying NOT NULL, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "name" character varying NOT NULL, "metadata" jsonb, CONSTRAINT "PK_3b8b97af9d9d8807e41e6f48362" PRIMARY KEY ("id"))`) + await queryRunner.query(`CREATE TABLE "role" ("id" character varying NOT NULL, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "name" character varying NOT NULL, "store_id" character varying, CONSTRAINT "PK_b36bcfe02fc8de3c57a8b2391c2" PRIMARY KEY ("id"))`) + await queryRunner.query(`CREATE INDEX "IDX_29259dd58b1052aef9be56941d" ON "role" ("store_id") `) + await queryRunner.query(`CREATE TABLE "role_permissions" ("role_id" character varying NOT NULL, "permission_id" character varying NOT NULL, CONSTRAINT "PK_25d24010f53bb80b78e412c9656" PRIMARY KEY ("role_id", "permission_id"))`) + await queryRunner.query(`CREATE INDEX "IDX_178199805b901ccd220ab7740e" ON "role_permissions" ("role_id") `) + await queryRunner.query(`CREATE INDEX "IDX_17022daf3f885f7d35423e9971" ON "role_permissions" ("permission_id") `) - await queryRunner.query(`ALTER TABLE "role_permissions" ADD CONSTRAINT "FK_178199805b901ccd220ab7740ec" FOREIGN KEY ("role_id") REFERENCES "role"("id") ON DELETE CASCADE ON UPDATE CASCADE`) - await queryRunner.query(`ALTER TABLE "role_permissions" ADD CONSTRAINT "FK_17022daf3f885f7d35423e9971e" FOREIGN KEY ("permission_id") REFERENCES "permission"("id") ON DELETE CASCADE ON UPDATE CASCADE`) - await queryRunner.query(`ALTER TABLE "user" ADD CONSTRAINT "FK_fb2e442d14add3cefbdf33c4561" FOREIGN KEY ("role_id") REFERENCES "role"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) - await queryRunner.query(`ALTER TABLE "role" ADD CONSTRAINT "FK_29259dd58b1052aef9be56941d4" FOREIGN KEY ("store_id") REFERENCES "store"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) - await queryRunner.query(`CREATE INDEX "IDX_fb2e442d14add3cefbdf33c456" ON "user" ("role_id") `) - } + await queryRunner.query(`ALTER TABLE "role_permissions" ADD CONSTRAINT "FK_178199805b901ccd220ab7740ec" FOREIGN KEY ("role_id") REFERENCES "role"("id") ON DELETE CASCADE ON UPDATE CASCADE`) + await queryRunner.query(`ALTER TABLE "role_permissions" ADD CONSTRAINT "FK_17022daf3f885f7d35423e9971e" FOREIGN KEY ("permission_id") REFERENCES "permission"("id") ON DELETE CASCADE ON UPDATE CASCADE`) + await queryRunner.query(`ALTER TABLE "user" ADD CONSTRAINT "FK_fb2e442d14add3cefbdf33c4561" FOREIGN KEY ("role_id") REFERENCES "role"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) + await queryRunner.query(`ALTER TABLE "role" ADD CONSTRAINT "FK_29259dd58b1052aef9be56941d4" FOREIGN KEY ("store_id") REFERENCES "store"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) + await queryRunner.query(`CREATE INDEX "IDX_fb2e442d14add3cefbdf33c456" ON "user" ("role_id") `) + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "role_permissions" DROP CONSTRAINT "FK_17022daf3f885f7d35423e9971e"`) - await queryRunner.query(`ALTER TABLE "role_permissions" DROP CONSTRAINT "FK_178199805b901ccd220ab7740ec"`) - await queryRunner.query(`ALTER TABLE "role" DROP CONSTRAINT "FK_29259dd58b1052aef9be56941d4"`) - await queryRunner.query(`DROP INDEX "public"."IDX_fb2e442d14add3cefbdf33c456"`) - await queryRunner.query(`ALTER TABLE "user" DROP CONSTRAINT "FK_fb2e442d14add3cefbdf33c4561"`) - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "role_id"`) - await queryRunner.query(`DROP INDEX "public"."IDX_17022daf3f885f7d35423e9971"`) - await queryRunner.query(`DROP INDEX "public"."IDX_178199805b901ccd220ab7740e"`) - await queryRunner.query(`DROP TABLE "role_permissions"`) - await queryRunner.query(`DROP INDEX "public"."IDX_29259dd58b1052aef9be56941d"`) - await queryRunner.query(`DROP TABLE "role"`) - await queryRunner.query(`DROP TABLE "permission"`) - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "role_permissions" DROP CONSTRAINT "FK_17022daf3f885f7d35423e9971e"`) + await queryRunner.query(`ALTER TABLE "role_permissions" DROP CONSTRAINT "FK_178199805b901ccd220ab7740ec"`) + await queryRunner.query(`ALTER TABLE "role" DROP CONSTRAINT "FK_29259dd58b1052aef9be56941d4"`) + await queryRunner.query(`DROP INDEX "public"."IDX_fb2e442d14add3cefbdf33c456"`) + await queryRunner.query(`ALTER TABLE "user" DROP CONSTRAINT "FK_fb2e442d14add3cefbdf33c4561"`) + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "role_id"`) + await queryRunner.query(`DROP INDEX "public"."IDX_17022daf3f885f7d35423e9971"`) + await queryRunner.query(`DROP INDEX "public"."IDX_178199805b901ccd220ab7740e"`) + await queryRunner.query(`DROP TABLE "role_permissions"`) + await queryRunner.query(`DROP INDEX "public"."IDX_29259dd58b1052aef9be56941d"`) + await queryRunner.query(`DROP TABLE "role"`) + await queryRunner.query(`DROP TABLE "permission"`) + } -} -``` + } + ``` -Finally, to reflect these changes, run the `build` command in the root directory of your medusa backend: + Finally, to reflect these changes, run the `build` command in the root directory of your medusa backend: -```bash npm2yarn -npm run build -``` + ```bash npm2yarn + npm run build + ``` -Then, run the migrations: + Then, run the migrations: -```bash -npx medusa migrations run -``` + ```bash + npx medusa migrations run + ``` -This will reflect the entity changes in your database. + This will reflect the entity changes in your database. -
+
--- @@ -347,99 +345,99 @@ Since the Medusa backend uses Express, you can create a middleware and attach it } }} /> -
-Example Implementation +
+ Example Implementation -In this example, you’ll create a middleware that runs on all admin-authenticated routes and checks the logged-in user’s permissions before giving them access to an API Route. + In this example, you’ll create a middleware that runs on all admin-authenticated routes and checks the logged-in user’s permissions before giving them access to an API Route. -Create the file `src/api/middlewares.ts` with the following content: + Create the file `src/api/middlewares.ts` with the following content: -```ts title=src/api/middlewares.ts -import type { - MiddlewaresConfig, - UserService, -} from "@medusajs/medusa" -import express from "express" -import type { - MedusaRequest, - MedusaResponse, - MedusaNextFunction, -} from "@medusajs/medusa" + ```ts title=src/api/middlewares.ts + import type { + MiddlewaresConfig, + UserService, + } from "@medusajs/medusa" + import express from "express" + import type { + MedusaRequest, + MedusaResponse, + MedusaNextFunction, + } from "@medusajs/medusa" -export const permissions = async ( - req: MedusaRequest, - res: MedusaResponse, - next: MedusaNextFunction -) => { - if (!req.user || !req.user.userId) { - next() - return - } - // retrieve currently logged-in user - const userService = req.scope.resolve( - "userService" - ) as UserService - const loggedInUser = await userService.retrieve( - req.user.userId, - { - select: ["id"], - relations: ["teamRole", "teamRole.permissions"], - }) - - if (!loggedInUser.teamRole) { - // considered as super user - next() - return - } - - const isAllowed = loggedInUser.teamRole?.permissions.some( - (permission) => { - const metadataKey = Object.keys(permission.metadata).find( - (key) => key === req.path - ) - if (!metadataKey) { - return false - } - - // boolean value - return permission.metadata[metadataKey] + export const permissions = async ( + req: MedusaRequest, + res: MedusaResponse, + next: MedusaNextFunction + ) => { + if (!req.user || !req.user.userId) { + next() + return } - ) + // retrieve currently logged-in user + const userService = req.scope.resolve( + "userService" + ) as UserService + const loggedInUser = await userService.retrieve( + req.user.userId, + { + select: ["id"], + relations: ["teamRole", "teamRole.permissions"], + }) - if (isAllowed) { - next() - return + if (!loggedInUser.teamRole) { + // considered as super user + next() + return + } + + const isAllowed = loggedInUser.teamRole?.permissions.some( + (permission) => { + const metadataKey = Object.keys(permission.metadata).find( + (key) => key === req.path + ) + if (!metadataKey) { + return false + } + + // boolean value + return permission.metadata[metadataKey] + } + ) + + if (isAllowed) { + next() + return + } + + // deny access + res.sendStatus(401) } - // deny access - res.sendStatus(401) -} + export const config: MiddlewaresConfig = { + routes: [ + { + matcher: "/admin/*", + middlewares: [permissions], + }, + ], + } + ``` -export const config: MiddlewaresConfig = { - routes: [ - { - matcher: "/admin/*", - middlewares: [permissions], - }, - ], -} -``` + In this middleware, you ensure that there is a logged-in user and the logged-in user has a role. If not, the user is admitted to access the API Route. Here, you presume that logged-in users who don’t have a role are “super-admin” users who can access all API Routes. You may choose to implement this differently. -In this middleware, you ensure that there is a logged-in user and the logged-in user has a role. If not, the user is admitted to access the API Route. Here, you presume that logged-in users who don’t have a role are “super-admin” users who can access all API Routes. You may choose to implement this differently. + If there’s a logged-in user that has a role, you check that the role’s permissions give them access to the current API Route. You do that by checking if a permission’s metadata has a key with the same request’s path. It may be better here to check for matching using regular expressions, for example, to check routes with path parameters. -If there’s a logged-in user that has a role, you check that the role’s permissions give them access to the current API Route. You do that by checking if a permission’s metadata has a key with the same request’s path. It may be better here to check for matching using regular expressions, for example, to check routes with path parameters. + Otherwise, if the user’s role doesn’t provide them with enough permissions, you return a `401` response code. -Otherwise, if the user’s role doesn’t provide them with enough permissions, you return a `401` response code. + :::tip -:::tip + Notice that you use `req.path` here to get the current API Route path. However, in middlewares, this doesn’t include the mount point which is `/admin`. So, for example, if the API Route path is `/admin/products`, `req.path` will be `/products`. You can alternatively use `req.originalUrl`. Learn more in [Express’s documentation](https://expressjs.com/en/api.html#req.originalUrl). -Notice that you use `req.path` here to get the current API Route path. However, in middlewares, this doesn’t include the mount point which is `/admin`. So, for example, if the API Route path is `/admin/products`, `req.path` will be `/products`. You can alternatively use `req.originalUrl`. Learn more in [Express’s documentation](https://expressjs.com/en/api.html#req.originalUrl). + ::: -::: + After defining the middleware, you apply it on all API Routes starting with `/admin/`. -After defining the middleware, you apply it on all API Routes starting with `/admin/`. - -
+
--- @@ -481,292 +479,290 @@ Furthermore, you may need to extend core services if you need to perform actions }, ]} /> -
- -Example Implementation - +
+ Example Implementation -In this example, you’ll only implement two API Routes for simplicity: create role API Route that create a new role with permissions, and associate user API Route that associates a user with a role. + In this example, you’ll only implement two API Routes for simplicity: create role API Route that create a new role with permissions, and associate user API Route that associates a user with a role. -You’ll also create basic services for `Role` and `Permission` to perform the functionalities of each of these API Routes and extend the core `UserService` to allow associating roles with users. + You’ll also create basic services for `Role` and `Permission` to perform the functionalities of each of these API Routes and extend the core `UserService` to allow associating roles with users. -Start by creating the file `src/services/permission.ts` with the following content: + Start by creating the file `src/services/permission.ts` with the following content: -```ts title=src/services/permission.ts -import { TransactionBaseService } from "@medusajs/medusa" -import { Permission } from "../models/permission" -import PermissionRepository from "../repositories/permission" + ```ts title=src/services/permission.ts + import { TransactionBaseService } from "@medusajs/medusa" + import { Permission } from "../models/permission" + import PermissionRepository from "../repositories/permission" -export type CreatePayload = Pick< - Permission, - "name" | "metadata" -> + export type CreatePayload = Pick< + Permission, + "name" | "metadata" + > -type InjectedDependencies = { - permissionRepository: typeof PermissionRepository -} - -class PermissionService extends TransactionBaseService { - protected readonly permissionRepository_: - typeof PermissionRepository - - constructor(container: InjectedDependencies) { - super(container) - this.permissionRepository_ = container.permissionRepository + type InjectedDependencies = { + permissionRepository: typeof PermissionRepository } - async create(data: CreatePayload) { - // omitting validation for simplicity - return this.atomicPhase_(async (manager) => { - const permissionRepo = manager.withRepository( - this.permissionRepository_ - ) - const permission = permissionRepo.create(data) + class PermissionService extends TransactionBaseService { + protected readonly permissionRepository_: + typeof PermissionRepository + + constructor(container: InjectedDependencies) { + super(container) + this.permissionRepository_ = container.permissionRepository + } - const result = await permissionRepo.save(permission) - - return result - }) - } -} - -export default PermissionService -``` - -This creates the `PermissionService` with only a `create` method that can be used to create a permission. - -Next, create the file `src/services/user.ts` with the following content: - -```ts title=src/services/user.ts -import { - UserService as MedusaUserService, User, -} from "@medusajs/medusa" -import { - UpdateUserInput, -} from "@medusajs/medusa/dist/types/user" - -class UserService extends MedusaUserService { - async update(userId: string, update: UpdateUserInput & { - role_id?: string - }): Promise { - return super.update(userId, update) - } -} - -export default UserService -``` - -This extends the core `UserService` to allow updating a user’s role. You may also want to extend the `create` method to allow specifying the role on creation. - -Then, create the file `src/services/role.ts` with the following content: - -```ts title=src/services/role.ts -import { TransactionBaseService } from "@medusajs/medusa" -import { Role } from "../models/role" -import RoleRepository from "../repositories/role" -import PermissionService, { - CreatePayload as PermissionCreatePayload, -} from "./permission" -import UserService from "./user" - -type CreatePayload = Pick & { - permissions?: PermissionCreatePayload[] -} - -type InjectedDependencies = { - roleRepository: typeof RoleRepository - permissionService: PermissionService - userService: UserService -} - -class RoleService extends TransactionBaseService { - protected readonly roleRpository_: typeof RoleRepository - protected readonly permissionService_: PermissionService - protected readonly userService_: UserService - - constructor(container: InjectedDependencies) { - super(container) - - this.roleRpository_ = container.roleRepository - this.permissionService_ = container.permissionService - this.userService_ = container.userService - } - - async retrieve(id: string): Promise { - // for simplicity, we retrieve all relations - // however, it's best to supply the relations - // as an optional method parameter - const roleRepo = this.manager_.withRepository( - this.roleRpository_ - ) - return await roleRepo.findOne({ - where: { - id, - }, - relations: [ - "permissions", - "store", - "users", - ], - }) - } - - async create(data: CreatePayload): Promise { - return this.atomicPhase_(async (manager) => { + async create(data: CreatePayload) { // omitting validation for simplicity - const { permissions: permissionsData = [] } = data - delete data.permissions - - const roleRepo = manager.withRepository( + return this.atomicPhase_(async (manager) => { + const permissionRepo = manager.withRepository( + this.permissionRepository_ + ) + const permission = permissionRepo.create(data) + + const result = await permissionRepo.save(permission) + + return result + }) + } + } + + export default PermissionService + ``` + + This creates the `PermissionService` with only a `create` method that can be used to create a permission. + + Next, create the file `src/services/user.ts` with the following content: + + ```ts title=src/services/user.ts + import { + UserService as MedusaUserService, User, + } from "@medusajs/medusa" + import { + UpdateUserInput, + } from "@medusajs/medusa/dist/types/user" + + class UserService extends MedusaUserService { + async update(userId: string, update: UpdateUserInput & { + role_id?: string + }): Promise { + return super.update(userId, update) + } + } + + export default UserService + ``` + + This extends the core `UserService` to allow updating a user’s role. You may also want to extend the `create` method to allow specifying the role on creation. + + Then, create the file `src/services/role.ts` with the following content: + + ```ts title=src/services/role.ts + import { TransactionBaseService } from "@medusajs/medusa" + import { Role } from "../models/role" + import RoleRepository from "../repositories/role" + import PermissionService, { + CreatePayload as PermissionCreatePayload, + } from "./permission" + import UserService from "./user" + + type CreatePayload = Pick & { + permissions?: PermissionCreatePayload[] + } + + type InjectedDependencies = { + roleRepository: typeof RoleRepository + permissionService: PermissionService + userService: UserService + } + + class RoleService extends TransactionBaseService { + protected readonly roleRpository_: typeof RoleRepository + protected readonly permissionService_: PermissionService + protected readonly userService_: UserService + + constructor(container: InjectedDependencies) { + super(container) + + this.roleRpository_ = container.roleRepository + this.permissionService_ = container.permissionService + this.userService_ = container.userService + } + + async retrieve(id: string): Promise { + // for simplicity, we retrieve all relations + // however, it's best to supply the relations + // as an optional method parameter + const roleRepo = this.manager_.withRepository( this.roleRpository_ ) - const role = roleRepo.create(data) - - role.permissions = [] - - for (const permissionData of permissionsData) { - role.permissions.push( - await this.permissionService_.create( - permissionData - ) - ) - } - const result = await roleRepo.save(role) - - return await this.retrieve(result.id) - }) - } - - async associateUser( - role_id: string, - user_id: string - ): Promise { - return this.atomicPhase_(async () => { - // omitting validation for simplicity - await this.userService_.update(user_id, { - role_id, + return await roleRepo.findOne({ + where: { + id, + }, + relations: [ + "permissions", + "store", + "users", + ], }) - - return await this.retrieve(role_id) - }) - } -} - -export default RoleService -``` - -This creates the `RoleService` with three methods: - -- `retrieve`: Retrieves a role with its relations. -- `create`: Creates a new role and, if provided, its permissions as well. -- `associateUser`: associates a user with a role. - -Now, you can create the API Routes. - -Start by creating the file `src/api/admin/roles/route.ts` with the following content: - -```ts title=src/api/admin/roles/route.ts -import type { - MedusaRequest, - MedusaResponse, -} from "@medusajs/medusa" -import RoleService from "../../../../services/role" - -export const POST = async ( - req: MedusaRequest, - res: MedusaResponse -) => { - // omitting validation for simplicity - const { - name, - store_id, - permissions = [], - } = req.body - - const roleService = req.scope.resolve( - "roleService" - ) as RoleService - - const role = await roleService.create({ - name, - store_id, - permissions, - }) - - res.json(role) -} -``` - -This creates the Create Role API Route at `/admin/roles` that uses the `RoleService` to create a new role. Notice that validation of received body parameters is omitted for simplicity. - -Next, create the file `src/api/routes/admin/roles/[id]/user/[user_id]/route.ts` with the following content: - -```ts title=src/api/routes/admin/roles/[id]/user/[user_id]/route.ts -import type { - MedusaRequest, - MedusaResponse, -} from "@medusajs/medusa" -import RoleService from "../../../../services/role" - -export const POST = async ( - req: MedusaRequest, - res: MedusaResponse -) => { - // omitting validation for simplicity purposes - const { - id, - user_id, - } = req.params - - const roleService = req.scope.resolve( - "roleService" - ) as RoleService - const role = await roleService.associateUser(id, user_id) - - res.json(role) -} -``` - -This creates the Associate User API Route at `/admin/roles/[id]/user/[user_id]` that uses the `RoleService` to associate a role with a user. - -To test the API Routes out, run the `build` command in the root directory of your Medusa backend project: - -```bash npm2yarn -npm run build -``` - -Then, start the backend with the following command: - -```bash -npx medusa develop -``` - -Try first to log in using the [Admin User Login API Route](https://docs.medusajs.com/api/admin#auth_postauth) with an existing admin user. Then, send a `POST` request to the `localhost:9000/admin/roles` API Route with the following request body parameters: - -```json -{ - "store_id": "store_01H8XPDY8WA1Z650MZSEY4Y0V0", - "name": "Product Manager", - "permissions": [ - { - "name": "Allow Products", - "metadata": { - "/products": true - } } - ] -} -``` -Make sure to replace the `store_id`'s value with your store’s ID. You can retrieve the store’s ID using the [Get Store Details API Route](https://docs.medusajs.com/api/admin#store_getstore). + async create(data: CreatePayload): Promise { + return this.atomicPhase_(async (manager) => { + // omitting validation for simplicity + const { permissions: permissionsData = [] } = data + delete data.permissions + + const roleRepo = manager.withRepository( + this.roleRpository_ + ) + const role = roleRepo.create(data) -This will create a new role with a permission that allows users of this role to access the `/admin/products` API Route. As mentioned before, because of the middleware’s implementation, you must specify the path without the `/admin` prefix. If you chose to implement this differently, such as with regular expressions, then change the permission’s metadata accordingly. + role.permissions = [] -Next, create a new user using the [Create User API Route](https://docs.medusajs.com/api/admin#users_postusers). Then, send a `POST` request to `localhost:9000/admin/roles//user/`, where `` is the ID of the role you created, and `` is the ID of the user you created. This will associate the user with the role you created. + for (const permissionData of permissionsData) { + role.permissions.push( + await this.permissionService_.create( + permissionData + ) + ) + } + const result = await roleRepo.save(role) -Finally, login with the user you created, then try to access any API Route other than `/admin/products`. You’ll receive a `401` unauthorized response. Then, try to access the [List Products API Route](https://docs.medusajs.com/api/admin#products_getproducts), and the user should be able to access it as expected. + return await this.retrieve(result.id) + }) + } -
+ async associateUser( + role_id: string, + user_id: string + ): Promise { + return this.atomicPhase_(async () => { + // omitting validation for simplicity + await this.userService_.update(user_id, { + role_id, + }) + + return await this.retrieve(role_id) + }) + } + } + + export default RoleService + ``` + + This creates the `RoleService` with three methods: + + - `retrieve`: Retrieves a role with its relations. + - `create`: Creates a new role and, if provided, its permissions as well. + - `associateUser`: associates a user with a role. + + Now, you can create the API Routes. + + Start by creating the file `src/api/admin/roles/route.ts` with the following content: + + ```ts title=src/api/admin/roles/route.ts + import type { + MedusaRequest, + MedusaResponse, + } from "@medusajs/medusa" + import RoleService from "../../../../services/role" + + export const POST = async ( + req: MedusaRequest, + res: MedusaResponse + ) => { + // omitting validation for simplicity + const { + name, + store_id, + permissions = [], + } = req.body + + const roleService = req.scope.resolve( + "roleService" + ) as RoleService + + const role = await roleService.create({ + name, + store_id, + permissions, + }) + + res.json(role) + } + ``` + + This creates the Create Role API Route at `/admin/roles` that uses the `RoleService` to create a new role. Notice that validation of received body parameters is omitted for simplicity. + + Next, create the file `src/api/routes/admin/roles/[id]/user/[user_id]/route.ts` with the following content: + + ```ts title=src/api/routes/admin/roles/[id]/user/[user_id]/route.ts + import type { + MedusaRequest, + MedusaResponse, + } from "@medusajs/medusa" + import RoleService from "../../../../services/role" + + export const POST = async ( + req: MedusaRequest, + res: MedusaResponse + ) => { + // omitting validation for simplicity purposes + const { + id, + user_id, + } = req.params + + const roleService = req.scope.resolve( + "roleService" + ) as RoleService + const role = await roleService.associateUser(id, user_id) + + res.json(role) + } + ``` + + This creates the Associate User API Route at `/admin/roles/[id]/user/[user_id]` that uses the `RoleService` to associate a role with a user. + + To test the API Routes out, run the `build` command in the root directory of your Medusa backend project: + + ```bash npm2yarn + npm run build + ``` + + Then, start the backend with the following command: + + ```bash + npx medusa develop + ``` + + Try first to log in using the [Admin User Login API Route](https://docs.medusajs.com/api/admin#auth_postauth) with an existing admin user. Then, send a `POST` request to the `localhost:9000/admin/roles` API Route with the following request body parameters: + + ```json + { + "store_id": "store_01H8XPDY8WA1Z650MZSEY4Y0V0", + "name": "Product Manager", + "permissions": [ + { + "name": "Allow Products", + "metadata": { + "/products": true + } + } + ] + } + ``` + + Make sure to replace the `store_id`'s value with your store’s ID. You can retrieve the store’s ID using the [Get Store Details API Route](https://docs.medusajs.com/api/admin#store_getstore). + + This will create a new role with a permission that allows users of this role to access the `/admin/products` API Route. As mentioned before, because of the middleware’s implementation, you must specify the path without the `/admin` prefix. If you chose to implement this differently, such as with regular expressions, then change the permission’s metadata accordingly. + + Next, create a new user using the [Create User API Route](https://docs.medusajs.com/api/admin#users_postusers). Then, send a `POST` request to `localhost:9000/admin/roles//user/`, where `` is the ID of the role you created, and `` is the ID of the user you created. This will associate the user with the role you created. + + Finally, login with the user you created, then try to access any API Route other than `/admin/products`. You’ll receive a `401` unauthorized response. Then, try to access the [List Products API Route](https://docs.medusajs.com/api/admin#products_getproducts), and the user should be able to access it as expected. + +
--- diff --git a/www/apps/docs/content/plugins/cms/contentful.md b/www/apps/docs/content/plugins/cms/contentful.mdx similarity index 64% rename from www/apps/docs/content/plugins/cms/contentful.md rename to www/apps/docs/content/plugins/cms/contentful.mdx index 6178a4ec81..fb0a20cf08 100644 --- a/www/apps/docs/content/plugins/cms/contentful.md +++ b/www/apps/docs/content/plugins/cms/contentful.mdx @@ -95,69 +95,59 @@ const plugins = [ The rest of this section includes the field names you can customize using this option for each content model type. -
- -product - +
+ product -- `title` -- `subtitle` -- `description` -- `variants` -- `options` -- `medusaId` -- `type` -- `collection` -- `tags` -- `handle` + - `title` + - `subtitle` + - `description` + - `variants` + - `options` + - `medusaId` + - `type` + - `collection` + - `tags` + - `handle` -
+
-
- -variant - +
+ variant -- `title` -- `sku` -- `prices` -- `options` -- `medusaId` + - `title` + - `sku` + - `prices` + - `options` + - `medusaId` -
+
-
- -region - +
+ region -- `name` -- `countries` -- `paymentProviders` -- `fulfillmentProviders` -- `medusaId` + - `name` + - `countries` + - `paymentProviders` + - `fulfillmentProviders` + - `medusaId` -
+
-
- -collection - +
+ collection -- `title` -- `medusaId` + - `title` + - `medusaId` -
+
-
- -type - +
+ type -- `name` -- `medusaId` + - `name` + - `medusaId` -
+
### Migrate Content Models @@ -173,252 +163,244 @@ Before creating the migration scripts, run the following command in the root of npm install --save-dev contentful-migration ``` -
- -product Content Model - +
+ product Content Model -Create the file `src/loaders/contentful-migrations/product.ts` with the following content: + Create the file `src/loaders/contentful-migrations/product.ts` with the following content: -```ts title=src/loaders/contentful-migrations/product.ts -import Migration, { - MigrationContext, -} from "contentful-migration" + ```ts title=src/loaders/contentful-migrations/product.ts + import Migration, { + MigrationContext, + } from "contentful-migration" -export function productMigration( - migration: Migration, - context?: MigrationContext -) { - const product = migration - .createContentType("product") - .name("Product") - .displayField("title") + export function productMigration( + migration: Migration, + context?: MigrationContext + ) { + const product = migration + .createContentType("product") + .name("Product") + .displayField("title") - product - .createField("title") - .name("Title") - .type("Symbol") - .required(true) - product - .createField("subtitle") - .name("Subtitle") - .type("Symbol") - product - .createField("handle") - .name("Handle") - .type("Symbol") - product - .createField("thumbnail") - .name("Thumbnail") - .type("Link") - .linkType("Asset") - product - .createField("description") - .name("Description") - .type("Text") - product - .createField("options") - .name("Options") - .type("Object") - product - .createField("tags") - .name("Tags") - .type("Object") - product - .createField("collection") - .name("Collection") - .type("Symbol") - product - .createField("type") - .name("Type") - .type("Symbol") - product - .createField("variants") - .name("Variants") - .type("Array") - .items({ - type: "Link", - linkType: "Entry", - validations: [ - { - linkContentType: ["productVariant"], - }, - ], - }) - product - .createField("medusaId") - .name("Medusa ID") - .type("Symbol") -} -``` - -
- -
- -productVariant Content Model - - -Create the file `src/loaders/contentful-migrations/product-variant.ts` with the following content: - -```ts title=src/loaders/contentful-migrations/product-variant.ts -import Migration, { - MigrationContext, -} from "contentful-migration" - -export function productVariantMigration( - migration: Migration, - context?: MigrationContext -) { - const productVariant = migration - .createContentType("productVariant") - .name("Product Variant") - .displayField("title") - - productVariant - .createField("title") - .name("Title") - .type("Symbol") - .required(true) - productVariant - .createField("sku") - .name("SKU") - .type("Symbol") - productVariant - .createField("options") - .name("Options") - .type("Object") - productVariant - .createField("prices") - .name("Prices") - .type("Object") - productVariant - .createField("medusaId") - .name("Medusa ID") - .type("Symbol") -} -``` - -
- -
- -collection Content Model - - -Create the file `src/loaders/contentful-migrations/product-collection.ts` with the following content: - -```ts title=src/loaders/contentful-migrations/product-collection.ts -import Migration, { - MigrationContext, -} from "contentful-migration" - -export function productCollectionMigration( - migration: Migration, - context?: MigrationContext -) { - const collection = migration - .createContentType("collection") - .name("Product Collection") - .displayField("title") - - collection + product .createField("title") .name("Title") .type("Symbol") .required(true) - collection + product + .createField("subtitle") + .name("Subtitle") + .type("Symbol") + product + .createField("handle") + .name("Handle") + .type("Symbol") + product + .createField("thumbnail") + .name("Thumbnail") + .type("Link") + .linkType("Asset") + product + .createField("description") + .name("Description") + .type("Text") + product + .createField("options") + .name("Options") + .type("Object") + product + .createField("tags") + .name("Tags") + .type("Object") + product + .createField("collection") + .name("Collection") + .type("Symbol") + product + .createField("type") + .name("Type") + .type("Symbol") + product + .createField("variants") + .name("Variants") + .type("Array") + .items({ + type: "Link", + linkType: "Entry", + validations: [ + { + linkContentType: ["productVariant"], + }, + ], + }) + product .createField("medusaId") .name("Medusa ID") .type("Symbol") -} -``` -
+ } + ``` -
- -productType Content Model - +
-Create the file `src/loaders/contentful-migrations/product-type.ts` with the following content: +
+ productVariant Content Model -```ts title=src/loaders/contentful-migrations/product-type.ts -import Migration, { - MigrationContext, -} from "contentful-migration" + Create the file `src/loaders/contentful-migrations/product-variant.ts` with the following content: -export function productTypeMigration( - migration: Migration, - context?: MigrationContext -) { - const collection = migration - .createContentType("productType") - .name("Product Type") - .displayField("title") + ```ts title=src/loaders/contentful-migrations/product-variant.ts + import Migration, { + MigrationContext, + } from "contentful-migration" - collection + export function productVariantMigration( + migration: Migration, + context?: MigrationContext + ) { + const productVariant = migration + .createContentType("productVariant") + .name("Product Variant") + .displayField("title") + + productVariant .createField("title") .name("Title") .type("Symbol") .required(true) - collection + productVariant + .createField("sku") + .name("SKU") + .type("Symbol") + productVariant + .createField("options") + .name("Options") + .type("Object") + productVariant + .createField("prices") + .name("Prices") + .type("Object") + productVariant .createField("medusaId") .name("Medusa ID") .type("Symbol") -} -``` -
+ } + ``` + +
+ +
+ collection Content Model + + Create the file `src/loaders/contentful-migrations/product-collection.ts` with the following content: + + ```ts title=src/loaders/contentful-migrations/product-collection.ts + import Migration, { + MigrationContext, + } from "contentful-migration" + + export function productCollectionMigration( + migration: Migration, + context?: MigrationContext + ) { + const collection = migration + .createContentType("collection") + .name("Product Collection") + .displayField("title") + + collection + .createField("title") + .name("Title") + .type("Symbol") + .required(true) + collection + .createField("medusaId") + .name("Medusa ID") + .type("Symbol") + } + ``` + +
+ +
+ productType Content Model + + Create the file `src/loaders/contentful-migrations/product-type.ts` with the following content: + + ```ts title=src/loaders/contentful-migrations/product-type.ts + import Migration, { + MigrationContext, + } from "contentful-migration" + + export function productTypeMigration( + migration: Migration, + context?: MigrationContext + ) { + const collection = migration + .createContentType("productType") + .name("Product Type") + .displayField("title") + + collection + .createField("title") + .name("Title") + .type("Symbol") + .required(true) + collection + .createField("medusaId") + .name("Medusa ID") + .type("Symbol") + } + ``` + +
-
- -region Content Model - +
+ region Content Model -Create the file `src/loaders/contentful-migrations/region.ts` with the following content: + Create the file `src/loaders/contentful-migrations/region.ts` with the following content: -```ts title=src/loaders/contentful-migrations/region.ts -import Migration, { - MigrationContext, -} from "contentful-migration" + ```ts title=src/loaders/contentful-migrations/region.ts + import Migration, { + MigrationContext, + } from "contentful-migration" -export function regionMigration( - migration: Migration, - context?: MigrationContext -) { - const region = migration - .createContentType("region") - .name("Region") - .displayField("name") + export function regionMigration( + migration: Migration, + context?: MigrationContext + ) { + const region = migration + .createContentType("region") + .name("Region") + .displayField("name") - region - .createField("name") - .name("Name") - .type("Symbol") - .required(true) - region - .createField("countries") - .name("Options") - .type("Object") - region - .createField("paymentProviders") - .name("Payment Providers") - .type("Object") - region - .createField("fulfillmentProviders") - .name("Fulfillment Providers") - .type("Object") - region - .createField("currencyCode") - .name("Currency Code") - .type("Symbol") - region - .createField("medusaId") - .name("Medusa ID") - .type("Symbol") -} -``` + region + .createField("name") + .name("Name") + .type("Symbol") + .required(true) + region + .createField("countries") + .name("Options") + .type("Object") + region + .createField("paymentProviders") + .name("Payment Providers") + .type("Object") + region + .createField("fulfillmentProviders") + .name("Fulfillment Providers") + .type("Object") + region + .createField("currencyCode") + .name("Currency Code") + .type("Symbol") + region + .createField("medusaId") + .name("Medusa ID") + .type("Symbol") + } + ``` -
+
Finally, create a [loader](../../development/loaders/overview.mdx) at `src/loaders/index.ts` with the following content: diff --git a/www/apps/docs/content/plugins/notifications/sendgrid.mdx b/www/apps/docs/content/plugins/notifications/sendgrid.mdx index f9246d11ac..aee3dfa4b9 100644 --- a/www/apps/docs/content/plugins/notifications/sendgrid.mdx +++ b/www/apps/docs/content/plugins/notifications/sendgrid.mdx @@ -71,7 +71,7 @@ Medusa supports localization so you can also create multiple templates for multi ## Template Reference -This section covers the template types supported by the plugin and what variables you can expect in your dynamic template. You can use the variables to add details like order total or customer name. +This section covers the template types supported by the plugin and what variables you can expect in your dynamic template. You can use the variables to add Details like order total or customer name. :::note @@ -85,9 +85,9 @@ You don’t have to create a template for every type in the reference. You can s **Description:** Template to be sent to the customer when they place a new order. -
- Example Data - +
+ Example Data + ```json noReport { "beforeInsert": [Function], @@ -304,7 +304,8 @@ You don’t have to create a template for every type in the reference. You can s "updated_at": Any, } ``` -
+ +
### Order Canceled @@ -312,8 +313,8 @@ You don’t have to create a template for every type in the reference. You can s **Description:** Template to be sent to a customer when their order is canceled. -
- Example Data +
+ Example Data ```json noReport { @@ -535,7 +536,8 @@ You don’t have to create a template for every type in the reference. You can s "updated_at": Any, } ``` -
+ +
### Order Shipment Created @@ -543,8 +545,8 @@ You don’t have to create a template for every type in the reference. You can s **Description:** Template to be sent to the customer when a shipment of their order has been created. -
- Example Data +
+ Example Data ```json noReport { @@ -817,7 +819,8 @@ You don’t have to create a template for every type in the reference. You can s "tracking_number": "", } ``` -
+ +
### Order Return Requested @@ -825,8 +828,8 @@ You don’t have to create a template for every type in the reference. You can s **Description:** Template to be sent to the customer when a return request is made for an order. -
- Example Data +
+ Example Data ```json noReport { @@ -1259,7 +1262,8 @@ You don’t have to create a template for every type in the reference. You can s "subtotal": "12.00 USD", } ``` -
+ +
### Order Items Returned @@ -1267,8 +1271,8 @@ You don’t have to create a template for every type in the reference. You can s **Description:** Template to be sent to the customer when an order’s items have been returned. -
- Example Data +
+ Example Data ```json noReport { @@ -1701,7 +1705,8 @@ You don’t have to create a template for every type in the reference. You can s "subtotal": "12.00 USD", } ``` -
+ +
### Claim Shipment Created @@ -1709,8 +1714,8 @@ You don’t have to create a template for every type in the reference. You can s **Description:** Template to be sent to the customer when a Claim shipment has been created. -
- Example Data +
+ Example Data ```json noReport { @@ -1998,7 +2003,8 @@ You don’t have to create a template for every type in the reference. You can s "tracking_number": "", } ``` -
+ +
### Swap Created @@ -2006,8 +2012,8 @@ You don’t have to create a template for every type in the reference. You can s **Description:** Template to be sent to the customer when a swap for an order has been created. -
- Example Data +
+ Example Data ```json noReport { @@ -2507,7 +2513,8 @@ You don’t have to create a template for every type in the reference. You can s "additional_total": "11.25 USD" } ``` -
+ +
### Swap Shipment Created @@ -2515,8 +2522,8 @@ You don’t have to create a template for every type in the reference. You can s **Description:** Template to be sent to the customer when a shipment of a swap of an order has been created. -
- Example Data +
+ Example Data ```json noReport Object { @@ -3087,7 +3094,8 @@ You don’t have to create a template for every type in the reference. You can s "tracking_number": "", } ``` -
+ +
### Swap Received @@ -3095,8 +3103,8 @@ You don’t have to create a template for every type in the reference. You can s **Description:** Template to be sent to the customer when a swap of an order has been received. -
- Example Data +
+ Example Data ```json noReport { @@ -3597,7 +3605,8 @@ You don’t have to create a template for every type in the reference. You can s "additional_total": "11.25 USD" } ``` -
+ +
### Gift Card Created @@ -3605,8 +3614,8 @@ You don’t have to create a template for every type in the reference. You can s **Description:** Template to be to the customer sent when a gift card in their order has been created. -
- Example Data +
+ Example Data ```json noReport Object { @@ -3765,7 +3774,8 @@ You don’t have to create a template for every type in the reference. You can s "display_value": 4 } ``` -
+ +
### Customer Password Reset @@ -3773,8 +3783,8 @@ You don’t have to create a template for every type in the reference. You can s **Description:** Template to be sent to the customer when they request a password reset. -
- Example Data +
+ Example Data ```json noReport Object { @@ -3785,7 +3795,8 @@ You don’t have to create a template for every type in the reference. You can s "token": Any, } ``` -
+ +
### User Password Reset @@ -3793,8 +3804,8 @@ You don’t have to create a template for every type in the reference. You can s **Description:** Template to be sent to the admin user when they request a password reset. -
- Example Data +
+ Example Data ```json noReport Object { @@ -3802,7 +3813,8 @@ You don’t have to create a template for every type in the reference. You can s "token": Any, } ``` -
+ +
### Restock Notification @@ -3810,8 +3822,8 @@ You don’t have to create a template for every type in the reference. You can s **Description:** Template to be sent to admin users when a product has hit the restock quantity threshold. -
- Example Data +
+ Example Data ```json noReport Object { @@ -3899,7 +3911,8 @@ You don’t have to create a template for every type in the reference. You can s ] } ``` -
+ +
--- @@ -4004,8 +4017,7 @@ export const POST = async ( to: "customer@mail.com", dynamic_template_data: { dynamic: "data" }, } - - sendgridService.sendEmail(sendOptions) + sendgridService.sendEmail(sendOptions) } ``` diff --git a/www/apps/docs/content/recipes/b2b.mdx b/www/apps/docs/content/recipes/b2b.mdx index a878fe04d4..c1f595ecc2 100644 --- a/www/apps/docs/content/recipes/b2b.mdx +++ b/www/apps/docs/content/recipes/b2b.mdx @@ -266,62 +266,60 @@ Medusa allows you to create custom API Routes exposed as REST APIs. } }} /> -
- -Example Implementation - +
+ Example Implementation -For example, create the following API Route that allows you to check the customer’s group and whether it has the `is_b2b` flag enabled: + For example, create the following API Route that allows you to check the customer’s group and whether it has the `is_b2b` flag enabled: + + ```ts title=src/api/store/customers/is-b2b/route.ts + import type { + CustomerService, + MedusaRequest, + MedusaResponse, + } from "@medusajs/medusa" + + export const GET = async ( + req: MedusaRequest, + res: MedusaResponse + ) => { + const customerService: CustomerService = req.scope.resolve( + "customerService" + ) + + const customer = await customerService + .retrieve(req.user.customer_id, { + relations: ["groups"], + }) + + const is_b2b = customer.groups.some( + (group) => group.metadata.is_b2b === "true" + ) -```ts title=src/api/store/customers/is-b2b/route.ts -import type { - CustomerService, - MedusaRequest, - MedusaResponse, -} from "@medusajs/medusa" - -export const GET = async ( - req: MedusaRequest, - res: MedusaResponse -) => { - const customerService: CustomerService = req.scope.resolve( - "customerService" - ) - - const customer = await customerService - .retrieve(req.user.customer_id, { - relations: ["groups"], + return res.json({ + is_b2b, }) + } + ``` - const is_b2b = customer.groups.some( - (group) => group.metadata.is_b2b === "true" - ) - - return res.json({ - is_b2b, - }) -} -``` + Then add the `requireCustomerAuthentication` middleware in `src/api/middlewares.ts` that ensures only authenticated customer can access this API Route: -Then add the `requireCustomerAuthentication` middleware in `src/api/middlewares.ts` that ensures only authenticated customer can access this API Route: + ```ts title=src/api/middlewares.ts + import { + requireCustomerAuthentication, + type MiddlewaresConfig, + } from "@medusajs/medusa" -```ts title=src/api/middlewares.ts -import { - requireCustomerAuthentication, - type MiddlewaresConfig, -} from "@medusajs/medusa" + export const config: MiddlewaresConfig = { + routes: [ + { + matcher: "/store/customers/is-b2b", + middlewares: [requireCustomerAuthentication()], + }, + ], + } + ``` -export const config: MiddlewaresConfig = { - routes: [ - { - matcher: "/store/customers/is-b2b", - middlewares: [requireCustomerAuthentication()], - }, - ], -} -``` - -
+
--- diff --git a/www/apps/docs/content/recipes/commerce-automation.mdx b/www/apps/docs/content/recipes/commerce-automation.mdx index 0c4e92a812..32522bd9b4 100644 --- a/www/apps/docs/content/recipes/commerce-automation.mdx +++ b/www/apps/docs/content/recipes/commerce-automation.mdx @@ -100,85 +100,83 @@ Medusa also provides official notification plugins that integrate with third-par }, ]} /> -
- -Example: Sending an email for new notes - - -Here’s an example of a subscriber that uses the SendGrid plugin to send an email to the customer when the order has a new note: +
+ Example: Sending an email for new notes -```ts title=src/subscribers/new-note.ts -import { - EventBusService, - NoteService, - OrderService, -} from "@medusajs/medusa" + Here’s an example of a subscriber that uses the SendGrid plugin to send an email to the customer when the order has a new note: -type InjectedDependencies = { - eventBusService: EventBusService - sendgridService: any - noteService: NoteService - orderService: OrderService -} + ```ts title=src/subscribers/new-note.ts + import { + EventBusService, + NoteService, + OrderService, + } from "@medusajs/medusa" -class NewNoteSubscriber { - protected sendGridService_: any - protected noteService_: NoteService - protected orderService_: OrderService - - constructor({ - eventBusService, - sendgridService, - noteService, - orderService, - }: InjectedDependencies) { - this.noteService_ = noteService - this.orderService_ = orderService - this.sendGridService_ = sendgridService - eventBusService.subscribe( - "note.created", - this.handleNoteCreated - ) + type InjectedDependencies = { + eventBusService: EventBusService + sendgridService: any + noteService: NoteService + orderService: OrderService } - handleNoteCreated = async (data) => { - // retrieve note by id - const note = await this.noteService_.retrieve(data.id, { - relations: ["author"], - }) + class NewNoteSubscriber { + protected sendGridService_: any + protected noteService_: NoteService + protected orderService_: OrderService - if (!note || note.resource_type !== "order") { - return + constructor({ + eventBusService, + sendgridService, + noteService, + orderService, + }: InjectedDependencies) { + this.noteService_ = noteService + this.orderService_ = orderService + this.sendGridService_ = sendgridService + eventBusService.subscribe( + "note.created", + this.handleNoteCreated + ) } - // retrieve note's order - const order = await this.orderService_.retrieve( - note.resource_id - ) + handleNoteCreated = async (data) => { + // retrieve note by id + const note = await this.noteService_.retrieve(data.id, { + relations: ["author"], + }) - if (!order) { - return + if (!note || note.resource_type !== "order") { + return + } + + // retrieve note's order + const order = await this.orderService_.retrieve( + note.resource_id + ) + + if (!order) { + return + } + + this.sendGridService_.sendEmail({ + templateId: "order-update", + from: "hello@medusajs.com", + to: order.email, + dynamic_template_data: { + // any data necessary for your template... + note_text: note.value, + note_author: note.author.first_name, + note_date: note.created_at, + order_id: order.display_id, + }, + }) } - - this.sendGridService_.sendEmail({ - templateId: "order-update", - from: "hello@medusajs.com", - to: order.email, - dynamic_template_data: { - // any data necessary for your template... - note_text: note.value, - note_author: note.author.first_name, - note_date: note.created_at, - order_id: order.display_id, - }, - }) } -} -export default NewNoteSubscriber -``` + export default NewNoteSubscriber + ``` -
+
--- @@ -198,75 +196,73 @@ You can implement automatic synchronization in Medusa using scheduled jobs. A sc } }} /> -
- -Example: Synchronizing products with a third-party service - +
+ Example: Synchronizing products with a third-party service -Here’s an example of synchronizing products with a third party service using a [loader](../development/loaders/create.md): + Here’s an example of synchronizing products with a third party service using a [loader](../development/loaders/create.md): -```ts title=src/loaders/sync-products.ts -import { - Logger, - ProductService, - StoreService, -} from "@medusajs/medusa" -import { - ProductSelector, -} from "@medusajs/medusa/dist/types/product" -import { AwilixContainer } from "awilix" + ```ts title=src/loaders/sync-products.ts + import { + Logger, + ProductService, + StoreService, + } from "@medusajs/medusa" + import { + ProductSelector, + } from "@medusajs/medusa/dist/types/product" + import { AwilixContainer } from "awilix" -export default async ( - container: AwilixContainer, - config: Record -): Promise => { - const logger = container.resolve("logger") - logger.info("Synchronizing products...") - const productService = container.resolve( - "productService" - ) - const storeService = container.resolve( - "storeService" - ) - // retrieve store to get last sync date - const store = await storeService.retrieve() + export default async ( + container: AwilixContainer, + config: Record + ): Promise => { + const logger = container.resolve("logger") + logger.info("Synchronizing products...") + const productService = container.resolve( + "productService" + ) + const storeService = container.resolve( + "storeService" + ) + // retrieve store to get last sync date + const store = await storeService.retrieve() - const productFilters: ProductSelector = {} + const productFilters: ProductSelector = {} - if (store.metadata.last_sync_date) { - productFilters.updated_at = { - gt: new Date( - store.metadata.last_sync_date as string - ), + if (store.metadata.last_sync_date) { + productFilters.updated_at = { + gt: new Date( + store.metadata.last_sync_date as string + ), + } } + + const updatedProducts = await productService.list( + productFilters + ) + + updatedProducts.forEach((product) => { + // assuming client is an initialized connection + // with a third-party service + client.sync(product) + }) + + await storeService.update({ + metadata: { + last_sync_date: new Date(), + }, + }) + + logger.info("Finish synchronizing products") } + ``` - const updatedProducts = await productService.list( - productFilters - ) - - updatedProducts.forEach((product) => { - // assuming client is an initialized connection - // with a third-party service - client.sync(product) - }) + Notice that here it’s assumed that: - await storeService.update({ - metadata: { - last_sync_date: new Date(), - }, - }) - - logger.info("Finish synchronizing products") -} -``` + 1. The last update date is stored in the `Store`'s metadata object. You can instead use a custom entity to handle this. + 2. The connection to the third-party service is assumed to be available and handled within the `client` variable. -Notice that here it’s assumed that: - -1. The last update date is stored in the `Store`'s metadata object. You can instead use a custom entity to handle this. -2. The connection to the third-party service is assumed to be available and handled within the `client` variable. - -
+
--- @@ -419,88 +415,86 @@ For example, if you're grouping customers with over twenty orders, you can use a }, ]} /> -
- -Example: Add customer to VIP group - +
+ Example: Add customer to VIP group -Here’s an example of a subscriber that listens to the `order.placed` event and checks if the customer should be added to the VIP customer group based on their number of orders: + Here’s an example of a subscriber that listens to the `order.placed` event and checks if the customer should be added to the VIP customer group based on their number of orders: -```ts title=src/subscribers/add-custom-to-vip.ts -import { - CustomerGroupService, - CustomerService, - EventBusService, - OrderService, -} from "@medusajs/medusa" + ```ts title=src/subscribers/add-custom-to-vip.ts + import { + CustomerGroupService, + CustomerService, + EventBusService, + OrderService, + } from "@medusajs/medusa" -type InjectedDependencies = { - orderService: OrderService - customerService: CustomerService - customerGroupService: CustomerGroupService - eventBusService: EventBusService -} - -class AddCustomerToVipSubscriber { - protected orderService_: OrderService - protected customerService_: CustomerService - protected customerGroupService_: CustomerGroupService - - constructor({ - orderService, - customerService, - customerGroupService, - eventBusService, - }: InjectedDependencies) { - this.orderService_ = orderService - this.customerService_ = customerService - this.customerGroupService_ = customerGroupService - eventBusService.subscribe( - "order.placed", - this.handleOrderPlaced - ) + type InjectedDependencies = { + orderService: OrderService + customerService: CustomerService + customerGroupService: CustomerGroupService + eventBusService: EventBusService } - handleOrderPlaced = async ({ id }) => { - // check if VIP group exists - const vipGroup = await this.customerGroupService_.list({ - name: "VIP", - }, { - relations: ["customers"], - }) - if (!vipGroup.length) { - return - } + class AddCustomerToVipSubscriber { + protected orderService_: OrderService + protected customerService_: CustomerService + protected customerGroupService_: CustomerGroupService - // retrieve order and its customer - const order = await this.orderService_.retrieve(id) - - if (!order || !order.customer_id || - vipGroup[0].customers.find( - (customer) => customer.id === order.customer_id - ) !== undefined) { - return - } - - // retrieve orders of this customer - const [, count] = await this.orderService_.listAndCount({ - customer_id: order.customer_id, - }) - - if (count >= 20) { - // add customer to VIP group - this.customerGroupService_.addCustomers( - vipGroup[0].id, - order.customer_id + constructor({ + orderService, + customerService, + customerGroupService, + eventBusService, + }: InjectedDependencies) { + this.orderService_ = orderService + this.customerService_ = customerService + this.customerGroupService_ = customerGroupService + eventBusService.subscribe( + "order.placed", + this.handleOrderPlaced ) } + + handleOrderPlaced = async ({ id }) => { + // check if VIP group exists + const vipGroup = await this.customerGroupService_.list({ + name: "VIP", + }, { + relations: ["customers"], + }) + if (!vipGroup.length) { + return + } + + // retrieve order and its customer + const order = await this.orderService_.retrieve(id) + + if (!order || !order.customer_id || + vipGroup[0].customers.find( + (customer) => customer.id === order.customer_id + ) !== undefined) { + return + } + + // retrieve orders of this customer + const [, count] = await this.orderService_.listAndCount({ + customer_id: order.customer_id, + }) + + if (count >= 20) { + // add customer to VIP group + this.customerGroupService_.addCustomers( + vipGroup[0].id, + order.customer_id + ) + } + } } -} -export default AddCustomerToVipSubscriber -``` + export default AddCustomerToVipSubscriber + ``` -
+
--- @@ -543,105 +537,103 @@ You can alternatively have a Scheduled Job that checks if the number of new prod }, ]} /> -
- -Example: Sending a newsletter email after adding ten products - +
+ Example: Sending a newsletter email after adding ten products -Here’s an example of listening to the `product.created` event in a subscriber and send a newsletter if the condition is met: + Here’s an example of listening to the `product.created` event in a subscriber and send a newsletter if the condition is met: -```ts title=src/subscribers/send-products-newsletter.ts -import { - CustomerService, - EventBusService, - NoteService, - OrderService, - ProductService, - StoreService, -} from "@medusajs/medusa" -import { - ProductSelector, -} from "@medusajs/medusa/dist/types/product" + ```ts title=src/subscribers/send-products-newsletter.ts + import { + CustomerService, + EventBusService, + NoteService, + OrderService, + ProductService, + StoreService, + } from "@medusajs/medusa" + import { + ProductSelector, + } from "@medusajs/medusa/dist/types/product" -type InjectedDependencies = { - eventBusService: EventBusService - sendgridService: any - productService: ProductService - storeService: StoreService - customerService: CustomerService -} - -class SendProductsNewsletterSubscriber { - protected sendGridService_: any - protected productService_: ProductService - protected storeService_: StoreService - protected customerService_: CustomerService - - constructor({ - eventBusService, - sendgridService, - productService, - storeService, - customerService, - }: InjectedDependencies) { - this.productService_ = productService - this.sendGridService_ = sendgridService - this.storeService_ = storeService - this.customerService_ = customerService - eventBusService.subscribe( - "product.created", - this.handleProductCreated - ) + type InjectedDependencies = { + eventBusService: EventBusService + sendgridService: any + productService: ProductService + storeService: StoreService + customerService: CustomerService } - handleProductCreated = async ({ id }) => { - // retrieve store to have access to last send date - const store = await this.storeService_.retrieve() - - const productFilters: ProductSelector = {} - if (store.metadata.last_send_date) { - productFilters.created_at = { - gt: new Date(store.metadata.last_send_date as string), + class SendProductsNewsletterSubscriber { + protected sendGridService_: any + protected productService_: ProductService + protected storeService_: StoreService + protected customerService_: CustomerService + + constructor({ + eventBusService, + sendgridService, + productService, + storeService, + customerService, + }: InjectedDependencies) { + this.productService_ = productService + this.sendGridService_ = sendgridService + this.storeService_ = storeService + this.customerService_ = customerService + eventBusService.subscribe( + "product.created", + this.handleProductCreated + ) + } + + handleProductCreated = async ({ id }) => { + // retrieve store to have access to last send date + const store = await this.storeService_.retrieve() + + const productFilters: ProductSelector = {} + if (store.metadata.last_send_date) { + productFilters.created_at = { + gt: new Date(store.metadata.last_send_date as string), + } + } + + const products = await this.productService_.list( + productFilters + ) + + if (products.length > 10) { + // get subscribed customers + const customers = await this.customerService_.list({ + metadata: { + is_subscribed: true, + }, + }) + this.sendGridService_.sendEmail({ + templateId: "product-newsletter", + from: "hello@medusajs.com", + to: customers.map((customer) => ({ + name: customer.first_name, + email: customer.email, + })), + dynamic_template_data: { + // any data necessary for your template... + products, + }, + }) + + await this.storeService_.update({ + metadata: { + last_send_date: new Date(), + }, + }) } } - - const products = await this.productService_.list( - productFilters - ) - - if (products.length > 10) { - // get subscribed customers - const customers = await this.customerService_.list({ - metadata: { - is_subscribed: true, - }, - }) - this.sendGridService_.sendEmail({ - templateId: "product-newsletter", - from: "hello@medusajs.com", - to: customers.map((customer) => ({ - name: customer.first_name, - email: customer.email, - })), - dynamic_template_data: { - // any data necessary for your template... - products, - }, - }) - - await this.storeService_.update({ - metadata: { - last_send_date: new Date(), - }, - }) - } } -} -export default SendProductsNewsletterSubscriber -``` + export default SendProductsNewsletterSubscriber + ``` -
+
--- diff --git a/www/apps/docs/content/recipes/digital-products.mdx b/www/apps/docs/content/recipes/digital-products.mdx index 44235e6539..b1326b13c0 100644 --- a/www/apps/docs/content/recipes/digital-products.mdx +++ b/www/apps/docs/content/recipes/digital-products.mdx @@ -135,99 +135,97 @@ For example, if you're selling the Harry Potter movies, you would have a `Produc }, ]} /> -
- -Example: Create ProductMedia Entity - +
+ Example: Create ProductMedia Entity -In this example, you’ll create a `ProductMedia` entity that is associated with the `ProductVariant` entity in a one-to-many relation. + In this example, you’ll create a `ProductMedia` entity that is associated with the `ProductVariant` entity in a one-to-many relation. -To do that, create the file `src/models/product-media.ts` with the following content: + To do that, create the file `src/models/product-media.ts` with the following content: -```ts title=src/models/product-media.ts -import { - BeforeInsert, - Column, - Entity, -} from "typeorm" -import { BaseEntity, ProductVariant } from "@medusajs/medusa" -import { generateEntityId } from "@medusajs/medusa/dist/utils" + ```ts title=src/models/product-media.ts + import { + BeforeInsert, + Column, + Entity, + } from "typeorm" + import { BaseEntity, ProductVariant } from "@medusajs/medusa" + import { generateEntityId } from "@medusajs/medusa/dist/utils" -export enum MediaType { - MAIN = "main", - PREVIEW = "preview" -} - -@Entity() -export class ProductMedia extends BaseEntity { - @Column({ type: "varchar" }) - name: string - - @Column ({ type: "enum", enum: MediaType, default: "main" }) - type: MediaType - - @Column({ type: "varchar" }) - file_key: string - - @Column({ type: "varchar" }) - mime_type: string - - @Column({ type: "varchar" }) - variant_id: string - - variant?: ProductVariant - - @BeforeInsert() - private beforeInsert(): void { - this.id = generateEntityId(this.id, "post") + export enum MediaType { + MAIN = "main", + PREVIEW = "preview" } -} -``` -The entity has the following attributes: + @Entity() + export class ProductMedia extends BaseEntity { + @Column({ type: "varchar" }) + name: string -- `name`: a string indicating the file name or a name entered by the merchant. -- `type`: an enum value indicating the type of file. If the file’s type is `main`, it means that this is the file that customers download when they purchase the product. If its type is `preview`, it means that the file is only used to preview the product variant to the customer. -- `file_key`: a string that indicates the downloadable file’s key. The key is retrieved by the installed file service, which is covered in the next step, and it’s used later if you want to get a downloadable link or delete the file. -- `variant_id`: a string indicating the ID of the product variant this file is associated with. -- `mime_type`: a string indicating the MIME type of the product variant. + @Column ({ type: "enum", enum: MediaType, default: "main" }) + type: MediaType -Next, you need to create a migration script that reflects the changes on the database schema. + @Column({ type: "varchar" }) + file_key: string -To do that, run the following command to create a migration file: + @Column({ type: "varchar" }) + mime_type: string -```bash -npx typeorm migration:create src/migrations/ProductMediaCreate -``` + @Column({ type: "varchar" }) + variant_id: string -This will create a file in the `src/migrations` directory. The file’s name will be of the format `-ProductMediaCreate.ts`, where `` is the time this migration was created. + variant?: ProductVariant -In the class defined in the file, change the `up` and `down` method to the following: + @BeforeInsert() + private beforeInsert(): void { + this.id = generateEntityId(this.id, "post") + } + } + ``` + + The entity has the following attributes: + + - `name`: a string indicating the file name or a name entered by the merchant. + - `type`: an enum value indicating the type of file. If the file’s type is `main`, it means that this is the file that customers download when they purchase the product. If its type is `preview`, it means that the file is only used to preview the product variant to the customer. + - `file_key`: a string that indicates the downloadable file’s key. The key is retrieved by the installed file service, which is covered in the next step, and it’s used later if you want to get a downloadable link or delete the file. + - `variant_id`: a string indicating the ID of the product variant this file is associated with. + - `mime_type`: a string indicating the MIME type of the product variant. + + Next, you need to create a migration script that reflects the changes on the database schema. + + To do that, run the following command to create a migration file: + + ```bash + npx typeorm migration:create src/migrations/ProductMediaCreate + ``` + + This will create a file in the `src/migrations` directory. The file’s name will be of the format `-ProductMediaCreate.ts`, where `` is the time this migration was created. + + In the class defined in the file, change the `up` and `down` method to the following: -```ts -export class ProductMediaCreate1693901604934 implements MigrationInterface { - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TYPE "public"."product_media_type_enum" AS ENUM('main', 'preview')`) - await queryRunner.query(`CREATE TABLE "product_media" ("id" character varying NOT NULL, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "name" character varying NOT NULL, "type" "public"."product_media_type_enum" NOT NULL DEFAULT 'main', "file_key" character varying NOT NULL, "mime_type" character varying NOT NULL, "variant_id" character varying NOT NULL, CONSTRAINT "PK_09d4639de8082a32aa27f3ac9a6" PRIMARY KEY ("id"))`) + ```ts + export class ProductMediaCreate1693901604934 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TYPE "public"."product_media_type_enum" AS ENUM('main', 'preview')`) + await queryRunner.query(`CREATE TABLE "product_media" ("id" character varying NOT NULL, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "name" character varying NOT NULL, "type" "public"."product_media_type_enum" NOT NULL DEFAULT 'main', "file_key" character varying NOT NULL, "mime_type" character varying NOT NULL, "variant_id" character varying NOT NULL, CONSTRAINT "PK_09d4639de8082a32aa27f3ac9a6" PRIMARY KEY ("id"))`) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP TABLE "product_media"`) + await queryRunner.query(`DROP TYPE "public"."product_media_type_enum"`) + } } + ``` - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP TABLE "product_media"`) - await queryRunner.query(`DROP TYPE "public"."product_media_type_enum"`) - } -} -``` + To apply the migrations on your database and create the `product_media` table, run the following commands in the root directory of your Medusa backend: -To apply the migrations on your database and create the `product_media` table, run the following commands in the root directory of your Medusa backend: + ```bash npm2yarn + npm run build + npx medusa migrations run + ``` -```bash npm2yarn -npm run build -npx medusa migrations run -``` - -
+
--- @@ -267,263 +265,261 @@ Creating an API Route also requires creating a service, which is a class that ty }, ]} /> -
- -Example: List and Create API Routes - +
+ Example: List and Create API Routes -This example showcases how you can create the list and create API Routes for digital products. These API Routes are chosen in particular as they’re used in later parts of this recipe. You may follow the same instructions to create other necessary API Routes. + This example showcases how you can create the list and create API Routes for digital products. These API Routes are chosen in particular as they’re used in later parts of this recipe. You may follow the same instructions to create other necessary API Routes. -Before creating the API Routes, you’ll create the `ProductMediaService`. Create the file `src/services/product-media.ts` with the following content: + Before creating the API Routes, you’ll create the `ProductMediaService`. Create the file `src/services/product-media.ts` with the following content: -```ts title=src/services/product-media.ts -import { - FindConfig, - ProductVariantService, - Selector, - TransactionBaseService, - buildQuery, -} from "@medusajs/medusa" -import { ProductMedia } from "../models/product-media" -import { MedusaError } from "@medusajs/utils" + ```ts title=src/services/product-media.ts + import { + FindConfig, + ProductVariantService, + Selector, + TransactionBaseService, + buildQuery, + } from "@medusajs/medusa" + import { ProductMedia } from "../models/product-media" + import { MedusaError } from "@medusajs/utils" -type InjectedDependencies = { - productVariantService: ProductVariantService -} - -class ProductMediaService extends TransactionBaseService { - protected productVariantService_: ProductVariantService - - constructor(container: InjectedDependencies) { - super(container) - this.productVariantService_ = - container.productVariantService + type InjectedDependencies = { + productVariantService: ProductVariantService } - private checkVariantInRelations( - relations: string[] - ): [string[], boolean] { - const variantsRelationIndex = relations.indexOf("variant") - const isVariantsEnabled = variantsRelationIndex !== -1 - if (isVariantsEnabled) { - relations.splice(variantsRelationIndex, 1) + class ProductMediaService extends TransactionBaseService { + protected productVariantService_: ProductVariantService + + constructor(container: InjectedDependencies) { + super(container) + this.productVariantService_ = + container.productVariantService } - return [relations, isVariantsEnabled] - } + private checkVariantInRelations( + relations: string[] + ): [string[], boolean] { + const variantsRelationIndex = relations.indexOf("variant") + const isVariantsEnabled = variantsRelationIndex !== -1 + if (isVariantsEnabled) { + relations.splice(variantsRelationIndex, 1) + } - async listAndCount( - selector?: Selector, - config: FindConfig = { - skip: 0, - take: 20, - relations: [], - } - ): Promise<[ProductMedia[], number]> { - const productMediaRepo = this.activeManager_.getRepository( - ProductMedia - ) - - const [ - relations, - isVariantsEnabled, - ] = this.checkVariantInRelations( - config.relations || [] - ) - - config.relations = relations - - const query = buildQuery(selector, config) - - const [ - productMedias, - count, - ] = await productMediaRepo.findAndCount(query) - - if (isVariantsEnabled) { - // retrieve product variants - await Promise.all(productMedias.map( - async (media, index) => { - productMedias[index].variant = - await this.retrieveVariantByMedia(media) - })) + return [relations, isVariantsEnabled] } - return [productMedias, count] - } - - async list( - selector?: Selector, - config: FindConfig = { - skip: 0, - take: 20, - relations: [], - } - ): Promise { - const [productMedias] = await this.listAndCount( - selector, config + async listAndCount( + selector?: Selector, + config: FindConfig = { + skip: 0, + take: 20, + relations: [], + } + ): Promise<[ProductMedia[], number]> { + const productMediaRepo = this.activeManager_.getRepository( + ProductMedia ) - return productMedias - } + const [ + relations, + isVariantsEnabled, + ] = this.checkVariantInRelations( + config.relations || [] + ) - async retrieve( - id: string, - config?: FindConfig - ): Promise { - const productMediaRepo = this.activeManager_.getRepository( - ProductMedia - ) + config.relations = relations - const query = buildQuery({ - id, - }, config) + const query = buildQuery(selector, config) - const productMedia = await productMediaRepo.findOne(query) + const [ + productMedias, + count, + ] = await productMediaRepo.findAndCount(query) - if (!productMedia) { - throw new MedusaError( - MedusaError.Types.NOT_FOUND, - "ProductMedia was not found" + if (isVariantsEnabled) { + // retrieve product variants + await Promise.all(productMedias.map( + async (media, index) => { + productMedias[index].variant = + await this.retrieveVariantByMedia(media) + })) + } + + return [productMedias, count] + } + + async list( + selector?: Selector, + config: FindConfig = { + skip: 0, + take: 20, + relations: [], + } + ): Promise { + const [productMedias] = await this.listAndCount( + selector, config + ) + + return productMedias + } + + async retrieve( + id: string, + config?: FindConfig + ): Promise { + const productMediaRepo = this.activeManager_.getRepository( + ProductMedia + ) + + const query = buildQuery({ + id, + }, config) + + const productMedia = await productMediaRepo.findOne(query) + + if (!productMedia) { + throw new MedusaError( + MedusaError.Types.NOT_FOUND, + "ProductMedia was not found" + ) + } + + if (config.relations.includes("variant")) { + productMedia.variant = await this.retrieveVariantByMedia( + productMedia + ) + } + + return productMedia + } + + async retrieveVariantByMedia(productMedia: ProductMedia) { + return await this.productVariantService_.retrieve( + productMedia.variant_id, + { + relations: ["product"], + } ) } - if (config.relations.includes("variant")) { - productMedia.variant = await this.retrieveVariantByMedia( - productMedia - ) + async create( + data: Pick< + ProductMedia, + "name" | "file_key" | "variant_id" | "type" | "mime_type" + > + ): Promise { + return this.atomicPhase_(async (manager) => { + const productMediaRepo = manager.getRepository( + ProductMedia + ) + const productMedia = productMediaRepo.create(data) + const result = await productMediaRepo.save(productMedia) + + return result + }) } - return productMedia + async update( + id: string, + data: Omit, "id"> + ): Promise { + return await this.atomicPhase_(async (manager) => { + const productMediaRepo = manager.getRepository( + ProductMedia + ) + const productMedia = await this.retrieve(id) + + Object.assign(productMedia, data) + + return await productMediaRepo.save(productMedia) + }) + } + + async delete(id: string): Promise { + return await this.atomicPhase_(async (manager) => { + const productMediaRepo = manager.getRepository( + ProductMedia + ) + const productMedia = await this.retrieve(id) + + await productMediaRepo.remove([productMedia]) + }) + } } - async retrieveVariantByMedia(productMedia: ProductMedia) { - return await this.productVariantService_.retrieve( - productMedia.variant_id, - { - relations: ["product"], + export default ProductMediaService + ``` + + This service implements the necessary methods to perform the basic CRUD operations. You can add any other method if necessary. + + You can now create the API Routes. Create the file `src/api/admin/product-media/route.ts` with the following content: + + ```ts title=src/api/admin/product-media/route.ts + import type { + MedusaRequest, + MedusaResponse, + } from "@medusajs/medusa" + import ProductMediaService + from "../../../services/product-media" + import { MediaType } from "../../../models/product-media" + + export const GET = async ( + req: MedusaRequest, + res: MedusaResponse + ) => { + const productMediaService = req.scope.resolve< + ProductMediaService + >("productMediaService") + // omitting pagination for simplicity + const [productMedias, count] = await productMediaService + .listAndCount({ + type: MediaType.MAIN, + }, { + relations: ["variant"], } ) - } - async create( - data: Pick< - ProductMedia, - "name" | "file_key" | "variant_id" | "type" | "mime_type" - > - ): Promise { - return this.atomicPhase_(async (manager) => { - const productMediaRepo = manager.getRepository( - ProductMedia - ) - const productMedia = productMediaRepo.create(data) - const result = await productMediaRepo.save(productMedia) - - return result + res.json({ + product_medias: productMedias, + count, }) } - async update( - id: string, - data: Omit, "id"> - ): Promise { - return await this.atomicPhase_(async (manager) => { - const productMediaRepo = manager.getRepository( - ProductMedia - ) - const productMedia = await this.retrieve(id) + export const POST = async ( + req: MedusaRequest, + res: MedusaResponse + ) => { + // validation omitted for simplicity + const { + variant_id, + file_key, + type = "main", + name, + mime_type, + } = req.body - Object.assign(productMedia, data) + const productMediaService = req.scope.resolve< + ProductMediaService + >("productMediaService") + const productMedia = await productMediaService.create({ + variant_id, + file_key, + type, + name, + }) - return await productMediaRepo.save(productMedia) + res.json({ + product_media: productMedia, }) } + ``` - async delete(id: string): Promise { - return await this.atomicPhase_(async (manager) => { - const productMediaRepo = manager.getRepository( - ProductMedia - ) - const productMedia = await this.retrieve(id) - - await productMediaRepo.remove([productMedia]) - }) - } -} + This creates two API Routes: -export default ProductMediaService -``` + - a `GET` API Route at `/admin/product-media` that retrieves a list of product media records that have the type `main`. It also retrieves the relations `variant` and `variant.product` to access the product media’s variant and main product. + - a `POST` API Route at `/admin/product-media` that accepts the necessary data to create a product media, then returns the created product media. -This service implements the necessary methods to perform the basic CRUD operations. You can add any other method if necessary. - -You can now create the API Routes. Create the file `src/api/admin/product-media/route.ts` with the following content: - -```ts title=src/api/admin/product-media/route.ts -import type { - MedusaRequest, - MedusaResponse, -} from "@medusajs/medusa" -import ProductMediaService - from "../../../services/product-media" -import { MediaType } from "../../../models/product-media" - -export const GET = async ( - req: MedusaRequest, - res: MedusaResponse -) => { - const productMediaService = req.scope.resolve< - ProductMediaService - >("productMediaService") - // omitting pagination for simplicity - const [productMedias, count] = await productMediaService - .listAndCount({ - type: MediaType.MAIN, - }, { - relations: ["variant"], - } - ) - - res.json({ - product_medias: productMedias, - count, - }) -} - -export const POST = async ( - req: MedusaRequest, - res: MedusaResponse -) => { - // validation omitted for simplicity - const { - variant_id, - file_key, - type = "main", - name, - mime_type, - } = req.body - - const productMediaService = req.scope.resolve< - ProductMediaService - >("productMediaService") - const productMedia = await productMediaService.create({ - variant_id, - file_key, - type, - name, - }) - - res.json({ - product_media: productMedia, - }) -} -``` - -This creates two API Routes: - -- a `GET` API Route at `/admin/product-media` that retrieves a list of product media records that have the type `main`. It also retrieves the relations `variant` and `variant.product` to access the product media’s variant and main product. -- a `POST` API Route at `/admin/product-media` that accepts the necessary data to create a product media, then returns the created product media. - -
+
--- @@ -564,362 +560,360 @@ To add an interface that allows the admin user to upload digital products, you c }, ]} /> -
- -Example: Digital Products Page in Admin - +
+ Example: Digital Products Page in Admin -In this example, you’ll add a single page that lists the digital products and allows you to create a new one. The implementation will be minimal for the purpose of simplicity, so you can elaborate on it based on your use case. - -Before starting off, make sure to install the necessary dependencies in your Medusa backend project: + In this example, you’ll add a single page that lists the digital products and allows you to create a new one. The implementation will be minimal for the purpose of simplicity, so you can elaborate on it based on your use case. + + Before starting off, make sure to install the necessary dependencies in your Medusa backend project: -```bash npm2yarn -npm install medusa-react @tanstack/react-query @medusajs/ui -``` + ```bash npm2yarn + npm install medusa-react @tanstack/react-query @medusajs/ui + ``` -This installs the necessary packages to use the Medusa React client and the [Medusa UI package](https://docs.medusajs.com/ui). + This installs the necessary packages to use the Medusa React client and the [Medusa UI package](https://docs.medusajs.com/ui). -You also need to create types for the expected requests and responses of the API Routes you created. This is helpful when using Medusa React’s custom hooks. To do that, create the file `src/types/product-media.ts` with the following content: + You also need to create types for the expected requests and responses of the API Routes you created. This is helpful when using Medusa React’s custom hooks. To do that, create the file `src/types/product-media.ts` with the following content: -```ts title=src/types/product-media.ts -import { - MediaType, - ProductMedia, -} from "../models/product-media" + ```ts title=src/types/product-media.ts + import { + MediaType, + ProductMedia, + } from "../models/product-media" -export type ListProductMediasRequest = { - // no expected parameters -}; + export type ListProductMediasRequest = { + // no expected parameters + }; -export type ListProductMediasResponse = { - product_medias: ProductMedia[] - count: number -}; + export type ListProductMediasResponse = { + product_medias: ProductMedia[] + count: number + }; -export type CreateProductMediaRequest = { - variant_id: string - name: string - file_key: string - type?: MediaType - mime_type: string -}; + export type CreateProductMediaRequest = { + variant_id: string + name: string + file_key: string + type?: MediaType + mime_type: string + }; -export type CreateProductMediaResponse = { - product_media: ProductMedia -}; -``` + export type CreateProductMediaResponse = { + product_media: ProductMedia + }; + ``` -You can now create your admin UI route. To do that, create the file `src/admin/routes/product-media/page.tsx` with the following content: + You can now create your admin UI route. To do that, create the file `src/admin/routes/product-media/page.tsx` with the following content: -```tsx title=src/admin/routes/product-media/page.tsx -import { RouteConfig } from "@medusajs/admin" -import { DocumentText } from "@medusajs/icons" -import { useAdminCustomQuery } from "medusa-react" -import { - ListProductMediasRequest, - ListProductMediasResponse, -} from "../../../types/product-media" -import { - Button, - Container, - Drawer, - Heading, - Table, -} from "@medusajs/ui" -import { Link } from "react-router-dom" -import { RouteProps } from "@medusajs/admin-ui" -import ProductMediaCreateForm - from "../../components/product-media/CreateForm" - -const ProductMediaListPage = (props: RouteProps) => { - const { data, isLoading } = useAdminCustomQuery< + ```tsx title=src/admin/routes/product-media/page.tsx + import { RouteConfig } from "@medusajs/admin" + import { DocumentText } from "@medusajs/icons" + import { useAdminCustomQuery } from "medusa-react" + import { ListProductMediasRequest, - ListProductMediasResponse - >( - "/product-media", - ["product-media"] - ) + ListProductMediasResponse, + } from "../../../types/product-media" + import { + Button, + Container, + Drawer, + Heading, + Table, + } from "@medusajs/ui" + import { Link } from "react-router-dom" + import { RouteProps } from "@medusajs/admin-ui" + import ProductMediaCreateForm + from "../../components/product-media/CreateForm" - return ( - -
- Digital Products - - - - - - - - Create Digital Product - - - - - - - -
- {isLoading &&
Loading...
} - {data && !data.product_medias.length && ( -
No Digital Products
- )} - {data && data.product_medias.length > 0 && ( - - - - Product - - Product Variant - - File Key - Action - - - - {data.product_medias.map((product_media) => ( - - - {product_media.variant.product.title} - - - {product_media.variant.title} - - - {product_media.file_key} - - - - View Product - - + const ProductMediaListPage = (props: RouteProps) => { + const { data, isLoading } = useAdminCustomQuery< + ListProductMediasRequest, + ListProductMediasResponse + >( + "/product-media", + ["product-media"] + ) + + return ( + +
+ Digital Products + + + + + + + + Create Digital Product + + + + + + + +
+ {isLoading &&
Loading...
} + {data && !data.product_medias.length && ( +
No Digital Products
+ )} + {data && data.product_medias.length > 0 && ( +
+ + + Product + + Product Variant + + File Key + Action - ))} - -
- )} -
- ) -} - -export const config: RouteConfig = { - link: { - label: "Digital Products", - icon: DocumentText, - }, -} - -export default ProductMediaListPage -``` - -This UI route will show under the sidebar with the label “Digital Products”. In the page, you use the `useAdminCustomQuery` hook imported from `medusa-react` to send a request to your custom “list digital products” API Route. - -In the page, you’ll show the list of digital products in a table, if there are any. You’ll also show a button that opens a drawer to the side of the page. - -In the drawer, you show the Create Digital Product form. To create this form, create the file `src/admin/components/product-media/CreateForm/index.tsx` with the following content: - -```tsx title=src/admin/components/product-media/CreateForm/index.tsx -import { useState } from "react" -import { MediaType } from "../../../../models/product-media" -import { - useAdminCreateProduct, - useAdminCustomPost, - useAdminUploadProtectedFile, -} from "medusa-react" -import { - CreateProductMediaRequest, - CreateProductMediaResponse, -} from "../../../../types/product-media" -import { - Button, - Container, - Input, - Label, - Select, -} from "@medusajs/ui" -import { RouteProps } from "@medusajs/admin-ui" -import { useNavigate } from "react-router-dom" - -const ProductMediaCreateForm = ({ - notify, -}: RouteProps) => { - const [productName, setProductName] = useState("") - const [ - productVariantName, - setProductVariantName, - ] = useState("") - const [name, setName] = useState("") - const [type, setType] = useState("main") - const [file, setFile] = useState() - - const createProduct = useAdminCreateProduct() - const uploadFile = useAdminUploadProtectedFile() - const { - mutate: createDigitalProduct, - isLoading, - } = useAdminCustomPost< - CreateProductMediaRequest, - CreateProductMediaResponse - >( - "/product-media", - ["product-media"] - ) - - const navigate = useNavigate() - - const handleSubmit = ( - e: React.FormEvent - ) => { - e.preventDefault() - - createProduct.mutate({ - title: productName, - is_giftcard: false, - discountable: false, - options: [ - { - title: "Digital Product", - }, - ], - variants: [ - { - title: productVariantName, - options: [ - { - value: name, // can also be the file name - }, - ], - // for simplicity, prices are omitted from form. - // Those can be edited from the product's page. - prices: [], - }, - ], - }, { - onSuccess: ({ product }) => { - // upload file - uploadFile.mutate(file, { - onSuccess: ({ uploads }) => { - if (!("key" in uploads[0])) { - return - } - // create the digital product - createDigitalProduct({ - variant_id: product.variants[0].id, - name, - file_key: uploads[0].key as string, - type: type as MediaType, - mime_type: file.type, - }, { - onSuccess: () => { - notify.success( - "Success", - "Digital Product Created Successfully" - ) - navigate("/a/product-media") - }, - }) - }, - }) - }, - }) + + + {data.product_medias.map((product_media) => ( + + + {product_media.variant.product.title} + + + {product_media.variant.title} + + + {product_media.file_key} + + + + View Product + + + + ))} + + + )} + + ) } - return ( - -
-
- - setProductName(e.target.value)} - /> -
-
- - - setProductVariantName(e.target.value) - } - /> -
-
- - setName(e.target.value)} - /> -
-
- - -
-
- - setFile(e.target.files[0])} - /> -
- -
-
- ) -} + export const config: RouteConfig = { + link: { + label: "Digital Products", + icon: DocumentText, + }, + } -export default ProductMediaCreateForm -``` + export default ProductMediaListPage + ``` -In this component, you create a form that accepts basic information needed to create the digital product. This form only accepts one file for one variant for simplicity purposes. You can expand on this based on your use case. + This UI route will show under the sidebar with the label “Digital Products”. In the page, you use the `useAdminCustomQuery` hook imported from `medusa-react` to send a request to your custom “list digital products” API Route. -Notice that an alternative approach would be to inject a widget to the Product Details page and allow users to upload the files from there. It depends on whether you’re only supporting Digital Products or you want the distinction between them, as done here. + In the page, you’ll show the list of digital products in a table, if there are any. You’ll also show a button that opens a drawer to the side of the page. -When the user submits the form, you first create a product with a variant. Then, you upload the file using the [Upload Protected File API Route](https://docs.medusajs.com/api/admin#uploads_postuploadsprotected). Finally, you create the digital product using the custom API Route you created. + In the drawer, you show the Create Digital Product form. To create this form, create the file `src/admin/components/product-media/CreateForm/index.tsx` with the following content: -The product’s details can still be edited from the same Products interface, similar to regular products. You can edit its price, add more variants, and more. + ```tsx title=src/admin/components/product-media/CreateForm/index.tsx + import { useState } from "react" + import { MediaType } from "../../../../models/product-media" + import { + useAdminCreateProduct, + useAdminCustomPost, + useAdminUploadProtectedFile, + } from "medusa-react" + import { + CreateProductMediaRequest, + CreateProductMediaResponse, + } from "../../../../types/product-media" + import { + Button, + Container, + Input, + Label, + Select, + } from "@medusajs/ui" + import { RouteProps } from "@medusajs/admin-ui" + import { useNavigate } from "react-router-dom" -To test it out, build changes and run the `develop` command: + const ProductMediaCreateForm = ({ + notify, + }: RouteProps) => { + const [productName, setProductName] = useState("") + const [ + productVariantName, + setProductVariantName, + ] = useState("") + const [name, setName] = useState("") + const [type, setType] = useState("main") + const [file, setFile] = useState() -```bash npm2yarn -npm run build -npx medusa develop -``` + const createProduct = useAdminCreateProduct() + const uploadFile = useAdminUploadProtectedFile() + const { + mutate: createDigitalProduct, + isLoading, + } = useAdminCustomPost< + CreateProductMediaRequest, + CreateProductMediaResponse + >( + "/product-media", + ["product-media"] + ) -If you open the admin now, you’ll find a new Digital Products item in the sidebar. You can try adding Digital Products and viewing them. + const navigate = useNavigate() -
+ const handleSubmit = ( + e: React.FormEvent + ) => { + e.preventDefault() + + createProduct.mutate({ + title: productName, + is_giftcard: false, + discountable: false, + options: [ + { + title: "Digital Product", + }, + ], + variants: [ + { + title: productVariantName, + options: [ + { + value: name, // can also be the file name + }, + ], + // for simplicity, prices are omitted from form. + // Those can be edited from the product's page. + prices: [], + }, + ], + }, { + onSuccess: ({ product }) => { + // upload file + uploadFile.mutate(file, { + onSuccess: ({ uploads }) => { + if (!("key" in uploads[0])) { + return + } + // create the digital product + createDigitalProduct({ + variant_id: product.variants[0].id, + name, + file_key: uploads[0].key as string, + type: type as MediaType, + mime_type: file.type, + }, { + onSuccess: () => { + notify.success( + "Success", + "Digital Product Created Successfully" + ) + navigate("/a/product-media") + }, + }) + }, + }) + }, + }) + } + + return ( + +
+
+ + setProductName(e.target.value)} + /> +
+
+ + + setProductVariantName(e.target.value) + } + /> +
+
+ + setName(e.target.value)} + /> +
+
+ + +
+
+ + setFile(e.target.files[0])} + /> +
+ +
+
+ ) + } + + export default ProductMediaCreateForm + ``` + + In this component, you create a form that accepts basic information needed to create the digital product. This form only accepts one file for one variant for simplicity purposes. You can expand on this based on your use case. + + Notice that an alternative approach would be to inject a widget to the Product Details page and allow users to upload the files from there. It depends on whether you’re only supporting Digital Products or you want the distinction between them, as done here. + + When the user submits the form, you first create a product with a variant. Then, you upload the file using the [Upload Protected File API Route](https://docs.medusajs.com/api/admin#uploads_postuploadsprotected). Finally, you create the digital product using the custom API Route you created. + + The product’s details can still be edited from the same Products interface, similar to regular products. You can edit its price, add more variants, and more. + + To test it out, build changes and run the `develop` command: + + ```bash npm2yarn + npm run build + npx medusa develop + ``` + + If you open the admin now, you’ll find a new Digital Products item in the sidebar. You can try adding Digital Products and viewing them. + +
--- @@ -947,110 +941,108 @@ Finally, you can send a notification, such as an email, to the customer using th } }} /> -
- -Example: Using SendGrid - +
+ Example: Using SendGrid -:::note + :::note -An alternative solution is to create a store download API Route that allows authenticated customers to download products they've purchased, then add the link to the API Route or a storefront page that calls the API Route in the email. Learn how to implement the download API Route [here](#download-product-after-purchase). + An alternative solution is to create a store download API Route that allows authenticated customers to download products they've purchased, then add the link to the API Route or a storefront page that calls the API Route in the email. Learn how to implement the download API Route [here](#download-product-after-purchase). -::: + ::: -Here’s an example of a subscriber that retrieves the download links and sends them to the customer using the SendGrid plugin: - -```ts title=src/subscribers/handle-order.ts -import { - AbstractFileService, - EventBusService, - OrderService, -} from "@medusajs/medusa" + Here’s an example of a subscriber that retrieves the download links and sends them to the customer using the SendGrid plugin: + + ```ts title=src/subscribers/handle-order.ts + import { + AbstractFileService, + EventBusService, + OrderService, + } from "@medusajs/medusa" -type InjectedDependencies = { - eventBusService: EventBusService - orderService: OrderService - sendgridService: any - fileService: AbstractFileService -} - -class HandleOrderSubscribers { - protected readonly orderService_: OrderService - protected readonly sendgridService_: any - protected readonly fileService_: AbstractFileService - - constructor({ - eventBusService, - orderService, - sendgridService, - fileService, - }: InjectedDependencies) { - this.orderService_ = orderService - this.sendgridService_ = sendgridService - this.fileService_ = fileService - eventBusService.subscribe( - "order.placed", - this.handleOrderPlaced - ) + type InjectedDependencies = { + eventBusService: EventBusService + orderService: OrderService + sendgridService: any + fileService: AbstractFileService } - handleOrderPlaced = async ( - data: Record - ) => { - const order = await this.orderService_.retrieve(data.id, { - relations: [ - "items", - "items.variant", - "items.variant.product_medias", - ], - }) + class HandleOrderSubscribers { + protected readonly orderService_: OrderService + protected readonly sendgridService_: any + protected readonly fileService_: AbstractFileService - // find product medias in the order - const urls = [] - for (const item of order.items) { - if (!item.variant.product_medias.length) { + constructor({ + eventBusService, + orderService, + sendgridService, + fileService, + }: InjectedDependencies) { + this.orderService_ = orderService + this.sendgridService_ = sendgridService + this.fileService_ = fileService + eventBusService.subscribe( + "order.placed", + this.handleOrderPlaced + ) + } + + handleOrderPlaced = async ( + data: Record + ) => { + const order = await this.orderService_.retrieve(data.id, { + relations: [ + "items", + "items.variant", + "items.variant.product_medias", + ], + }) + + // find product medias in the order + const urls = [] + for (const item of order.items) { + if (!item.variant.product_medias.length) { + return + } + + await Promise.all([ + item.variant.product_medias.forEach( + async (productMedia) => { + // get the download URL from the file service + const downloadUrl = await + this.fileService_.getPresignedDownloadUrl({ + fileKey: productMedia.file_key, + isPrivate: true, + }) + + urls.push(downloadUrl) + }), + ]) + } + + if (!urls.length) { return } - await Promise.all([ - item.variant.product_medias.forEach( - async (productMedia) => { - // get the download URL from the file service - const downloadUrl = await - this.fileService_.getPresignedDownloadUrl({ - fileKey: productMedia.file_key, - isPrivate: true, - }) - - urls.push(downloadUrl) - }), - ]) + this.sendgridService_.sendEmail({ + templateId: "digital-download", + from: "hello@medusajs.com", + to: order.email, + dynamic_template_data: { + // any data necessary for your template... + digital_download_urls: urls, + }, + }) } - - if (!urls.length) { - return - } - - this.sendgridService_.sendEmail({ - templateId: "digital-download", - from: "hello@medusajs.com", - to: order.email, - dynamic_template_data: { - // any data necessary for your template... - digital_download_urls: urls, - }, - }) } -} -export default HandleOrderSubscribers -``` + export default HandleOrderSubscribers + ``` -Notice that regardless of what file service you have installed, you can access it using dependency injection under the name `fileService`. + Notice that regardless of what file service you have installed, you can access it using dependency injection under the name `fileService`. -The `handleOrderPlaced` method retrieves the order, loops over its items to find digital products and retrieve their download links, then uses SendGrid to send the email, passing it the urls as a data payload. You can customize the sent data based on your SendGrid template and your use case. + The `handleOrderPlaced` method retrieves the order, loops over its items to find digital products and retrieve their download links, then uses SendGrid to send the email, passing it the urls as a data payload. You can customize the sent data based on your SendGrid template and your use case. -
+
--- @@ -1070,251 +1062,247 @@ In the product detail's page, you can add a button that allows customers to down To implement this, create a storefront API Route that allows you to fetch the digital product, then customize the Next.js storefront to show the preview button if a product is digital. -
- -Example - +
+ Example -Before you customize the Next.js storefront, you need to add a store API Route in your backend. + Before you customize the Next.js storefront, you need to add a store API Route in your backend. -Create the file `src/api/store/product-media/route.ts` with the following content: + Create the file `src/api/store/product-media/route.ts` with the following content: -```ts title=src/api/store/product-media/route.ts -import type { - MedusaRequest, - MedusaResponse, -} from "@medusajs/medusa" -import ProductMediaService - from "../../../services/product-media" -import { MediaType } from "../../../models/product-media" + ```ts title=src/api/store/product-media/route.ts + import type { + MedusaRequest, + MedusaResponse, + } from "@medusajs/medusa" + import ProductMediaService + from "../../../services/product-media" + import { MediaType } from "../../../models/product-media" -export const GET = async ( - req: MedusaRequest, - res: MedusaResponse -) => { - const productMediaService = req.scope.resolve< - ProductMediaService - >("productMediaService") - // omitting pagination for simplicity - const [ - productMedias, - count, - ] = await productMediaService.listAndCount({ - type: MediaType.PREVIEW, - ...(req.query), - }, { - relations: ["variant"], - }) + export const GET = async ( + req: MedusaRequest, + res: MedusaResponse + ) => { + const productMediaService = req.scope.resolve< + ProductMediaService + >("productMediaService") + // omitting pagination for simplicity + const [ + productMedias, + count, + ] = await productMediaService.listAndCount({ + type: MediaType.PREVIEW, + ...(req.query), + }, { + relations: ["variant"], + }) - res.json({ - product_medias: productMedias, - count, - }) -} -``` + res.json({ + product_medias: productMedias, + count, + }) + } + ``` -This adds a store API Route that returns a list of product medias of type `preview`. It also allows you to pass query parameters to filter the returned products medias. + This adds a store API Route that returns a list of product medias of type `preview`. It also allows you to pass query parameters to filter the returned products medias. -Now, you can customize the Next.js storefront to show the preview button. + Now, you can customize the Next.js storefront to show the preview button. -First, if you're using TypeScript for your development, create the file `src/types/product-media.ts` with the following content: + First, if you're using TypeScript for your development, create the file `src/types/product-media.ts` with the following content: -```ts title=src/types/product-media.ts + ```ts title=src/types/product-media.ts -import { Product } from "@medusajs/medusa" -import { ProductVariant } from "@medusajs/product" + import { Product } from "@medusajs/medusa" + import { ProductVariant } from "@medusajs/product" -export enum ProductMediaVariantType { - PREVIEW = "preview", - MAIN = "main", -} + export enum ProductMediaVariantType { + PREVIEW = "preview", + MAIN = "main", + } -export type ProductMedia = { - id: string - variant_id: string - name?: string - file_key?: string - mime_type?: string - created_at?: Date - updated_at?: Date - type?: ProductMediaVariantType - variant_id?: string - variants?: ProductVariant[] - created_at: Date - updated_at: Date -} + export type ProductMedia = { + id: string + variant_id: string + name?: string + file_key?: string + mime_type?: string + created_at?: Date + updated_at?: Date + type?: ProductMediaVariantType + variant_id?: string + variants?: ProductVariant[] + created_at: Date + updated_at: Date + } -export type DigitalProduct = Omit & { - product_medias?: ProductMedia[] - variants?: DigitalProductVariant[] -} + export type DigitalProduct = Omit & { + product_medias?: ProductMedia[] + variants?: DigitalProductVariant[] + } -export type DigitalProductVariant = ProductVariant & { - product_medias?: ProductMedia -} -``` + export type DigitalProductVariant = ProductVariant & { + product_medias?: ProductMedia + } + ``` -Then, add in `src/lib/data/index.ts` a new function that retrieves the product media of the product variant being viewed: + Then, add in `src/lib/data/index.ts` a new function that retrieves the product media of the product variant being viewed: -```ts title=src/lib/data/index.ts -import { - DigitalProduct, - ProductMedia, -} from "types/product-media" + ```ts title=src/lib/data/index.ts + import { + DigitalProduct, + ProductMedia, + } from "types/product-media" -// ... rest of the functions + // ... rest of the functions -export async function getProductMediaPreviewByVariant( - variant: Variant -): Promise { - const { - product_medias, - } = await medusaRequest( - "GET", - `/product-media`, - { - query: { - variant_ids: variant.id, - }, + export async function getProductMediaPreviewByVariant( + variant: Variant + ): Promise { + const { + product_medias, + } = await medusaRequest( + "GET", + `/product-media`, + { + query: { + variant_ids: variant.id, + }, + } + ) + .then((res) => res.body) + .catch((err) => { + throw err + }) + + return product_medias[0] + } + ``` + + To allow customers to download the file preview without exposing its URL, create a Next.js API route in the file `src/app/api/download/preview/route.ts` with the following content: + + ```ts title=src/app/api/download/preview/route.ts + import { NextRequest, NextResponse } from "next/server" + + export async function GET(req: NextRequest) { + // Get the file info from the URL + const { + file_path, + file_name, + mime_type, + } = Object.fromEntries(req.nextUrl.searchParams) + + // Fetch the file + const response = await fetch(file_path) + + // Handle the case where the file could not be fetched + if (!response.ok) { + return new NextResponse("File not found", { status: 404 }) } - ) - .then((res) => res.body) - .catch((err) => { - throw err - }) - return product_medias[0] -} -``` + // Get the file content as a buffer + const fileBuffer = await response.arrayBuffer() -To allow customers to download the file preview without exposing its URL, create a Next.js API route in the file `src/app/api/download/preview/route.ts` with the following content: - -```ts title=src/app/api/download/preview/route.ts -import { NextRequest, NextResponse } from "next/server" - -export async function GET(req: NextRequest) { - // Get the file info from the URL - const { - file_path, - file_name, - mime_type, - } = Object.fromEntries(req.nextUrl.searchParams) - - // Fetch the file - const response = await fetch(file_path) - - // Handle the case where the file could not be fetched - if (!response.ok) { - return new NextResponse("File not found", { status: 404 }) - } - - // Get the file content as a buffer - const fileBuffer = await response.arrayBuffer() - - // Define response headers - const headers = { - "Content-Type": mime_type, - // This sets the file name for the download - "Content-Disposition": `attachment; filename="${ - file_name - }"`, - } - - // Create a NextResponse with the file content and headers - const response = new NextResponse(fileBuffer, { - status: 200, - headers, - }) - - return response -} -``` - -Next, create the preview button in the file `src/modules/products/components/product-media-preview/index.tsx`: - -```tsx title=src/modules/products/components/product-media-preview/index.tsx -import Button from "@modules/common/components/button" -import { ProductMedia } from "types/product-media" - -type Props = { - media: ProductMedia -} - -const ProductMediaPreview: React.FC = ({ media }) => { - const downloadPreview = () => { - window.location.href = `${ - process.env.NEXT_PUBLIC_BASE_URL - }/api/download/preview?file_path=${ - media.file_key - }&file_name=${ - media.name - }&mime_type=${ - media.mime_type - }` - } - - return ( -
- -
- ) -} - -export default ProductMediaPreview -``` - -Finally, add the button as one of the product actions defined in `src/modules/products/components/product-actions/index.tsx`. These are the actions shown to the customer in the product details page: - -```tsx title=src/modules/products/components/product-actions/index.tsx -// other imports... -import ProductMediaPreview from "../product-media-preview" -import { getProductMediaPreviewByVariant } from "@lib/data" -import { ProductMedia } from "types/product-media" - - -const ProductActions: React.FC = ({ - product, -}) => { - // other code... - - const [productMedia, setProductMedia] = useState< - ProductMedia - >({}) - - useEffect(() => { - const getProductMedia = async () => { - if (!variant) {return} - await getProductMediaPreviewByVariant(variant) - .then((res) => { - setProductMedia(res) - }) + // Define response headers + const headers = { + "Content-Type": mime_type, + // This sets the file name for the download + "Content-Disposition": `attachment; filename="${ + file_name + }"`, } - getProductMedia() - }, [variant]) - return ( -
- {/* other code... */} + // Create a NextResponse with the file content and headers + const response = new NextResponse(fileBuffer, { + status: 200, + headers, + }) - {productMedia && ( - - )} + return response + } + ``` - -
- ) -} + Next, create the preview button in the file `src/modules/products/components/product-media-preview/index.tsx`: -export default ProductActions -``` + ```tsx title=src/modules/products/components/product-media-preview/index.tsx + import Button from "@modules/common/components/button" + import { ProductMedia } from "types/product-media" -The + type Props = { + media: ProductMedia + } -
+ const ProductMediaPreview: React.FC = ({ media }) => { + const downloadPreview = () => { + window.location.href = `${ + process.env.NEXT_PUBLIC_BASE_URL + }/api/download/preview?file_path=${ + media.file_key + }&file_name=${ + media.name + }&mime_type=${ + media.mime_type + }` + } + + return ( +
+ +
+ ) + } + + export default ProductMediaPreview + ``` + + Finally, add the button as one of the product actions defined in `src/modules/products/components/product-actions/index.tsx`. These are the actions shown to the customer in the product details page: + + ```tsx title=src/modules/products/components/product-actions/index.tsx + // other imports... + import ProductMediaPreview from "../product-media-preview" + import { getProductMediaPreviewByVariant } from "@lib/data" + import { ProductMedia } from "types/product-media" + + + const ProductActions: React.FC = ({ + product, + }) => { + // other code... + + const [productMedia, setProductMedia] = useState< + ProductMedia + >({}) + + useEffect(() => { + const getProductMedia = async () => { + if (!variant) {return} + await getProductMediaPreviewByVariant(variant) + .then((res) => { + setProductMedia(res) + }) + } + getProductMedia() + }, [variant]) + + return ( +
+ {/* other code... */} + + {productMedia && ( + + )} + + +
+ ) + } + + export default ProductActions + ``` + +
### Update Product Tabs @@ -1322,960 +1310,954 @@ In the product details page, additional information related to the product and i You can change this section to show information relevant to the product. For example, how many pages are in an e-book, or how the e-book will be delivered to the customer. -
- -Example - +
+ Example -In this example, you'll change the content of the Product Information and Shipping & Returns tabs to show information relevant to the digital product. The Product Information tab will include custom information relevant to digital products, and the Shipping & Returns tab will be changed to "E-book delivery" and will hold details about how the e-book will be delivered to the customer. + In this example, you'll change the content of the Product Information and Shipping & Returns tabs to show information relevant to the digital product. The Product Information tab will include custom information relevant to digital products, and the Shipping & Returns tab will be changed to "E-book delivery" and will hold details about how the e-book will be delivered to the customer. -One way to store custom information relevant to the digital product is using the `metadata` field. For example, to store the number of pages of an e-book, set the `metadata` field to the following: + One way to store custom information relevant to the digital product is using the `metadata` field. For example, to store the number of pages of an e-book, set the `metadata` field to the following: -```json -{ - "metadata": { - "Pages": "420" + ```json + { + "metadata": { + "Pages": "420" + } } -} -``` + ``` -Then, you can customize the product additional details section to loop through the `metadata` field's properties and show their information. + Then, you can customize the product additional details section to loop through the `metadata` field's properties and show their information. -Next, change the `ProductTabs`, `ProductInfoTab`, and `ShippingInfoTab` components defined in `src/modules/products/components/product-tabs/index.tsx` to the following: + Next, change the `ProductTabs`, `ProductInfoTab`, and `ShippingInfoTab` components defined in `src/modules/products/components/product-tabs/index.tsx` to the following: -```tsx title=src/modules/products/components/product-tabs/index.tsx -const ProductTabs = ({ product }: ProductTabsProps) => { - const tabs = useMemo(() => { - return [ - { - label: "Product Information", - component: , - }, - { - label: "E-book delivery", - component: , - }, - ] - }, [product]) - // ... rest of code -} + ```tsx title=src/modules/products/components/product-tabs/index.tsx + const ProductTabs = ({ product }: ProductTabsProps) => { + const tabs = useMemo(() => { + return [ + { + label: "Product Information", + component: , + }, + { + label: "E-book delivery", + component: , + }, + ] + }, [product]) + // ... rest of code + } -const ProductInfoTab = ({ product }: ProductTabsProps) => { - // map the metadata object to an array - const metadata = useMemo(() => { - if (!product.metadata) {return []} - return Object.keys(product.metadata).map((key) => { - return [key, product.metadata?.[key]] - }) - }, [product]) + const ProductInfoTab = ({ product }: ProductTabsProps) => { + // map the metadata object to an array + const metadata = useMemo(() => { + if (!product.metadata) {return []} + return Object.keys(product.metadata).map((key) => { + return [key, product.metadata?.[key]] + }) + }, [product]) - return ( - -
-
- {/* Map the metadata as product information */} - {metadata && - metadata.slice(0, 2).map(([key, value], i) => ( -
- {key} -

{value}

-
- ))} -
-
- {metadata.length > 2 && - metadata.slice(2, 4).map(([key, value], i) => { - return ( + return ( + +
+
+ {/* Map the metadata as product information */} + {metadata && + metadata.slice(0, 2).map(([key, value], i) => (
{key}

{value}

- ) - })} -
-
- {product.tags?.length ? ( -
- Tags -
- ) : null} -
- ) -} - -const ShippingInfoTab = () => { - return ( - -
-
- -
- - Instant delivery - -

- Your e-book will be delivered instantly via - email. You can also download it from your - account anytime. -

+ ))} +
+
+ {metadata.length > 2 && + metadata.slice(2, 4).map(([key, value], i) => { + return ( +
+ {key} +

{value}

+
+ ) + })}
-
- + {product.tags?.length ? (
- - Free previews - -

- Get a free preview of the e-book before - you buy it. Just click the - button above to download it. -

+ Tags +
+ ) : null} + + ) + } + + const ShippingInfoTab = () => { + return ( + +
+
+ +
+ + Instant delivery + +

+ Your e-book will be delivered instantly via + email. You can also download it from your + account anytime. +

+
+
+
+ +
+ + Free previews + +

+ Get a free preview of the e-book before + you buy it. Just click the + button above to download it. +

+
-
- - ) -} -``` + + ) + } + ``` -This changes the titles of the tabs and their content. + This changes the titles of the tabs and their content. -
+
### Change Shipping Form in Checkout When a customer purchases a digital product, the shipping form shown during checkout is not relevant. So, you can change its content to instead only ask for the customer's name and email. -
- -Example - +
+ Example -The checkout flow is managed by a checkout context defined in `src/lib/context/checkout-context.tsx`. Change the content of the file to the following: + The checkout flow is managed by a checkout context defined in `src/lib/context/checkout-context.tsx`. Change the content of the file to the following: -```tsx title=src/lib/context/checkout-context.tsx -"use client" + ```tsx title=src/lib/context/checkout-context.tsx + "use client" -import { medusaClient } from "@lib/config" -import useToggleState, { - StateType, -} from "@lib/hooks/use-toggle-state" -import { - Cart, - Customer, - StorePostCartsCartReq, -} from "@medusajs/medusa" -import Wrapper - from "@modules/checkout/components/payment-wrapper" -import { isEqual } from "lodash" -import { - formatAmount, - useCart, - useCartShippingOptions, - useMeCustomer, - useRegions, - useSetPaymentSession, - useUpdateCart, -} from "medusa-react" -import { useRouter } from "next/navigation" -import React, { - createContext, - useContext, - useEffect, - useMemo, -} from "react" -import { - FormProvider, - useForm, - useFormContext, -} from "react-hook-form" -import { useStore } from "./store-context" + import { medusaClient } from "@lib/config" + import useToggleState, { + StateType, + } from "@lib/hooks/use-toggle-state" + import { + Cart, + Customer, + StorePostCartsCartReq, + } from "@medusajs/medusa" + import Wrapper + from "@modules/checkout/components/payment-wrapper" + import { isEqual } from "lodash" + import { + formatAmount, + useCart, + useCartShippingOptions, + useMeCustomer, + useRegions, + useSetPaymentSession, + useUpdateCart, + } from "medusa-react" + import { useRouter } from "next/navigation" + import React, { + createContext, + useContext, + useEffect, + useMemo, + } from "react" + import { + FormProvider, + useForm, + useFormContext, + } from "react-hook-form" + import { useStore } from "./store-context" -type AddressValues = { - first_name: string - last_name: string - country_code: string -} + type AddressValues = { + first_name: string + last_name: string + country_code: string + } -export type CheckoutFormValues = { - shipping_address: AddressValues - billing_address?: AddressValues - email: string -} + export type CheckoutFormValues = { + shipping_address: AddressValues + billing_address?: AddressValues + email: string + } -interface CheckoutContext { - cart?: Omit - shippingMethods: { - label?: string; - value?: string; - price: string - }[] - isLoading: boolean - readyToComplete: boolean - sameAsBilling: StateType - editAddresses: StateType - initPayment: () => Promise - setAddresses: (addresses: CheckoutFormValues) => void - setSavedAddress: (address: AddressValues) => void - setShippingOption: (soId: string) => void - setPaymentSession: (providerId: string) => void - onPaymentCompleted: () => void -} + interface CheckoutContext { + cart?: Omit + shippingMethods: { + label?: string; + value?: string; + price: string + }[] + isLoading: boolean + readyToComplete: boolean + sameAsBilling: StateType + editAddresses: StateType + initPayment: () => Promise + setAddresses: (addresses: CheckoutFormValues) => void + setSavedAddress: (address: AddressValues) => void + setShippingOption: (soId: string) => void + setPaymentSession: (providerId: string) => void + onPaymentCompleted: () => void + } -const CheckoutContext = createContext< - CheckoutContext | null ->(null) + const CheckoutContext = createContext< + CheckoutContext | null + >(null) -interface CheckoutProviderProps { - children?: React.ReactNode -} + interface CheckoutProviderProps { + children?: React.ReactNode + } -const IDEMPOTENCY_KEY = "create_payment_session_key" + const IDEMPOTENCY_KEY = "create_payment_session_key" -export const CheckoutProvider = ({ - children, -}: CheckoutProviderProps) => { - const { - cart, - setCart, - addShippingMethod: { - mutate: setShippingMethod, - isLoading: addingShippingMethod, - }, - completeCheckout: { - mutate: complete, - isLoading: completingCheckout, - }, - } = useCart() + export const CheckoutProvider = ({ + children, + }: CheckoutProviderProps) => { + const { + cart, + setCart, + addShippingMethod: { + mutate: setShippingMethod, + isLoading: addingShippingMethod, + }, + completeCheckout: { + mutate: complete, + isLoading: completingCheckout, + }, + } = useCart() - const { customer } = useMeCustomer() - const { countryCode } = useStore() + const { customer } = useMeCustomer() + const { countryCode } = useStore() - const methods = useForm({ - defaultValues: mapFormValues(customer, cart, countryCode), - reValidateMode: "onChange", - }) + const methods = useForm({ + defaultValues: mapFormValues(customer, cart, countryCode), + reValidateMode: "onChange", + }) - const { - mutate: setPaymentSessionMutation, - isLoading: settingPaymentSession, - } = useSetPaymentSession(cart?.id!) + const { + mutate: setPaymentSessionMutation, + isLoading: settingPaymentSession, + } = useSetPaymentSession(cart?.id!) - const { - mutate: updateCart, - isLoading: updatingCart, - } = useUpdateCart( - cart?.id! - ) - - const { - shipping_options, - } = useCartShippingOptions(cart?.id!, { - enabled: !!cart?.id, - }) - - const { regions } = useRegions() - - const { resetCart, setRegion } = useStore() - const { push } = useRouter() - - const editAddresses = useToggleState() - const sameAsBilling = useToggleState( - cart?.billing_address && cart?.shipping_address - ? isEqual(cart.billing_address, cart.shipping_address) - : true - ) - - /** - * Boolean that indicates if a - * part of the checkout is loading. - */ - const isLoading = useMemo(() => { - return ( - addingShippingMethod || - settingPaymentSession || - updatingCart || - completingCheckout + const { + mutate: updateCart, + isLoading: updatingCart, + } = useUpdateCart( + cart?.id! ) - }, [ - addingShippingMethod, - completingCheckout, - settingPaymentSession, - updatingCart, - ]) - /** - * Boolean that indicates if the checkout is ready to be - * completed. A checkout is ready to be completed if - * the user has supplied a email, shipping address, - * billing address, shipping method, and a method of payment. - */ - const readyToComplete = useMemo(() => { - return ( - !!cart && - !!cart.email && - !!cart.shipping_address && - !!cart.billing_address && - !!cart.payment_session && - cart.shipping_methods?.length > 0 + const { + shipping_options, + } = useCartShippingOptions(cart?.id!, { + enabled: !!cart?.id, + }) + + const { regions } = useRegions() + + const { resetCart, setRegion } = useStore() + const { push } = useRouter() + + const editAddresses = useToggleState() + const sameAsBilling = useToggleState( + cart?.billing_address && cart?.shipping_address + ? isEqual(cart.billing_address, cart.shipping_address) + : true ) - }, [cart]) - const shippingMethods = useMemo(() => { - if (shipping_options && cart?.region) { - return shipping_options?.map((option) => ({ - value: option.id, - label: option.name, - price: formatAmount({ - amount: option.amount || 0, - region: cart.region, - }), - })) - } - - return [] - }, [shipping_options, cart]) - - /** - * Resets the form when the cart changed. - */ - useEffect(() => { - if (cart?.id) { - methods.reset(mapFormValues(customer, cart, countryCode)) - } - }, [customer, cart, methods, countryCode]) - - useEffect(() => { - if (!cart) { - editAddresses.open() - return - } - - if (cart?.shipping_address && cart?.billing_address) { - editAddresses.close() - return - } - - editAddresses.open() - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [cart]) - - /** - * Method to set the selected shipping method for the cart. - * This is called when the user selects a shipping method, - * such as UPS, FedEx, etc. - */ - const setShippingOption = (soId: string) => { - if (cart) { - setShippingMethod( - { option_id: soId }, - { - onSuccess: ({ cart }) => setCart(cart), - } + /** + * Boolean that indicates if a + * part of the checkout is loading. + */ + const isLoading = useMemo(() => { + return ( + addingShippingMethod || + settingPaymentSession || + updatingCart || + completingCheckout ) - } - } + }, [ + addingShippingMethod, + completingCheckout, + settingPaymentSession, + updatingCart, + ]) - /** - * Method to create the payment sessions available for the - * cart. Uses a idempotency key to prevent - * duplicate requests. - */ - const createPaymentSession = async (cartId: string) => { - return medusaClient.carts - .createPaymentSessions(cartId, { - "Idempotency-Key": IDEMPOTENCY_KEY, - }) - .then(({ cart }) => cart) - .catch(() => null) - } + /** + * Boolean that indicates if the checkout is ready to be + * completed. A checkout is ready to be completed if + * the user has supplied a email, shipping address, + * billing address, shipping method, and a method of payment. + */ + const readyToComplete = useMemo(() => { + return ( + !!cart && + !!cart.email && + !!cart.shipping_address && + !!cart.billing_address && + !!cart.payment_session && + cart.shipping_methods?.length > 0 + ) + }, [cart]) - /** - * Method that calls the createPaymentSession method and - * updates the cart with the payment session. - */ - const initPayment = async () => { - if (cart?.id && !cart.payment_sessions?.length && cart?.items?.length) { - const paymentSession = await createPaymentSession(cart.id) + const shippingMethods = useMemo(() => { + if (shipping_options && cart?.region) { + return shipping_options?.map((option) => ({ + value: option.id, + label: option.name, + price: formatAmount({ + amount: option.amount || 0, + region: cart.region, + }), + })) + } - if (!paymentSession) { - setTimeout(initPayment, 500) - } else { - setCart(paymentSession) + return [] + }, [shipping_options, cart]) + + /** + * Resets the form when the cart changed. + */ + useEffect(() => { + if (cart?.id) { + methods.reset(mapFormValues(customer, cart, countryCode)) + } + }, [customer, cart, methods, countryCode]) + + useEffect(() => { + if (!cart) { + editAddresses.open() return } - } - } - /** - * Method to set the selected payment session for the cart. - * This is called when the user selects a payment provider, - * such as Stripe, PayPal, etc. - */ - const setPaymentSession = (providerId: string) => { - if (cart) { - setPaymentSessionMutation( - { - provider_id: providerId, - }, - { - onSuccess: ({ cart }) => { - setCart(cart) - }, - } - ) - } - } + if (cart?.shipping_address && cart?.billing_address) { + editAddresses.close() + return + } - const prepareFinalSteps = () => { - initPayment() + editAddresses.open() + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [cart]) - if ( - shippingMethods?.length && shippingMethods?.[0]?.value - ) { - setShippingOption(shippingMethods[0].value) - } - } - - const setSavedAddress = (address: AddressValues) => { - const setValue = methods.setValue - - setValue("shipping_address", { - country_code: address.country_code || "", - first_name: address.first_name || "", - last_name: address.last_name || "", - }) - } - - /** - * Method that validates if the cart's region matches the - * shipping address's region. If not, it will update the - * cart region. - */ - const validateRegion = (countryCode: string) => { - if (regions && cart) { - const region = regions.find((r) => - r.countries.map((c) => c.iso_2).includes(countryCode) - ) - - if (region && region.id !== cart.region.id) { - setRegion(region.id, countryCode) + /** + * Method to set the selected shipping method for the cart. + * This is called when the user selects a shipping method, + * such as UPS, FedEx, etc. + */ + const setShippingOption = (soId: string) => { + if (cart) { + setShippingMethod( + { option_id: soId }, + { + onSuccess: ({ cart }) => setCart(cart), + } + ) } } - } - /** - * Method that sets the addresses and email on the cart. - */ - const setAddresses = (data: CheckoutFormValues) => { - const { shipping_address, billing_address, email } = data - - const payload: StorePostCartsCartReq = { - shipping_address, - email, + /** + * Method to create the payment sessions available for the + * cart. Uses a idempotency key to prevent + * duplicate requests. + */ + const createPaymentSession = async (cartId: string) => { + return medusaClient.carts + .createPaymentSessions(cartId, { + "Idempotency-Key": IDEMPOTENCY_KEY, + }) + .then(({ cart }) => cart) + .catch(() => null) } - if (isEqual(shipping_address, billing_address)) { - sameAsBilling.open() + /** + * Method that calls the createPaymentSession method and + * updates the cart with the payment session. + */ + const initPayment = async () => { + if (cart?.id && !cart.payment_sessions?.length && cart?.items?.length) { + const paymentSession = await createPaymentSession(cart.id) + + if (!paymentSession) { + setTimeout(initPayment, 500) + } else { + setCart(paymentSession) + return + } + } } - if (sameAsBilling.state) { - payload.billing_address = shipping_address - } else { - payload.billing_address = billing_address + /** + * Method to set the selected payment session for the cart. + * This is called when the user selects a payment provider, + * such as Stripe, PayPal, etc. + */ + const setPaymentSession = (providerId: string) => { + if (cart) { + setPaymentSessionMutation( + { + provider_id: providerId, + }, + { + onSuccess: ({ cart }) => { + setCart(cart) + }, + } + ) + } } - updateCart(payload, { - onSuccess: ({ cart }) => { - setCart(cart) - prepareFinalSteps() - }, - }) - } + const prepareFinalSteps = () => { + initPayment() - /** - * Method to complete the checkout process. This is called - * when the user clicks the "Complete Checkout" button. - */ - const onPaymentCompleted = () => { - complete(undefined, { - onSuccess: ({ data }) => { - resetCart() - push(`/order/confirmed/${data.id}`) - }, - }) - } + if ( + shippingMethods?.length && shippingMethods?.[0]?.value + ) { + setShippingOption(shippingMethods[0].value) + } + } - return ( - - - { + const setValue = methods.setValue + + setValue("shipping_address", { + country_code: address.country_code || "", + first_name: address.first_name || "", + last_name: address.last_name || "", + }) + } + + /** + * Method that validates if the cart's region matches the + * shipping address's region. If not, it will update the + * cart region. + */ + const validateRegion = (countryCode: string) => { + if (regions && cart) { + const region = regions.find((r) => + r.countries.map((c) => c.iso_2).includes(countryCode) + ) + + if (region && region.id !== cart.region.id) { + setRegion(region.id, countryCode) + } + } + } + + /** + * Method that sets the addresses and email on the cart. + */ + const setAddresses = (data: CheckoutFormValues) => { + const { shipping_address, billing_address, email } = data + + const payload: StorePostCartsCartReq = { + shipping_address, + email, + } + + if (isEqual(shipping_address, billing_address)) { + sameAsBilling.open() + } + + if (sameAsBilling.state) { + payload.billing_address = shipping_address + } else { + payload.billing_address = billing_address + } + + updateCart(payload, { + onSuccess: ({ cart }) => { + setCart(cart) + prepareFinalSteps() + }, + }) + } + + /** + * Method to complete the checkout process. This is called + * when the user clicks the "Complete Checkout" button. + */ + const onPaymentCompleted = () => { + complete(undefined, { + onSuccess: ({ data }) => { + resetCart() + push(`/order/confirmed/${data.id}`) + }, + }) + } + + return ( + + - {children} - - - - ) -} - -export const useCheckout = () => { - const context = useContext(CheckoutContext) - const form = useFormContext() - if (context === null) { - throw new Error( - "useProductActionContext must be used within a ProductActionProvider" + + {children} + + + ) } - return { ...context, ...form } -} -/** - * Method to map the fields of a potential customer and - * the cart to the checkout form values. Information is - * assigned with the following priority: - * 1. Cart information - * 2. Customer information - * 3. Default values - null - */ -const mapFormValues = ( - customer?: Omit, - cart?: Omit, - currentCountry?: string -): CheckoutFormValues => { - const customerShippingAddress = - customer?.shipping_addresses?.[0] - const customerBillingAddress = - customer?.billing_address - - return { - shipping_address: { - first_name: - cart?.shipping_address?.first_name || - customerShippingAddress?.first_name || - "", - last_name: - cart?.shipping_address?.last_name || - customerShippingAddress?.last_name || - "", - country_code: - currentCountry || - cart?.shipping_address?.country_code || - customerShippingAddress?.country_code || - "", - }, - billing_address: { - first_name: - cart?.billing_address?.first_name || - customerBillingAddress?.first_name || - "", - last_name: - cart?.billing_address?.last_name || - customerBillingAddress?.last_name || - "", - country_code: - cart?.shipping_address?.country_code || - customerBillingAddress?.country_code || - "", - }, - email: cart?.email || customer?.email || "", + export const useCheckout = () => { + const context = useContext(CheckoutContext) + const form = useFormContext() + if (context === null) { + throw new Error( + "useProductActionContext must be used within a ProductActionProvider" + ) + } + return { ...context, ...form } } -} -``` -This removes all references to shipping fields that you don't need for digital products. + /** + * Method to map the fields of a potential customer and + * the cart to the checkout form values. Information is + * assigned with the following priority: + * 1. Cart information + * 2. Customer information + * 3. Default values - null + */ + const mapFormValues = ( + customer?: Omit, + cart?: Omit, + currentCountry?: string + ): CheckoutFormValues => { + const customerShippingAddress = + customer?.shipping_addresses?.[0] + const customerBillingAddress = + customer?.billing_address -Next, update the content of `src/modules/checkout/components/addresses/index.tsx` to remove the unnecessary address fields: + return { + shipping_address: { + first_name: + cart?.shipping_address?.first_name || + customerShippingAddress?.first_name || + "", + last_name: + cart?.shipping_address?.last_name || + customerShippingAddress?.last_name || + "", + country_code: + currentCountry || + cart?.shipping_address?.country_code || + customerShippingAddress?.country_code || + "", + }, + billing_address: { + first_name: + cart?.billing_address?.first_name || + customerBillingAddress?.first_name || + "", + last_name: + cart?.billing_address?.last_name || + customerBillingAddress?.last_name || + "", + country_code: + cart?.shipping_address?.country_code || + customerBillingAddress?.country_code || + "", + }, + email: cart?.email || customer?.email || "", + } + } + ``` + + This removes all references to shipping fields that you don't need for digital products. + + Next, update the content of `src/modules/checkout/components/addresses/index.tsx` to remove the unnecessary address fields: -```tsx title=src/modules/checkout/components/addresses/index.tsx -import { useCheckout } from "@lib/context/checkout-context" -import Button from "@modules/common/components/button" -import Spinner from "@modules/common/icons/spinner" -import ShippingAddress from "../shipping-address" + ```tsx title=src/modules/checkout/components/addresses/index.tsx + import { useCheckout } from "@lib/context/checkout-context" + import Button from "@modules/common/components/button" + import Spinner from "@modules/common/icons/spinner" + import ShippingAddress from "../shipping-address" -const Addresses = () => { - const { - editAddresses: { state: isEdit, toggle: setEdit }, - setAddresses, - handleSubmit, - cart, - } = useCheckout() - return ( -
-
-
- 1 + const Addresses = () => { + const { + editAddresses: { state: isEdit, toggle: setEdit }, + setAddresses, + handleSubmit, + cart, + } = useCheckout() + return ( +
+
+
+ 1 +
+

Shipping address

-

Shipping address

-
- {isEdit ? ( -
- - -
- ) : ( -
-
- {cart && cart.shipping_address ? ( -
-
- ✓ -
-
-
- - {cart.shipping_address.first_name}{" "} - {cart.shipping_address.last_name} - {cart.shipping_address.country} - -
- {cart.email} + {isEdit ? ( +
+ + +
+ ) : ( +
+
+ {cart && cart.shipping_address ? ( +
+
+ ✓ +
+
+
+ + {cart.shipping_address.first_name}{" "} + {cart.shipping_address.last_name} + {cart.shipping_address.country} + +
+ {cart.email} +
+
+
+
-
- -
-
- ) : ( -
- -
- )} + ) : ( +
+ +
+ )} +
+
+ )} +
+ ) + } + + export default Addresses + ``` + + Finally, change the shipping details shown in the order confirmation page by replacing the content of `src/modules/order/components/shipping-details/index.tsx` with the following: + + ```tsx title=src/modules/order/components/shipping-details/index.tsx + import { Address, ShippingMethod } from "@medusajs/medusa" + + type ShippingDetailsProps = { + address: Address + shippingMethods: ShippingMethod[] + email: string + } + + const ShippingDetails = ({ + address, + shippingMethods, + email, + }: ShippingDetailsProps) => { + return ( +
+

Delivery

+
+

+ Details +

+
+ + {`${address.first_name} ${address.last_name}`} + + {email}
- )} -
- ) -} - -export default Addresses -``` - -Finally, change the shipping details shown in the order confirmation page by replacing the content of `src/modules/order/components/shipping-details/index.tsx` with the following: - -```tsx title=src/modules/order/components/shipping-details/index.tsx -import { Address, ShippingMethod } from "@medusajs/medusa" - -type ShippingDetailsProps = { - address: Address - shippingMethods: ShippingMethod[] - email: string -} - -const ShippingDetails = ({ - address, - shippingMethods, - email, -}: ShippingDetailsProps) => { - return ( -
-

Delivery

-
-

- Details -

-
- - {`${address.first_name} ${address.last_name}`} - - {email} +
+

+ Delivery method +

+
+ {shippingMethods.map((sm) => { + return ( +
+ {sm.shipping_option.name} +
+ ) + })} +
-
-

- Delivery method -

-
- {shippingMethods.map((sm) => { - return ( -
- {sm.shipping_option.name} -
- ) - })} -
-
-
- ) -} + ) + } -export default ShippingDetails -``` + export default ShippingDetails + ``` -
+
### Download Product After Purchase After the customer purchases the digital product you can show a download button to allow them to immediately download the product. -
- -Example - +
+ Example -Before you implement the storefront changes, you need to create a new API Route in the backend that ensures that the currently logged-in customer has purchased the digital product and, if so, returns a presigned URL to download it. + Before you implement the storefront changes, you need to create a new API Route in the backend that ensures that the currently logged-in customer has purchased the digital product and, if so, returns a presigned URL to download it. -Create the file `src/api/store/product-media/download/[variant_id]/route.ts` with the following content: + Create the file `src/api/store/product-media/download/[variant_id]/route.ts` with the following content: -```ts title=src/api/store/product-media/download/route.ts -import type { - AbstractFileService, - MedusaRequest, - MedusaResponse, - OrderService, - ProductVariant, -} from "@medusajs/medusa" -import ProductMediaService - from "../../../../services/product-media" -import { MediaType } from "../../../../models/product-media" + ```ts title=src/api/store/product-media/download/route.ts + import type { + AbstractFileService, + MedusaRequest, + MedusaResponse, + OrderService, + ProductVariant, + } from "@medusajs/medusa" + import ProductMediaService + from "../../../../services/product-media" + import { MediaType } from "../../../../models/product-media" -export const GET = async ( - req: MedusaRequest, - res: MedusaResponse -) => { - const variantId = req.params.variant_id - if (!variantId) { - throw new Error("Variant ID is required") - } - const ordersService = req.scope.resolve< - OrderService - >("orderService") - const orders = await ordersService.list({ - customer_id: req.user.customer_id, - }, { - relations: ["items", "items.variant"], - }) - - let variant: ProductVariant - orders.some((order) => ( - order.items.some((item) => { - if (item.variant_id === variantId) { - variant = item.variant - return true - } - - return false + export const GET = async ( + req: MedusaRequest, + res: MedusaResponse + ) => { + const variantId = req.params.variant_id + if (!variantId) { + throw new Error("Variant ID is required") + } + const ordersService = req.scope.resolve< + OrderService + >("orderService") + const orders = await ordersService.list({ + customer_id: req.user.customer_id, + }, { + relations: ["items", "items.variant"], }) - )) + + let variant: ProductVariant + orders.some((order) => ( + order.items.some((item) => { + if (item.variant_id === variantId) { + variant = item.variant + return true + } - if (!variant) { - throw new Error("Customer hasn't purchased this product.") + return false + }) + )) + + if (!variant) { + throw new Error("Customer hasn't purchased this product.") + } + + // get the product media and the presigned URL + const productMediaService = req.scope.resolve< + ProductMediaService + >("productMediaService") + const productMedias = await productMediaService.list({ + type: MediaType.MAIN, + variant_id: variant.id, + }) + + const fileService = req.scope.resolve< + AbstractFileService + >("fileService") + + res.json({ + url: await fileService.getPresignedDownloadUrl({ + fileKey: productMedias[0].file_key, + isPrivate: true, + }), + name: productMedias[0].name, + mime_type: productMedias[0].mime_type, + }) } + ``` - // get the product media and the presigned URL - const productMediaService = req.scope.resolve< - ProductMediaService - >("productMediaService") - const productMedias = await productMediaService.list({ - type: MediaType.MAIN, - variant_id: variant.id, - }) + Then, add the `requireCustomerAuthentication` middleware to this API Route in `src/api/middlewares.ts`: - const fileService = req.scope.resolve< - AbstractFileService - >("fileService") + ```ts title=src/api/middlewares.ts + import { + requireCustomerAuthentication, + type MiddlewaresConfig, + } from "@medusajs/medusa" - res.json({ - url: await fileService.getPresignedDownloadUrl({ - fileKey: productMedias[0].file_key, - isPrivate: true, - }), - name: productMedias[0].name, - mime_type: productMedias[0].mime_type, - }) -} -``` - -Then, add the `requireCustomerAuthentication` middleware to this API Route in `src/api/middlewares.ts`: - -```ts title=src/api/middlewares.ts -import { - requireCustomerAuthentication, - type MiddlewaresConfig, -} from "@medusajs/medusa" - -export const config: MiddlewaresConfig = { - routes: [ - { - matcher: "/store/product-media/download/*", - middlewares: [requireCustomerAuthentication()], - }, - ], -} -``` - -This ensures that only logged-in customers can access this API Route. - -You can use this API Route in your storefront to add a button that allows downloading the purchased digital product. - -To mask the presigned URL, create a Next.js API route at `src/app/api/download/main/[variant_id]/route.ts` with the following content: - -```ts title=src/app/api/download/main/[variant_id]/route.ts -import { NextRequest, NextResponse } from "next/server" - -export async function GET( - req: NextRequest, - { params }: { params: Record } -) { - // Get the variant ID from the URL - const { variant_id } = params - - // Define the API URL - const apiUrl = `${ - process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL - }/store/product-media/download/${variant_id}` - - // Fetch the file data - const { - url, - name, - mime_type, - } = await fetch(apiUrl) - .then((res) => res.json()) - - // Handle the case where the file doesn't exist - // or the customer didn't purchase the product - if (!url) { - return new NextResponse( - "File doesn't exist", - { status: 401 } - ) + export const config: MiddlewaresConfig = { + routes: [ + { + matcher: "/store/product-media/download/*", + middlewares: [requireCustomerAuthentication()], + }, + ], } + ``` - // Fetch the file - const response = await fetch(url) + This ensures that only logged-in customers can access this API Route. - // Handle the case where the file could not be fetched - if (!response.ok) { - return new NextResponse( - "File not found", - { status: 404 } - ) + You can use this API Route in your storefront to add a button that allows downloading the purchased digital product. + + To mask the presigned URL, create a Next.js API route at `src/app/api/download/main/[variant_id]/route.ts` with the following content: + + ```ts title=src/app/api/download/main/[variant_id]/route.ts + import { NextRequest, NextResponse } from "next/server" + + export async function GET( + req: NextRequest, + { params }: { params: Record } + ) { + // Get the variant ID from the URL + const { variant_id } = params + + // Define the API URL + const apiUrl = `${ + process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL + }/store/product-media/download/${variant_id}` + + // Fetch the file data + const { + url, + name, + mime_type, + } = await fetch(apiUrl) + .then((res) => res.json()) + + // Handle the case where the file doesn't exist + // or the customer didn't purchase the product + if (!url) { + return new NextResponse( + "File doesn't exist", + { status: 401 } + ) + } + + // Fetch the file + const response = await fetch(url) + + // Handle the case where the file could not be fetched + if (!response.ok) { + return new NextResponse( + "File not found", + { status: 404 } + ) + } + + // Get the file content as a buffer + const fileBuffer = await response.arrayBuffer() + + // Define response headers + const headers = { + "Content-Type": mime_type, + // This sets the file name for the download + "Content-Disposition": `attachment; filename="${name}"`, + } + + // Create a NextResponse with the PDF content and headers + const response = new NextResponse(fileBuffer, { + status: 200, + headers, + }) + + return response } + ``` - // Get the file content as a buffer - const fileBuffer = await response.arrayBuffer() + Finally, add a button in the storefront that uses this route to allow customers to download the digital product after purchase. - // Define response headers - const headers = { - "Content-Type": mime_type, - // This sets the file name for the download - "Content-Disposition": `attachment; filename="${name}"`, - } - - // Create a NextResponse with the PDF content and headers - const response = new NextResponse(fileBuffer, { - status: 200, - headers, - }) - - return response -} -``` - -Finally, add a button in the storefront that uses this route to allow customers to download the digital product after purchase. - -For example, you can change the `src/modules/order/components/items/index.tsx` file that shows the items to the customer in the order confirmation page to include a new download button: + For example, you can change the `src/modules/order/components/items/index.tsx` file that shows the items to the customer in the order confirmation page to include a new download button: -```tsx title=src/modules/order/components/items/index.tsx -import useEnrichedLineItems from "@lib/hooks/use-enrich-line-items" -import { LineItem, Region } from "@medusajs/medusa" -import LineItemOptions from "@modules/common/components/line-item-options" -import LineItemPrice from "@modules/common/components/line-item-price" -import Thumbnail from "@modules/products/components/thumbnail" -import SkeletonLineItem from "@modules/skeletons/components/skeleton-line-item" -import Link from "next/link" -import medusaRequest from "../medusa-fetch" + ```tsx title=src/modules/order/components/items/index.tsx + import useEnrichedLineItems from "@lib/hooks/use-enrich-line-items" + import { LineItem, Region } from "@medusajs/medusa" + import LineItemOptions from "@modules/common/components/line-item-options" + import LineItemPrice from "@modules/common/components/line-item-price" + import Thumbnail from "@modules/products/components/thumbnail" + import SkeletonLineItem from "@modules/skeletons/components/skeleton-line-item" + import Link from "next/link" + import medusaRequest from "../medusa-fetch" -type ItemsProps = { - items: LineItem[] - region: Region - cartId: string -} - -const Items = ({ items, region, cartId }: ItemsProps) => { - const enrichedItems = useEnrichedLineItems(items, cartId) - - const handleDownload = async (variantId: string) => { - window.location.href = `${process.env.NEXT_PUBLIC_BASE_URL}/api/download/main/${variant_id}` + type ItemsProps = { + items: LineItem[] + region: Region + cartId: string } - return ( -
- {enrichedItems?.length - ? enrichedItems.map((item) => { - return ( -
-
- -
-
-
-
-
-

- - {item.title} - -

- - Quantity: {item.quantity} -
-
- - + const Items = ({ items, region, cartId }: ItemsProps) => { + const enrichedItems = useEnrichedLineItems(items, cartId) + + const handleDownload = async (variantId: string) => { + window.location.href = `${process.env.NEXT_PUBLIC_BASE_URL}/api/download/main/${variant_id}` + } + + return ( +
+ {enrichedItems?.length + ? enrichedItems.map((item) => { + return ( +
+
+ +
+
+
+
+
+

+ + {item.title} + +

+ + Quantity: {item.quantity} +
+
+ + +
-
- ) - }) - : Array.from(Array(items.length).keys()).map((i) => { - return - })} -
- ) -} + ) + }) + : Array.from(Array(items.length).keys()).map((i) => { + return + })} +
+ ) + } -export default Items -``` + export default Items + ``` -
+
--- diff --git a/www/apps/docs/content/recipes/marketplace.mdx b/www/apps/docs/content/recipes/marketplace.mdx index cc1080e15e..3bab9d1e5a 100644 --- a/www/apps/docs/content/recipes/marketplace.mdx +++ b/www/apps/docs/content/recipes/marketplace.mdx @@ -41,105 +41,105 @@ To associate these entities with the `Store` entity, you need to extend and cust } }} /> -
-Example: Associate User with Store +
+ Example: Associate User with Store -For example, to associate the `User` entity with the `Store` entity, create the file `src/models/user.ts` with the following content: + For example, to associate the `User` entity with the `Store` entity, create the file `src/models/user.ts` with the following content: -```ts title=src/models/user.ts -import { - Column, - Entity, - Index, - JoinColumn, - ManyToOne, -} from "typeorm" -import { - User as MedusaUser, -} from "@medusajs/medusa" -import { Store } from "./store" + ```ts title=src/models/user.ts + import { + Column, + Entity, + Index, + JoinColumn, + ManyToOne, + } from "typeorm" + import { + User as MedusaUser, + } from "@medusajs/medusa" + import { Store } from "./store" -@Entity() -export class User extends MedusaUser { - @Index("UserStoreId") - @Column({ nullable: true }) - store_id?: string + @Entity() + export class User extends MedusaUser { + @Index("UserStoreId") + @Column({ nullable: true }) + store_id?: string - @ManyToOne(() => Store, (store) => store.members) - @JoinColumn({ name: "store_id", referencedColumnName: "id" }) - store?: Store -} -``` + @ManyToOne(() => Store, (store) => store.members) + @JoinColumn({ name: "store_id", referencedColumnName: "id" }) + store?: Store + } + ``` -Then, you need to extend the `UserRepository` to point to your extended entity. To do that, create the file `src/repositories/user.ts` with the following content: + Then, you need to extend the `UserRepository` to point to your extended entity. To do that, create the file `src/repositories/user.ts` with the following content: -```ts title=src/repositories/user.ts -import { User } from "../models/user" -import { - dataSource, -} from "@medusajs/medusa/dist/loaders/database" -import { - UserRepository as MedusaUserRepository, -} from "@medusajs/medusa/dist/repositories/user" + ```ts title=src/repositories/user.ts + import { User } from "../models/user" + import { + dataSource, + } from "@medusajs/medusa/dist/loaders/database" + import { + UserRepository as MedusaUserRepository, + } from "@medusajs/medusa/dist/repositories/user" -export const UserRepository = dataSource - .getRepository(User) - .extend({ - ...Object.assign( - MedusaUserRepository, - { target: User } - ), - }) + export const UserRepository = dataSource + .getRepository(User) + .extend({ + ...Object.assign( + MedusaUserRepository, + { target: User } + ), + }) -export default UserRepository -``` + export default UserRepository + ``` -Next, you need to create a migration that reflects the changes on the `User` entity in your database. To do that, run the following command to create a migration file: + Next, you need to create a migration that reflects the changes on the `User` entity in your database. To do that, run the following command to create a migration file: -```bash -npx typeorm migration:create src/migrations/add-user-store-id -``` + ```bash + npx typeorm migration:create src/migrations/add-user-store-id + ``` -This creates a file in the `src/migrations` directory of the format `_add-user-store-id.ts`. Replace the `up` and `down` methods in that file with the methods here: + This creates a file in the `src/migrations` directory of the format `_add-user-store-id.ts`. Replace the `up` and `down` methods in that file with the methods here: -```ts title=src/migrations/_add-user-store-id.ts -// ... + ```ts title=src/migrations/_add-user-store-id.ts + // ... -export class AddUserStoreId1681287255173 - implements MigrationInterface { - // ... + export class AddUserStoreId1681287255173 + implements MigrationInterface { + // ... - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `ALTER TABLE "user" ADD "store_id" character varying` - ) - await queryRunner.query( - `CREATE INDEX "UserStoreId" ON "user" ("store_id")` - ) - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "user" ADD "store_id" character varying` + ) + await queryRunner.query( + `CREATE INDEX "UserStoreId" ON "user" ("store_id")` + ) + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `DROP INDEX "public"."UserStoreId"` - ) - await queryRunner.query( - `ALTER TABLE "user" DROP COLUMN "store_id"` - ) - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `DROP INDEX "public"."UserStoreId"` + ) + await queryRunner.query( + `ALTER TABLE "user" DROP COLUMN "store_id"` + ) + } -} -``` + } + ``` -Finally, to reflect these changes and start using them, `build` your changes and run migrations with the following commands: + Finally, to reflect these changes and start using them, `build` your changes and run migrations with the following commands: -```bash npm2yarn -npm run build -npx medusa migrations run -``` + ```bash npm2yarn + npm run build + npx medusa migrations run + ``` -You can extend other entities in a similar manner to associate them with a store. + You can extend other entities in a similar manner to associate them with a store. -
+
--- @@ -179,75 +179,76 @@ You can also extend services if you need to customize a functionality implemente } }} /> -
-Example: Extend User Service +
+ Example: Extend User Service -You can extend the user service to change how the `create` method is implemented. + You can extend the user service to change how the `create` method is implemented. -To extend the user service, create the file `src/services/user.ts` with the following content: + To extend the user service, create the file `src/services/user.ts` with the following content: -```ts title=src/services/user.ts -import { Lifetime } from "awilix" -import { - UserService as MedusaUserService, -} from "@medusajs/medusa" -import { User } from "../models/user" -import { - CreateUserInput as MedusaCreateUserInput, -} from "@medusajs/medusa/dist/types/user" -import StoreRepository from "../repositories/store" + ```ts title=src/services/user.ts + import { Lifetime } from "awilix" + import { + UserService as MedusaUserService, + } from "@medusajs/medusa" + import { User } from "../models/user" + import { + CreateUserInput as MedusaCreateUserInput, + } from "@medusajs/medusa/dist/types/user" + import StoreRepository from "../repositories/store" -type CreateUserInput = { - store_id?: string -} & MedusaCreateUserInput + type CreateUserInput = { + store_id?: string + } & MedusaCreateUserInput -class UserService extends MedusaUserService { - static LIFE_TIME = Lifetime.SCOPED - protected readonly loggedInUser_: User | null - protected readonly storeRepository_: typeof StoreRepository + class UserService extends MedusaUserService { + static LIFE_TIME = Lifetime.SCOPED + protected readonly loggedInUser_: User | null + protected readonly storeRepository_: typeof StoreRepository - constructor(container, options) { - super(...arguments) - this.storeRepository_ = container.storeRepository + constructor(container, options) { + super(...arguments) + this.storeRepository_ = container.storeRepository - try { - this.loggedInUser_ = container.loggedInUser - } catch (e) { - // avoid errors when backend first runs + try { + this.loggedInUser_ = container.loggedInUser + } catch (e) { + // avoid errors when backend first runs + } + } + + async create( + user: CreateUserInput, + password: string + ): Promise { + if (!user.store_id) { + const storeRepo = this.manager_.withRepository( + this.storeRepository_ + ) + let newStore = storeRepo.create() + newStore = await storeRepo.save(newStore) + user.store_id = newStore.id + } + + return await super.create(user, password) } } - async create( - user: CreateUserInput, - password: string - ): Promise { - if (!user.store_id) { - const storeRepo = this.manager_.withRepository( - this.storeRepository_ - ) - let newStore = storeRepo.create() - newStore = await storeRepo.save(newStore) - user.store_id = newStore.id - } + export default UserService + ``` - return await super.create(user, password) - } -} + In the `create` method of this extended service, you create a new store if the user being created doesn't have a store associated with it. -export default UserService -``` + You can then test out your customization by running the `build` command and starting the backend: -In the `create` method of this extended service, you create a new store if the user being created doesn't have a store associated with it. + ```bash + npm run build + npx medusa develop + ``` -You can then test out your customization by running the `build` command and starting the backend: - -```bash -npm run build -npx medusa develop -``` -
+
--- @@ -267,34 +268,35 @@ To listen to events, you need to create Subscribers that subscribe a handler met } }} /> -
-Example: Listen to Order Created Event +
+ Example: Listen to Order Created Event -To listen to the `order.placed` event, create the file `src/subscribers/orderNotifier.ts` with the following content: + To listen to the `order.placed` event, create the file `src/subscribers/orderNotifier.ts` with the following content: -```ts title=src/subscribers/orderNotifier.ts -class OrderNotifierSubscriber { - constructor({ eventBusService }) { - eventBusService.subscribe("order.placed", this.handleOrder) + ```ts title=src/subscribers/orderNotifier.ts + class OrderNotifierSubscriber { + constructor({ eventBusService }) { + eventBusService.subscribe("order.placed", this.handleOrder) + } + + handleOrder = async (data) => { + // TODO perform functionality + } } - handleOrder = async (data) => { - // TODO perform functionality - } -} + export default OrderNotifierSubscriber + ``` -export default OrderNotifierSubscriber -``` + This subscribes the `handleOrder` method to be executed whenever the `order.placed` event is emitted. -This subscribes the `handleOrder` method to be executed whenever the `order.placed` event is emitted. + You can then test out your subscriber by running the `build` command and starting the backend: -You can then test out your subscriber by running the `build` command and starting the backend: + ```bash + npm run build + npx medusa develop + ``` -```bash -npm run build -npx medusa develop -``` -
+
--- diff --git a/www/apps/docs/content/recipes/pos.mdx b/www/apps/docs/content/recipes/pos.mdx index 2fbae2a8fc..aeb6fe2563 100644 --- a/www/apps/docs/content/recipes/pos.mdx +++ b/www/apps/docs/content/recipes/pos.mdx @@ -94,50 +94,48 @@ To search through product variants by their barcode, you can create a custom API }, ]} /> -
- -Example: Search Products By Barcode API Route - +
+ Example: Search Products By Barcode API Route -Here’s an example of creating a custom API Route at `/store/pos/search-barcode` that searches product variants by a barcode: + Here’s an example of creating a custom API Route at `/store/pos/search-barcode` that searches product variants by a barcode: -```ts title=src/api/store/pos/search-barcode/route.ts -import type { - MedusaRequest, - MedusaResponse, - ProductVariantService, -} from "@medusajs/medusa" -import { MedusaError } from "@medusajs/utils" + ```ts title=src/api/store/pos/search-barcode/route.ts + import type { + MedusaRequest, + MedusaResponse, + ProductVariantService, + } from "@medusajs/medusa" + import { MedusaError } from "@medusajs/utils" -export const GET = async ( - req: MedusaRequest, - res: MedusaResponse -) => { - const barcode = (req.query.barcode as string) || "" - if (!barcode) { - throw new MedusaError( - MedusaError.Types.INVALID_DATA, - "Barcode is required" - ) - } - // get product service - const productVariantService = req.scope.resolve< - ProductVariantService - >("productVariantService") + export const GET = async ( + req: MedusaRequest, + res: MedusaResponse + ) => { + const barcode = (req.query.barcode as string) || "" + if (!barcode) { + throw new MedusaError( + MedusaError.Types.INVALID_DATA, + "Barcode is required" + ) + } + // get product service + const productVariantService = req.scope.resolve< + ProductVariantService + >("productVariantService") - // retrieve product variants by barcode - const productVariants = await productVariantService - .list({ - barcode, + // retrieve product variants by barcode + const productVariants = await productVariantService + .list({ + barcode, + }) + + res.json({ + product_variants: productVariants, }) + } + ``` - res.json({ - product_variants: productVariants, - }) -} -``` - -
+
--- diff --git a/www/apps/docs/content/references/entities/classes/Address.mdx b/www/apps/docs/content/references/entities/classes/Address.mdx index 136a315690..e1ac01d7da 100644 --- a/www/apps/docs/content/references/entities/classes/Address.mdx +++ b/www/apps/docs/content/references/entities/classes/Address.mdx @@ -49,7 +49,7 @@ An address is used across the Medusa backend within other schemas and object typ }, { "name": "country", - "type": "``null`` \\| [`Country`](Country.mdx)", + "type": "``null`` \\| [Country](Country.mdx)", "description": "A country object.", "optional": false, "defaultValue": "", @@ -76,7 +76,7 @@ An address is used across the Medusa backend within other schemas and object typ }, { "name": "customer", - "type": "``null`` \\| [`Customer`](Customer.mdx)", + "type": "``null`` \\| [Customer](Customer.mdx)", "description": "Available if the relation `customer` is expanded.", "optional": false, "defaultValue": "", @@ -130,7 +130,7 @@ An address is used across the Medusa backend within other schemas and object typ }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/BatchJob.mdx b/www/apps/docs/content/references/entities/classes/BatchJob.mdx index ea81f95595..193447cc31 100644 --- a/www/apps/docs/content/references/entities/classes/BatchJob.mdx +++ b/www/apps/docs/content/references/entities/classes/BatchJob.mdx @@ -40,7 +40,7 @@ A Batch Job indicates an asynchronus task stored in the Medusa backend. Its stat }, { "name": "context", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "The context of the batch job, the type of the batch job determines what the context should contain.", "optional": false, "defaultValue": "", @@ -67,7 +67,7 @@ A Batch Job indicates an asynchronus task stored in the Medusa backend. Its stat }, { "name": "created_by_user", - "type": "[`User`](User.mdx)", + "type": "[User](User.mdx)", "description": "The details of the user that created the batch job.", "optional": false, "defaultValue": "", @@ -138,7 +138,7 @@ A Batch Job indicates an asynchronus task stored in the Medusa backend. Its stat }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -156,7 +156,7 @@ A Batch Job indicates an asynchronus task stored in the Medusa backend. Its stat }, { "name": "role", - "type": "[`UserRoles`](../enums/UserRoles.mdx)", + "type": "[UserRoles](../enums/UserRoles.mdx)", "description": "The user's role. These roles don't provide any different privileges.", "optional": false, "defaultValue": "member", @@ -230,7 +230,7 @@ A Batch Job indicates an asynchronus task stored in the Medusa backend. Its stat }, { "name": "result", - "type": "{ `advancement_count?`: `number` ; `count?`: `number` ; `errors?`: (`string` \\| [`BatchJobResultError`](../types/BatchJobResultError.mdx))[] ; `file_key?`: `string` ; `file_size?`: `number` ; `progress?`: `number` ; `stat_descriptors?`: [`BatchJobResultStatDescriptor`](../types/BatchJobResultStatDescriptor.mdx)[] } & Record<`string`, `unknown`\\>", + "type": "`{ advancement_count?: number ; count?: number ; errors?: (string \\| [BatchJobResultError](../types/BatchJobResultError.mdx))[] ; file_key?: string ; file_size?: number ; progress?: number ; stat_descriptors?: [BatchJobResultStatDescriptor](../types/BatchJobResultStatDescriptor.mdx)[] }` & `Record`", "description": "The result of the batch job.", "optional": false, "defaultValue": "", @@ -256,7 +256,7 @@ A Batch Job indicates an asynchronus task stored in the Medusa backend. Its stat }, { "name": "errors", - "type": "(`string` \\| [`BatchJobResultError`](../types/BatchJobResultError.mdx))[]", + "type": "(`string` \\| [BatchJobResultError](../types/BatchJobResultError.mdx))[]", "description": "", "optional": true, "defaultValue": "", @@ -292,7 +292,7 @@ A Batch Job indicates an asynchronus task stored in the Medusa backend. Its stat }, { "name": "stat_descriptors", - "type": "[`BatchJobResultStatDescriptor`](../types/BatchJobResultStatDescriptor.mdx)[]", + "type": "[BatchJobResultStatDescriptor](../types/BatchJobResultStatDescriptor.mdx)[]", "description": "", "optional": true, "defaultValue": "", @@ -303,7 +303,7 @@ A Batch Job indicates an asynchronus task stored in the Medusa backend. Its stat }, { "name": "status", - "type": "[`BatchJobStatus`](../enums/BatchJobStatus.mdx)", + "type": "[BatchJobStatus](../enums/BatchJobStatus.mdx)", "description": "The status of the batch job.", "optional": false, "defaultValue": "created", diff --git a/www/apps/docs/content/references/entities/classes/Cart.mdx b/www/apps/docs/content/references/entities/classes/Cart.mdx index 9d4d66d067..6bce374839 100644 --- a/www/apps/docs/content/references/entities/classes/Cart.mdx +++ b/www/apps/docs/content/references/entities/classes/Cart.mdx @@ -13,7 +13,7 @@ A cart represents a virtual shopping bag. It can be used to complete an order, a ", + "type": "`Record`", "description": "The context of the cart which can include info like IP or user agent.", "optional": false, "defaultValue": "", @@ -58,7 +58,7 @@ A cart represents a virtual shopping bag. It can be used to complete an order, a }, { "name": "customer", - "type": "[`Customer`](Customer.mdx)", + "type": "[Customer](Customer.mdx)", "description": "The details of the customer the cart belongs to.", "optional": false, "defaultValue": "", @@ -94,7 +94,7 @@ A cart represents a virtual shopping bag. It can be used to complete an order, a }, { "name": "discounts", - "type": "[`Discount`](Discount.mdx)[]", + "type": "[Discount](Discount.mdx)[]", "description": "An array of details of all discounts applied to the cart.", "optional": false, "defaultValue": "", @@ -130,7 +130,7 @@ A cart represents a virtual shopping bag. It can be used to complete an order, a }, { "name": "gift_cards", - "type": "[`GiftCard`](GiftCard.mdx)[]", + "type": "[GiftCard](GiftCard.mdx)[]", "description": "An array of details of all gift cards applied to the cart.", "optional": false, "defaultValue": "", @@ -166,7 +166,7 @@ A cart represents a virtual shopping bag. It can be used to complete an order, a }, { "name": "items", - "type": "[`LineItem`](LineItem.mdx)[]", + "type": "[LineItem](LineItem.mdx)[]", "description": "The line items added to the cart.", "optional": false, "defaultValue": "", @@ -175,7 +175,7 @@ A cart represents a virtual shopping bag. It can be used to complete an order, a }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -193,7 +193,7 @@ A cart represents a virtual shopping bag. It can be used to complete an order, a }, { "name": "payment", - "type": "[`Payment`](Payment.mdx)", + "type": "[Payment](Payment.mdx)", "description": "The details of the payment associated with the cart.", "optional": false, "defaultValue": "", @@ -220,7 +220,7 @@ A cart represents a virtual shopping bag. It can be used to complete an order, a }, { "name": "payment_session", - "type": "``null`` \\| [`PaymentSession`](PaymentSession.mdx)", + "type": "``null`` \\| [PaymentSession](PaymentSession.mdx)", "description": "The details of the selected payment session in the cart.", "optional": false, "defaultValue": "", @@ -229,7 +229,7 @@ A cart represents a virtual shopping bag. It can be used to complete an order, a }, { "name": "payment_sessions", - "type": "[`PaymentSession`](PaymentSession.mdx)[]", + "type": "[PaymentSession](PaymentSession.mdx)[]", "description": "The details of all payment sessions created on the cart.", "optional": false, "defaultValue": "", @@ -265,7 +265,7 @@ A cart represents a virtual shopping bag. It can be used to complete an order, a }, { "name": "region", - "type": "[`Region`](Region.mdx)", + "type": "[Region](Region.mdx)", "description": "The details of the region associated with the cart.", "optional": false, "defaultValue": "", @@ -283,7 +283,7 @@ A cart represents a virtual shopping bag. It can be used to complete an order, a }, { "name": "sales_channel", - "type": "[`SalesChannel`](SalesChannel.mdx)", + "type": "[SalesChannel](SalesChannel.mdx)", "description": "The details of the sales channel associated with the cart.", "optional": false, "defaultValue": "", @@ -301,7 +301,7 @@ A cart represents a virtual shopping bag. It can be used to complete an order, a }, { "name": "shipping_address", - "type": "``null`` \\| [`Address`](Address.mdx)", + "type": "``null`` \\| [Address](Address.mdx)", "description": "The details of the shipping address associated with the cart.", "optional": false, "defaultValue": "", @@ -319,7 +319,7 @@ A cart represents a virtual shopping bag. It can be used to complete an order, a }, { "name": "shipping_methods", - "type": "[`ShippingMethod`](ShippingMethod.mdx)[]", + "type": "[ShippingMethod](ShippingMethod.mdx)[]", "description": "The details of the shipping methods added to the cart.", "optional": false, "defaultValue": "", @@ -373,7 +373,7 @@ A cart represents a virtual shopping bag. It can be used to complete an order, a }, { "name": "type", - "type": "[`CartType`](../enums/CartType.mdx)", + "type": "[CartType](../enums/CartType.mdx)", "description": "The cart's type.", "optional": false, "defaultValue": "default", diff --git a/www/apps/docs/content/references/entities/classes/ClaimImage.mdx b/www/apps/docs/content/references/entities/classes/ClaimImage.mdx index feebb6aaad..b6a646983e 100644 --- a/www/apps/docs/content/references/entities/classes/ClaimImage.mdx +++ b/www/apps/docs/content/references/entities/classes/ClaimImage.mdx @@ -13,7 +13,7 @@ The details of an image attached to a claim. ", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -120,7 +120,7 @@ The details of an image attached to a claim. }, { "name": "reason", - "type": "[`ClaimReason`](../enums/ClaimReason.mdx)", + "type": "[ClaimReason](../enums/ClaimReason.mdx)", "description": "The reason for the claim", "optional": false, "defaultValue": "", @@ -129,7 +129,7 @@ The details of an image attached to a claim. }, { "name": "tags", - "type": "[`ClaimTag`](ClaimTag.mdx)[]", + "type": "[ClaimTag](ClaimTag.mdx)[]", "description": "User defined tags for easy filtering and grouping.", "optional": false, "defaultValue": "", @@ -147,7 +147,7 @@ The details of an image attached to a claim. }, { "name": "variant", - "type": "[`ProductVariant`](ProductVariant.mdx)", + "type": "[ProductVariant](ProductVariant.mdx)", "description": "The details of the product variant to potentially replace the item in the original order.", "optional": false, "defaultValue": "", @@ -203,7 +203,7 @@ The details of an image attached to a claim. }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/ClaimItem.mdx b/www/apps/docs/content/references/entities/classes/ClaimItem.mdx index 9cefa9f2ff..2f08d87f94 100644 --- a/www/apps/docs/content/references/entities/classes/ClaimItem.mdx +++ b/www/apps/docs/content/references/entities/classes/ClaimItem.mdx @@ -13,7 +13,7 @@ A claim item is an item created as part of a claim. It references an item in the ", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -120,7 +120,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "order", - "type": "[`Order`](Order.mdx)", + "type": "[Order](Order.mdx)", "description": "The details of the order that this claim was created for.", "optional": false, "defaultValue": "", @@ -138,7 +138,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "payment_status", - "type": "[`ClaimPaymentStatus`](../enums/ClaimPaymentStatus.mdx)", + "type": "[ClaimPaymentStatus](../enums/ClaimPaymentStatus.mdx)", "description": "The status of the claim's payment", "optional": false, "defaultValue": "na", @@ -156,7 +156,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "return_order", - "type": "[`Return`](Return.mdx)", + "type": "[Return](Return.mdx)", "description": "The details of the return associated with the claim if the claim's type is `replace`.", "optional": false, "defaultValue": "", @@ -165,7 +165,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "shipping_address", - "type": "[`Address`](Address.mdx)", + "type": "[Address](Address.mdx)", "description": "The details of the address that new items should be shipped to.", "optional": false, "defaultValue": "", @@ -183,7 +183,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "shipping_methods", - "type": "[`ShippingMethod`](ShippingMethod.mdx)[]", + "type": "[ShippingMethod](ShippingMethod.mdx)[]", "description": "The details of the shipping methods that the claim order will be shipped with.", "optional": false, "defaultValue": "", @@ -192,7 +192,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "type", - "type": "[`ClaimType`](../enums/ClaimType.mdx)", + "type": "[ClaimType](../enums/ClaimType.mdx)", "description": "The claim's type", "optional": false, "defaultValue": "", @@ -248,7 +248,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "images", - "type": "[`ClaimImage`](ClaimImage.mdx)[]", + "type": "[ClaimImage](ClaimImage.mdx)[]", "description": "The claim images that are attached to the claim item.", "optional": false, "defaultValue": "", @@ -256,7 +256,7 @@ A claim item is an item created as part of a claim. It references an item in the "children": [ { "name": "claim_item", - "type": "[`ClaimItem`](ClaimItem.mdx)", + "type": "[ClaimItem](ClaimItem.mdx)", "description": "The details of the claim item this image is associated with.", "optional": false, "defaultValue": "", @@ -301,7 +301,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -330,7 +330,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "item", - "type": "[`LineItem`](LineItem.mdx)", + "type": "[LineItem](LineItem.mdx)", "description": "The details of the line item in the original order that this claim item refers to.", "optional": false, "defaultValue": "", @@ -338,7 +338,7 @@ A claim item is an item created as part of a claim. It references an item in the "children": [ { "name": "adjustments", - "type": "[`LineItemAdjustment`](LineItemAdjustment.mdx)[]", + "type": "[LineItemAdjustment](LineItemAdjustment.mdx)[]", "description": "The details of the item's adjustments, which are available when a discount is applied on the item.", "optional": false, "defaultValue": "", @@ -356,7 +356,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "cart", - "type": "[`Cart`](Cart.mdx)", + "type": "[Cart](Cart.mdx)", "description": "The details of the cart that the line item may belongs to.", "optional": false, "defaultValue": "", @@ -374,7 +374,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "claim_order", - "type": "[`ClaimOrder`](ClaimOrder.mdx)", + "type": "[ClaimOrder](ClaimOrder.mdx)", "description": "The details of the claim that the line item may belong to.", "optional": false, "defaultValue": "", @@ -456,7 +456,7 @@ A claim item is an item created as part of a claim. It references an item in the { "name": "includes_tax", "type": "`boolean`", - "description": "Indicates if the line item unit_price include tax", + "description": "Indicates if the line item unit\\_price include tax", "optional": false, "defaultValue": "false", "expandable": false, @@ -483,7 +483,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -492,7 +492,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "order", - "type": "[`Order`](Order.mdx)", + "type": "[Order](Order.mdx)", "description": "The details of the order that the line item may belongs to.", "optional": false, "defaultValue": "", @@ -501,7 +501,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "order_edit", - "type": "``null`` \\| [`OrderEdit`](OrderEdit.mdx)", + "type": "``null`` \\| [OrderEdit](OrderEdit.mdx)", "description": "The details of the order edit.", "optional": true, "defaultValue": "", @@ -627,7 +627,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "swap", - "type": "[`Swap`](Swap.mdx)", + "type": "[Swap](Swap.mdx)", "description": "The details of the swap that the line item may belong to.", "optional": false, "defaultValue": "", @@ -645,7 +645,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "tax_lines", - "type": "[`LineItemTaxLine`](LineItemTaxLine.mdx)[]", + "type": "[LineItemTaxLine](LineItemTaxLine.mdx)[]", "description": "The details of the item's tax lines.", "optional": false, "defaultValue": "", @@ -708,7 +708,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "variant", - "type": "[`ProductVariant`](ProductVariant.mdx)", + "type": "[ProductVariant](ProductVariant.mdx)", "description": "The details of the product variant that this item was created from.", "optional": false, "defaultValue": "", @@ -737,7 +737,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -764,7 +764,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "reason", - "type": "[`ClaimReason`](../enums/ClaimReason.mdx)", + "type": "[ClaimReason](../enums/ClaimReason.mdx)", "description": "The reason for the claim", "optional": false, "defaultValue": "", @@ -810,7 +810,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "tags", - "type": "[`ClaimTag`](ClaimTag.mdx)[]", + "type": "[ClaimTag](ClaimTag.mdx)[]", "description": "User defined tags for easy filtering and grouping.", "optional": false, "defaultValue": "", @@ -845,7 +845,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -883,7 +883,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "variant", - "type": "[`ProductVariant`](ProductVariant.mdx)", + "type": "[ProductVariant](ProductVariant.mdx)", "description": "The details of the product variant to potentially replace the item in the original order.", "optional": false, "defaultValue": "", @@ -892,7 +892,7 @@ A claim item is an item created as part of a claim. It references an item in the { "name": "allow_backorder", "type": "`boolean`", - "description": "Whether the Product Variant should be purchasable when `inventory_quantity` is 0.", + "description": "Whether the Product Variant should be purchasable when `inventory\\_quantity` is 0.", "optional": false, "defaultValue": "false", "expandable": false, @@ -963,7 +963,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "inventory_items", - "type": "[`ProductVariantInventoryItem`](ProductVariantInventoryItem.mdx)[]", + "type": "[ProductVariantInventoryItem](ProductVariantInventoryItem.mdx)[]", "description": "The details inventory items of the product variant.", "optional": false, "defaultValue": "", @@ -1008,7 +1008,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "metadata", - "type": "``null`` \\| Record<`string`, `unknown`\\>", + "type": "``null`` \\| `Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -1026,7 +1026,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "options", - "type": "[`ProductOptionValue`](ProductOptionValue.mdx)[]", + "type": "[ProductOptionValue](ProductOptionValue.mdx)[]", "description": "The details of the product options that this product variant defines values for.", "optional": false, "defaultValue": "", @@ -1044,7 +1044,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "prices", - "type": "[`MoneyAmount`](MoneyAmount.mdx)[]", + "type": "[MoneyAmount](MoneyAmount.mdx)[]", "description": "The details of the prices of the Product Variant, each represented as a Money Amount. Each Money Amount represents a price in a given currency or a specific Region.", "optional": false, "defaultValue": "", @@ -1053,7 +1053,7 @@ A claim item is an item created as part of a claim. It references an item in the }, { "name": "product", - "type": "[`Product`](Product.mdx)", + "type": "[Product](Product.mdx)", "description": "The details of the product that the product variant belongs to.", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/ClaimOrder.mdx b/www/apps/docs/content/references/entities/classes/ClaimOrder.mdx index cd817c9382..92ef2561f7 100644 --- a/www/apps/docs/content/references/entities/classes/ClaimOrder.mdx +++ b/www/apps/docs/content/references/entities/classes/ClaimOrder.mdx @@ -13,7 +13,7 @@ A Claim represents a group of faulty or missing items. It consists of claim item ", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -112,7 +112,7 @@ A Claim represents a group of faulty or missing items. It consists of claim item }, { "name": "order", - "type": "[`Order`](Order.mdx)", + "type": "[Order](Order.mdx)", "description": "The details of the order that this claim was created for.", "optional": false, "defaultValue": "", @@ -130,7 +130,7 @@ A Claim represents a group of faulty or missing items. It consists of claim item }, { "name": "payment_status", - "type": "[`ClaimPaymentStatus`](../enums/ClaimPaymentStatus.mdx)", + "type": "[ClaimPaymentStatus](../enums/ClaimPaymentStatus.mdx)", "description": "The status of the claim's payment", "optional": false, "defaultValue": "na", @@ -148,7 +148,7 @@ A Claim represents a group of faulty or missing items. It consists of claim item }, { "name": "return_order", - "type": "[`Return`](Return.mdx)", + "type": "[Return](Return.mdx)", "description": "The details of the return associated with the claim if the claim's type is `replace`.", "optional": false, "defaultValue": "", @@ -157,7 +157,7 @@ A Claim represents a group of faulty or missing items. It consists of claim item }, { "name": "shipping_address", - "type": "[`Address`](Address.mdx)", + "type": "[Address](Address.mdx)", "description": "The details of the address that new items should be shipped to.", "optional": false, "defaultValue": "", @@ -175,7 +175,7 @@ A Claim represents a group of faulty or missing items. It consists of claim item }, { "name": "shipping_methods", - "type": "[`ShippingMethod`](ShippingMethod.mdx)[]", + "type": "[ShippingMethod](ShippingMethod.mdx)[]", "description": "The details of the shipping methods that the claim order will be shipped with.", "optional": false, "defaultValue": "", @@ -184,7 +184,7 @@ A Claim represents a group of faulty or missing items. It consists of claim item }, { "name": "type", - "type": "[`ClaimType`](../enums/ClaimType.mdx)", + "type": "[ClaimType](../enums/ClaimType.mdx)", "description": "The claim's type", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/ClaimTag.mdx b/www/apps/docs/content/references/entities/classes/ClaimTag.mdx index 31d26fbb1c..c0cf8bb31d 100644 --- a/www/apps/docs/content/references/entities/classes/ClaimTag.mdx +++ b/www/apps/docs/content/references/entities/classes/ClaimTag.mdx @@ -40,7 +40,7 @@ Claim Tags are user defined tags that can be assigned to claim items for easy fi }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/Country.mdx b/www/apps/docs/content/references/entities/classes/Country.mdx index 4a26cc7217..6f4555ba0a 100644 --- a/www/apps/docs/content/references/entities/classes/Country.mdx +++ b/www/apps/docs/content/references/entities/classes/Country.mdx @@ -67,7 +67,7 @@ Country details }, { "name": "region", - "type": "[`Region`](Region.mdx)", + "type": "[Region](Region.mdx)", "description": "The details of the region the country is associated with.", "optional": false, "defaultValue": "", @@ -84,7 +84,7 @@ Country details }, { "name": "countries", - "type": "[`Country`](Country.mdx)[]", + "type": "[Country](Country.mdx)[]", "description": "The details of the countries included in this region.", "optional": false, "defaultValue": "", @@ -102,7 +102,7 @@ Country details }, { "name": "currency", - "type": "[`Currency`](Currency.mdx)", + "type": "[Currency](Currency.mdx)", "description": "The details of the currency used in the region.", "optional": false, "defaultValue": "", @@ -129,7 +129,7 @@ Country details }, { "name": "fulfillment_providers", - "type": "[`FulfillmentProvider`](FulfillmentProvider.mdx)[]", + "type": "[FulfillmentProvider](FulfillmentProvider.mdx)[]", "description": "The details of the fulfillment providers that can be used to fulfill items of orders and similar resources in the region.", "optional": false, "defaultValue": "", @@ -166,7 +166,7 @@ Country details }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -184,7 +184,7 @@ Country details }, { "name": "payment_providers", - "type": "[`PaymentProvider`](PaymentProvider.mdx)[]", + "type": "[PaymentProvider](PaymentProvider.mdx)[]", "description": "The details of the payment providers that can be used to process payments in the region.", "optional": false, "defaultValue": "", @@ -202,7 +202,7 @@ Country details }, { "name": "tax_provider", - "type": "[`TaxProvider`](TaxProvider.mdx)", + "type": "[TaxProvider](TaxProvider.mdx)", "description": "The details of the tax provider used in the region.", "optional": false, "defaultValue": "", @@ -229,7 +229,7 @@ Country details }, { "name": "tax_rates", - "type": "``null`` \\| [`TaxRate`](TaxRate.mdx)[]", + "type": "``null`` \\| [TaxRate](TaxRate.mdx)[]", "description": "The details of the tax rates used in the region, aside from the default rate.", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/CustomShippingOption.mdx b/www/apps/docs/content/references/entities/classes/CustomShippingOption.mdx index 4bc6c956a1..007cb729d0 100644 --- a/www/apps/docs/content/references/entities/classes/CustomShippingOption.mdx +++ b/www/apps/docs/content/references/entities/classes/CustomShippingOption.mdx @@ -13,7 +13,7 @@ Custom Shipping Options are overridden Shipping Options. Admins can attach a Cus ", + "type": "`Record`", "description": "The context of the cart which can include info like IP or user agent.", "optional": false, "defaultValue": "", @@ -66,7 +66,7 @@ Custom Shipping Options are overridden Shipping Options. Admins can attach a Cus }, { "name": "customer", - "type": "[`Customer`](Customer.mdx)", + "type": "[Customer](Customer.mdx)", "description": "The details of the customer the cart belongs to.", "optional": false, "defaultValue": "", @@ -102,7 +102,7 @@ Custom Shipping Options are overridden Shipping Options. Admins can attach a Cus }, { "name": "discounts", - "type": "[`Discount`](Discount.mdx)[]", + "type": "[Discount](Discount.mdx)[]", "description": "An array of details of all discounts applied to the cart.", "optional": false, "defaultValue": "", @@ -138,7 +138,7 @@ Custom Shipping Options are overridden Shipping Options. Admins can attach a Cus }, { "name": "gift_cards", - "type": "[`GiftCard`](GiftCard.mdx)[]", + "type": "[GiftCard](GiftCard.mdx)[]", "description": "An array of details of all gift cards applied to the cart.", "optional": false, "defaultValue": "", @@ -174,7 +174,7 @@ Custom Shipping Options are overridden Shipping Options. Admins can attach a Cus }, { "name": "items", - "type": "[`LineItem`](LineItem.mdx)[]", + "type": "[LineItem](LineItem.mdx)[]", "description": "The line items added to the cart.", "optional": false, "defaultValue": "", @@ -183,7 +183,7 @@ Custom Shipping Options are overridden Shipping Options. Admins can attach a Cus }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -201,7 +201,7 @@ Custom Shipping Options are overridden Shipping Options. Admins can attach a Cus }, { "name": "payment", - "type": "[`Payment`](Payment.mdx)", + "type": "[Payment](Payment.mdx)", "description": "The details of the payment associated with the cart.", "optional": false, "defaultValue": "", @@ -228,7 +228,7 @@ Custom Shipping Options are overridden Shipping Options. Admins can attach a Cus }, { "name": "payment_session", - "type": "``null`` \\| [`PaymentSession`](PaymentSession.mdx)", + "type": "``null`` \\| [PaymentSession](PaymentSession.mdx)", "description": "The details of the selected payment session in the cart.", "optional": false, "defaultValue": "", @@ -237,7 +237,7 @@ Custom Shipping Options are overridden Shipping Options. Admins can attach a Cus }, { "name": "payment_sessions", - "type": "[`PaymentSession`](PaymentSession.mdx)[]", + "type": "[PaymentSession](PaymentSession.mdx)[]", "description": "The details of all payment sessions created on the cart.", "optional": false, "defaultValue": "", @@ -273,7 +273,7 @@ Custom Shipping Options are overridden Shipping Options. Admins can attach a Cus }, { "name": "region", - "type": "[`Region`](Region.mdx)", + "type": "[Region](Region.mdx)", "description": "The details of the region associated with the cart.", "optional": false, "defaultValue": "", @@ -291,7 +291,7 @@ Custom Shipping Options are overridden Shipping Options. Admins can attach a Cus }, { "name": "sales_channel", - "type": "[`SalesChannel`](SalesChannel.mdx)", + "type": "[SalesChannel](SalesChannel.mdx)", "description": "The details of the sales channel associated with the cart.", "optional": false, "defaultValue": "", @@ -309,7 +309,7 @@ Custom Shipping Options are overridden Shipping Options. Admins can attach a Cus }, { "name": "shipping_address", - "type": "``null`` \\| [`Address`](Address.mdx)", + "type": "``null`` \\| [Address](Address.mdx)", "description": "The details of the shipping address associated with the cart.", "optional": false, "defaultValue": "", @@ -327,7 +327,7 @@ Custom Shipping Options are overridden Shipping Options. Admins can attach a Cus }, { "name": "shipping_methods", - "type": "[`ShippingMethod`](ShippingMethod.mdx)[]", + "type": "[ShippingMethod](ShippingMethod.mdx)[]", "description": "The details of the shipping methods added to the cart.", "optional": false, "defaultValue": "", @@ -381,7 +381,7 @@ Custom Shipping Options are overridden Shipping Options. Admins can attach a Cus }, { "name": "type", - "type": "[`CartType`](../enums/CartType.mdx)", + "type": "[CartType](../enums/CartType.mdx)", "description": "The cart's type.", "optional": false, "defaultValue": "default", @@ -437,7 +437,7 @@ Custom Shipping Options are overridden Shipping Options. Admins can attach a Cus }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -455,7 +455,7 @@ Custom Shipping Options are overridden Shipping Options. Admins can attach a Cus }, { "name": "shipping_option", - "type": "[`ShippingOption`](ShippingOption.mdx)", + "type": "[ShippingOption](ShippingOption.mdx)", "description": "The details of the overridden shipping options.", "optional": false, "defaultValue": "", @@ -473,7 +473,7 @@ Custom Shipping Options are overridden Shipping Options. Admins can attach a Cus { "name": "amount", "type": "``null`` \\| `number`", - "description": "The amount to charge for shipping when the Shipping Option price type is `flat_rate`.", + "description": "The amount to charge for shipping when the Shipping Option price type is `flat\\_rate`.", "optional": false, "defaultValue": "", "expandable": false, @@ -490,7 +490,7 @@ Custom Shipping Options are overridden Shipping Options. Admins can attach a Cus }, { "name": "data", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "The data needed for the Fulfillment Provider to identify the Shipping Option.", "optional": false, "defaultValue": "", @@ -536,7 +536,7 @@ Custom Shipping Options are overridden Shipping Options. Admins can attach a Cus }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -554,8 +554,8 @@ Custom Shipping Options are overridden Shipping Options. Admins can attach a Cus }, { "name": "price_type", - "type": "[`ShippingOptionPriceType`](../enums/ShippingOptionPriceType.mdx)", - "description": "The type of pricing calculation that is used when creatin Shipping Methods from the Shipping Option. Can be `flat_rate` for fixed prices or `calculated` if the Fulfillment Provider can provide price calulations.", + "type": "[ShippingOptionPriceType](../enums/ShippingOptionPriceType.mdx)", + "description": "The type of pricing calculation that is used when creatin Shipping Methods from the Shipping Option. Can be `flat\\_rate` for fixed prices or `calculated` if the Fulfillment Provider can provide price calulations.", "optional": false, "defaultValue": "", "expandable": false, @@ -563,7 +563,7 @@ Custom Shipping Options are overridden Shipping Options. Admins can attach a Cus }, { "name": "profile", - "type": "[`ShippingProfile`](ShippingProfile.mdx)", + "type": "[ShippingProfile](ShippingProfile.mdx)", "description": "The details of the shipping profile that the shipping option belongs to.", "optional": false, "defaultValue": "", @@ -581,7 +581,7 @@ Custom Shipping Options are overridden Shipping Options. Admins can attach a Cus }, { "name": "provider", - "type": "[`FulfillmentProvider`](FulfillmentProvider.mdx)", + "type": "[FulfillmentProvider](FulfillmentProvider.mdx)", "description": "The details of the fulfillment provider that will be used to later to process the shipping method created from this shipping option and its fulfillments.", "optional": false, "defaultValue": "", @@ -599,7 +599,7 @@ Custom Shipping Options are overridden Shipping Options. Admins can attach a Cus }, { "name": "region", - "type": "[`Region`](Region.mdx)", + "type": "[Region](Region.mdx)", "description": "The details of the region this shipping option can be used in.", "optional": false, "defaultValue": "", @@ -617,7 +617,7 @@ Custom Shipping Options are overridden Shipping Options. Admins can attach a Cus }, { "name": "requirements", - "type": "[`ShippingOptionRequirement`](ShippingOptionRequirement.mdx)[]", + "type": "[ShippingOptionRequirement](ShippingOptionRequirement.mdx)[]", "description": "The details of the requirements that must be satisfied for the Shipping Option to be available for usage in a Cart.", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/Customer.mdx b/www/apps/docs/content/references/entities/classes/Customer.mdx index 0abd0f28e1..5a81426421 100644 --- a/www/apps/docs/content/references/entities/classes/Customer.mdx +++ b/www/apps/docs/content/references/entities/classes/Customer.mdx @@ -13,7 +13,7 @@ A customer can make purchases in your store and manage their profile. ", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -230,7 +230,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "groups", - "type": "[`CustomerGroup`](CustomerGroup.mdx)[]", + "type": "[CustomerGroup](CustomerGroup.mdx)[]", "description": "The customer groups the customer belongs to.", "optional": false, "defaultValue": "", @@ -247,7 +247,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "customers", - "type": "[`Customer`](Customer.mdx)[]", + "type": "[Customer](Customer.mdx)[]", "description": "The details of the customers that belong to the customer group.", "optional": false, "defaultValue": "", @@ -274,7 +274,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -292,7 +292,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "price_lists", - "type": "[`PriceList`](PriceList.mdx)[]", + "type": "[PriceList](PriceList.mdx)[]", "description": "The price lists that are associated with the customer group.", "optional": false, "defaultValue": "", @@ -339,7 +339,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -348,7 +348,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "orders", - "type": "[`Order`](Order.mdx)[]", + "type": "[Order](Order.mdx)[]", "description": "The details of the orders this customer placed.", "optional": false, "defaultValue": "", @@ -356,7 +356,7 @@ A customer can make purchases in your store and manage their profile. "children": [ { "name": "billing_address", - "type": "[`Address`](Address.mdx)", + "type": "[Address](Address.mdx)", "description": "The details of the billing address associated with the order.", "optional": false, "defaultValue": "", @@ -383,7 +383,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "cart", - "type": "[`Cart`](Cart.mdx)", + "type": "[Cart](Cart.mdx)", "description": "The details of the cart associated with the order.", "optional": false, "defaultValue": "", @@ -401,7 +401,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "claims", - "type": "[`ClaimOrder`](ClaimOrder.mdx)[]", + "type": "[ClaimOrder](ClaimOrder.mdx)[]", "description": "The details of the claims created for the order.", "optional": false, "defaultValue": "", @@ -419,7 +419,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "currency", - "type": "[`Currency`](Currency.mdx)", + "type": "[Currency](Currency.mdx)", "description": "The details of the currency used in the order.", "optional": false, "defaultValue": "", @@ -437,7 +437,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "customer", - "type": "[`Customer`](Customer.mdx)", + "type": "[Customer](Customer.mdx)", "description": "The details of the customer associated with the order.", "optional": false, "defaultValue": "", @@ -464,7 +464,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "discounts", - "type": "[`Discount`](Discount.mdx)[]", + "type": "[Discount](Discount.mdx)[]", "description": "The details of the discounts applied on the order.", "optional": false, "defaultValue": "", @@ -482,7 +482,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "draft_order", - "type": "[`DraftOrder`](DraftOrder.mdx)", + "type": "[DraftOrder](DraftOrder.mdx)", "description": "The details of the draft order this order was created from.", "optional": false, "defaultValue": "", @@ -500,7 +500,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "edits", - "type": "[`OrderEdit`](OrderEdit.mdx)[]", + "type": "[OrderEdit](OrderEdit.mdx)[]", "description": "The details of the order edits done on the order.", "optional": false, "defaultValue": "", @@ -527,7 +527,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "fulfillment_status", - "type": "[`FulfillmentStatus`](../enums/FulfillmentStatus.mdx)", + "type": "[FulfillmentStatus](../enums/FulfillmentStatus.mdx)", "description": "The order's fulfillment status", "optional": false, "defaultValue": "not_fulfilled", @@ -536,7 +536,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "fulfillments", - "type": "[`Fulfillment`](Fulfillment.mdx)[]", + "type": "[Fulfillment](Fulfillment.mdx)[]", "description": "The details of the fulfillments created for the order.", "optional": false, "defaultValue": "", @@ -563,7 +563,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "gift_card_transactions", - "type": "[`GiftCardTransaction`](GiftCardTransaction.mdx)[]", + "type": "[GiftCardTransaction](GiftCardTransaction.mdx)[]", "description": "The gift card transactions made in the order.", "optional": false, "defaultValue": "", @@ -572,7 +572,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "gift_cards", - "type": "[`GiftCard`](GiftCard.mdx)[]", + "type": "[GiftCard](GiftCard.mdx)[]", "description": "The details of the gift card used in the order.", "optional": false, "defaultValue": "", @@ -608,7 +608,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "items", - "type": "[`LineItem`](LineItem.mdx)[]", + "type": "[LineItem](LineItem.mdx)[]", "description": "The details of the line items that belong to the order.", "optional": false, "defaultValue": "", @@ -617,7 +617,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -653,7 +653,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "payment_status", - "type": "[`PaymentStatus`](../enums/PaymentStatus.mdx)", + "type": "[PaymentStatus](../enums/PaymentStatus.mdx)", "description": "The order's payment status", "optional": false, "defaultValue": "not_paid", @@ -662,7 +662,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "payments", - "type": "[`Payment`](Payment.mdx)[]", + "type": "[Payment](Payment.mdx)[]", "description": "The details of the payments used in the order.", "optional": false, "defaultValue": "", @@ -698,7 +698,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "refunds", - "type": "[`Refund`](Refund.mdx)[]", + "type": "[Refund](Refund.mdx)[]", "description": "The details of the refunds created for the order.", "optional": false, "defaultValue": "", @@ -707,7 +707,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "region", - "type": "[`Region`](Region.mdx)", + "type": "[Region](Region.mdx)", "description": "The details of the region this order was created in.", "optional": false, "defaultValue": "", @@ -725,7 +725,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "returnable_items", - "type": "[`LineItem`](LineItem.mdx)[]", + "type": "[LineItem](LineItem.mdx)[]", "description": "The details of the line items that are returnable as part of the order, swaps, or claims", "optional": true, "defaultValue": "", @@ -734,7 +734,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "returns", - "type": "[`Return`](Return.mdx)[]", + "type": "[Return](Return.mdx)[]", "description": "The details of the returns created for the order.", "optional": false, "defaultValue": "", @@ -743,7 +743,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "sales_channel", - "type": "[`SalesChannel`](SalesChannel.mdx)", + "type": "[SalesChannel](SalesChannel.mdx)", "description": "The details of the sales channel this order belongs to.", "optional": false, "defaultValue": "", @@ -761,7 +761,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "shipping_address", - "type": "[`Address`](Address.mdx)", + "type": "[Address](Address.mdx)", "description": "The details of the shipping address associated with the order.", "optional": false, "defaultValue": "", @@ -779,7 +779,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "shipping_methods", - "type": "[`ShippingMethod`](ShippingMethod.mdx)[]", + "type": "[ShippingMethod](ShippingMethod.mdx)[]", "description": "The details of the shipping methods used in the order.", "optional": false, "defaultValue": "", @@ -806,7 +806,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "status", - "type": "[`OrderStatus`](../enums/OrderStatus.mdx)", + "type": "[OrderStatus](../enums/OrderStatus.mdx)", "description": "The order's status", "optional": false, "defaultValue": "pending", @@ -824,7 +824,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "swaps", - "type": "[`Swap`](Swap.mdx)[]", + "type": "[Swap](Swap.mdx)[]", "description": "The details of the swaps created for the order.", "optional": false, "defaultValue": "", @@ -889,7 +889,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "shipping_addresses", - "type": "[`Address`](Address.mdx)[]", + "type": "[Address](Address.mdx)[]", "description": "The details of the shipping addresses associated with the customer.", "optional": false, "defaultValue": "", @@ -933,7 +933,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "country", - "type": "``null`` \\| [`Country`](Country.mdx)", + "type": "``null`` \\| [Country](Country.mdx)", "description": "A country object.", "optional": false, "defaultValue": "", @@ -960,7 +960,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "customer", - "type": "``null`` \\| [`Customer`](Customer.mdx)", + "type": "``null`` \\| [Customer](Customer.mdx)", "description": "Available if the relation `customer` is expanded.", "optional": false, "defaultValue": "", @@ -1014,7 +1014,7 @@ A customer can make purchases in your store and manage their profile. }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/CustomerGroup.mdx b/www/apps/docs/content/references/entities/classes/CustomerGroup.mdx index c7aaeae400..b2aaee5a67 100644 --- a/www/apps/docs/content/references/entities/classes/CustomerGroup.mdx +++ b/www/apps/docs/content/references/entities/classes/CustomerGroup.mdx @@ -22,7 +22,7 @@ A customer group that can be used to organize customers into groups of similar t }, { "name": "customers", - "type": "[`Customer`](Customer.mdx)[]", + "type": "[Customer](Customer.mdx)[]", "description": "The details of the customers that belong to the customer group.", "optional": false, "defaultValue": "", @@ -30,7 +30,7 @@ A customer group that can be used to organize customers into groups of similar t "children": [ { "name": "billing_address", - "type": "[`Address`](Address.mdx)", + "type": "[Address](Address.mdx)", "description": "The details of the billing address associated with the customer.", "optional": false, "defaultValue": "", @@ -84,7 +84,7 @@ A customer group that can be used to organize customers into groups of similar t }, { "name": "groups", - "type": "[`CustomerGroup`](CustomerGroup.mdx)[]", + "type": "[CustomerGroup](CustomerGroup.mdx)[]", "description": "The customer groups the customer belongs to.", "optional": false, "defaultValue": "", @@ -120,7 +120,7 @@ A customer group that can be used to organize customers into groups of similar t }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -129,7 +129,7 @@ A customer group that can be used to organize customers into groups of similar t }, { "name": "orders", - "type": "[`Order`](Order.mdx)[]", + "type": "[Order](Order.mdx)[]", "description": "The details of the orders this customer placed.", "optional": false, "defaultValue": "", @@ -156,7 +156,7 @@ A customer group that can be used to organize customers into groups of similar t }, { "name": "shipping_addresses", - "type": "[`Address`](Address.mdx)[]", + "type": "[Address](Address.mdx)[]", "description": "The details of the shipping addresses associated with the customer.", "optional": false, "defaultValue": "", @@ -194,7 +194,7 @@ A customer group that can be used to organize customers into groups of similar t }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -212,7 +212,7 @@ A customer group that can be used to organize customers into groups of similar t }, { "name": "price_lists", - "type": "[`PriceList`](PriceList.mdx)[]", + "type": "[PriceList](PriceList.mdx)[]", "description": "The price lists that are associated with the customer group.", "optional": false, "defaultValue": "", @@ -229,7 +229,7 @@ A customer group that can be used to organize customers into groups of similar t }, { "name": "customer_groups", - "type": "[`CustomerGroup`](CustomerGroup.mdx)[]", + "type": "[CustomerGroup](CustomerGroup.mdx)[]", "description": "The details of the customer groups that the Price List can apply to.", "optional": false, "defaultValue": "", @@ -293,7 +293,7 @@ A customer group that can be used to organize customers into groups of similar t }, { "name": "prices", - "type": "[`MoneyAmount`](MoneyAmount.mdx)[]", + "type": "[MoneyAmount](MoneyAmount.mdx)[]", "description": "The prices that belong to the price list, represented as a Money Amount.", "optional": false, "defaultValue": "", @@ -311,7 +311,7 @@ A customer group that can be used to organize customers into groups of similar t }, { "name": "status", - "type": "[`PriceListStatus`](../enums/PriceListStatus.mdx)", + "type": "[PriceListStatus](../enums/PriceListStatus.mdx)", "description": "The status of the Price List", "optional": false, "defaultValue": "draft", @@ -320,7 +320,7 @@ A customer group that can be used to organize customers into groups of similar t }, { "name": "type", - "type": "[`PriceListType`](../enums/PriceListType.mdx)", + "type": "[PriceListType](../enums/PriceListType.mdx)", "description": "The type of Price List. This can be one of either `sale` or `override`.", "optional": false, "defaultValue": "sale", diff --git a/www/apps/docs/content/references/entities/classes/Discount.mdx b/www/apps/docs/content/references/entities/classes/Discount.mdx index d883f4992a..5d390d5bc2 100644 --- a/www/apps/docs/content/references/entities/classes/Discount.mdx +++ b/www/apps/docs/content/references/entities/classes/Discount.mdx @@ -76,7 +76,7 @@ A discount can be applied to a cart for promotional purposes. }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -85,7 +85,7 @@ A discount can be applied to a cart for promotional purposes. }, { "name": "parent_discount", - "type": "[`Discount`](Discount.mdx)", + "type": "[Discount](Discount.mdx)", "description": "The details of the parent discount that this discount was created from.", "optional": false, "defaultValue": "", @@ -156,7 +156,7 @@ A discount can be applied to a cart for promotional purposes. }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -165,7 +165,7 @@ A discount can be applied to a cart for promotional purposes. }, { "name": "parent_discount", - "type": "[`Discount`](Discount.mdx)", + "type": "[Discount](Discount.mdx)", "description": "The details of the parent discount that this discount was created from.", "optional": false, "defaultValue": "", @@ -183,7 +183,7 @@ A discount can be applied to a cart for promotional purposes. }, { "name": "regions", - "type": "[`Region`](Region.mdx)[]", + "type": "[Region](Region.mdx)[]", "description": "The details of the regions in which the Discount can be used.", "optional": false, "defaultValue": "", @@ -192,7 +192,7 @@ A discount can be applied to a cart for promotional purposes. }, { "name": "rule", - "type": "[`DiscountRule`](DiscountRule.mdx)", + "type": "[DiscountRule](DiscountRule.mdx)", "description": "The details of the discount rule that defines how the discount will be applied to a cart..", "optional": false, "defaultValue": "", @@ -266,7 +266,7 @@ A discount can be applied to a cart for promotional purposes. }, { "name": "regions", - "type": "[`Region`](Region.mdx)[]", + "type": "[Region](Region.mdx)[]", "description": "The details of the regions in which the Discount can be used.", "optional": false, "defaultValue": "", @@ -283,7 +283,7 @@ A discount can be applied to a cart for promotional purposes. }, { "name": "countries", - "type": "[`Country`](Country.mdx)[]", + "type": "[Country](Country.mdx)[]", "description": "The details of the countries included in this region.", "optional": false, "defaultValue": "", @@ -301,7 +301,7 @@ A discount can be applied to a cart for promotional purposes. }, { "name": "currency", - "type": "[`Currency`](Currency.mdx)", + "type": "[Currency](Currency.mdx)", "description": "The details of the currency used in the region.", "optional": false, "defaultValue": "", @@ -328,7 +328,7 @@ A discount can be applied to a cart for promotional purposes. }, { "name": "fulfillment_providers", - "type": "[`FulfillmentProvider`](FulfillmentProvider.mdx)[]", + "type": "[FulfillmentProvider](FulfillmentProvider.mdx)[]", "description": "The details of the fulfillment providers that can be used to fulfill items of orders and similar resources in the region.", "optional": false, "defaultValue": "", @@ -365,7 +365,7 @@ A discount can be applied to a cart for promotional purposes. }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -383,7 +383,7 @@ A discount can be applied to a cart for promotional purposes. }, { "name": "payment_providers", - "type": "[`PaymentProvider`](PaymentProvider.mdx)[]", + "type": "[PaymentProvider](PaymentProvider.mdx)[]", "description": "The details of the payment providers that can be used to process payments in the region.", "optional": false, "defaultValue": "", @@ -401,7 +401,7 @@ A discount can be applied to a cart for promotional purposes. }, { "name": "tax_provider", - "type": "[`TaxProvider`](TaxProvider.mdx)", + "type": "[TaxProvider](TaxProvider.mdx)", "description": "The details of the tax provider used in the region.", "optional": false, "defaultValue": "", @@ -428,7 +428,7 @@ A discount can be applied to a cart for promotional purposes. }, { "name": "tax_rates", - "type": "``null`` \\| [`TaxRate`](TaxRate.mdx)[]", + "type": "``null`` \\| [TaxRate](TaxRate.mdx)[]", "description": "The details of the tax rates used in the region, aside from the default rate.", "optional": false, "defaultValue": "", @@ -448,7 +448,7 @@ A discount can be applied to a cart for promotional purposes. }, { "name": "rule", - "type": "[`DiscountRule`](DiscountRule.mdx)", + "type": "[DiscountRule](DiscountRule.mdx)", "description": "The details of the discount rule that defines how the discount will be applied to a cart..", "optional": false, "defaultValue": "", @@ -456,7 +456,7 @@ A discount can be applied to a cart for promotional purposes. "children": [ { "name": "allocation", - "type": "[`AllocationType`](../enums/AllocationType.mdx)", + "type": "[AllocationType](../enums/AllocationType.mdx)", "description": "The scope that the discount should apply to.", "optional": false, "defaultValue": "", @@ -465,7 +465,7 @@ A discount can be applied to a cart for promotional purposes. }, { "name": "conditions", - "type": "[`DiscountCondition`](DiscountCondition.mdx)[]", + "type": "[DiscountCondition](DiscountCondition.mdx)[]", "description": "The details of the discount conditions associated with the rule. They can be used to limit when the discount can be used.", "optional": false, "defaultValue": "", @@ -510,7 +510,7 @@ A discount can be applied to a cart for promotional purposes. }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -519,8 +519,8 @@ A discount can be applied to a cart for promotional purposes. }, { "name": "type", - "type": "[`DiscountRuleType`](../enums/DiscountRuleType.mdx)", - "description": "The type of the Discount, can be `fixed` for discounts that reduce the price by a fixed amount, `percentage` for percentage reductions or `free_shipping` for shipping vouchers.", + "type": "[DiscountRuleType](../enums/DiscountRuleType.mdx)", + "description": "The type of the Discount, can be `fixed` for discounts that reduce the price by a fixed amount, `percentage` for percentage reductions or `free\\_shipping` for shipping vouchers.", "optional": false, "defaultValue": "", "expandable": false, diff --git a/www/apps/docs/content/references/entities/classes/DiscountCondition.mdx b/www/apps/docs/content/references/entities/classes/DiscountCondition.mdx index 8f87541d9a..d82528883d 100644 --- a/www/apps/docs/content/references/entities/classes/DiscountCondition.mdx +++ b/www/apps/docs/content/references/entities/classes/DiscountCondition.mdx @@ -22,8 +22,8 @@ Holds rule conditions for when a discount is applicable }, { "name": "customer_groups", - "type": "[`CustomerGroup`](CustomerGroup.mdx)[]", - "description": "Customer groups associated with this condition if `type` is `customer_groups`.", + "type": "[CustomerGroup](CustomerGroup.mdx)[]", + "description": "Customer groups associated with this condition if `type` is `customer\\_groups`.", "optional": false, "defaultValue": "", "expandable": true, @@ -39,7 +39,7 @@ Holds rule conditions for when a discount is applicable }, { "name": "customers", - "type": "[`Customer`](Customer.mdx)[]", + "type": "[Customer](Customer.mdx)[]", "description": "The details of the customers that belong to the customer group.", "optional": false, "defaultValue": "", @@ -66,7 +66,7 @@ Holds rule conditions for when a discount is applicable }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -84,7 +84,7 @@ Holds rule conditions for when a discount is applicable }, { "name": "price_lists", - "type": "[`PriceList`](PriceList.mdx)[]", + "type": "[PriceList](PriceList.mdx)[]", "description": "The price lists that are associated with the customer group.", "optional": false, "defaultValue": "", @@ -113,7 +113,7 @@ Holds rule conditions for when a discount is applicable }, { "name": "discount_rule", - "type": "[`DiscountRule`](DiscountRule.mdx)", + "type": "[DiscountRule](DiscountRule.mdx)", "description": "The details of the discount rule associated with the condition.", "optional": false, "defaultValue": "", @@ -121,7 +121,7 @@ Holds rule conditions for when a discount is applicable "children": [ { "name": "allocation", - "type": "[`AllocationType`](../enums/AllocationType.mdx)", + "type": "[AllocationType](../enums/AllocationType.mdx)", "description": "The scope that the discount should apply to.", "optional": false, "defaultValue": "", @@ -130,7 +130,7 @@ Holds rule conditions for when a discount is applicable }, { "name": "conditions", - "type": "[`DiscountCondition`](DiscountCondition.mdx)[]", + "type": "[DiscountCondition](DiscountCondition.mdx)[]", "description": "The details of the discount conditions associated with the rule. They can be used to limit when the discount can be used.", "optional": false, "defaultValue": "", @@ -175,7 +175,7 @@ Holds rule conditions for when a discount is applicable }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -184,8 +184,8 @@ Holds rule conditions for when a discount is applicable }, { "name": "type", - "type": "[`DiscountRuleType`](../enums/DiscountRuleType.mdx)", - "description": "The type of the Discount, can be `fixed` for discounts that reduce the price by a fixed amount, `percentage` for percentage reductions or `free_shipping` for shipping vouchers.", + "type": "[DiscountRuleType](../enums/DiscountRuleType.mdx)", + "description": "The type of the Discount, can be `fixed` for discounts that reduce the price by a fixed amount, `percentage` for percentage reductions or `free\\_shipping` for shipping vouchers.", "optional": false, "defaultValue": "", "expandable": false, @@ -231,7 +231,7 @@ Holds rule conditions for when a discount is applicable }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -240,8 +240,8 @@ Holds rule conditions for when a discount is applicable }, { "name": "operator", - "type": "[`DiscountConditionOperator`](../enums/DiscountConditionOperator.mdx)", - "description": "The operator of the condition. `in` indicates that discountable resources are within the specified resources. `not_in` indicates that discountable resources are everything but the specified resources.", + "type": "[DiscountConditionOperator](../enums/DiscountConditionOperator.mdx)", + "description": "The operator of the condition. `in` indicates that discountable resources are within the specified resources. `not\\_in` indicates that discountable resources are everything but the specified resources.", "optional": false, "defaultValue": "", "expandable": false, @@ -268,8 +268,8 @@ Holds rule conditions for when a discount is applicable }, { "name": "product_collections", - "type": "[`ProductCollection`](ProductCollection.mdx)[]", - "description": "Product collections associated with this condition if `type` is `product_collections`.", + "type": "[ProductCollection](ProductCollection.mdx)[]", + "description": "Product collections associated with this condition if `type` is `product\\_collections`.", "optional": false, "defaultValue": "", "expandable": true, @@ -312,7 +312,7 @@ Holds rule conditions for when a discount is applicable }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -321,7 +321,7 @@ Holds rule conditions for when a discount is applicable }, { "name": "products", - "type": "[`Product`](Product.mdx)[]", + "type": "[Product](Product.mdx)[]", "description": "The details of the products that belong to this product collection.", "optional": false, "defaultValue": "", @@ -350,8 +350,8 @@ Holds rule conditions for when a discount is applicable }, { "name": "product_tags", - "type": "[`ProductTag`](ProductTag.mdx)[]", - "description": "Product tags associated with this condition if `type` is `product_tags`.", + "type": "[ProductTag](ProductTag.mdx)[]", + "description": "Product tags associated with this condition if `type` is `product\\_tags`.", "optional": false, "defaultValue": "", "expandable": true, @@ -385,7 +385,7 @@ Holds rule conditions for when a discount is applicable }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -414,8 +414,8 @@ Holds rule conditions for when a discount is applicable }, { "name": "product_types", - "type": "[`ProductType`](ProductType.mdx)[]", - "description": "Product types associated with this condition if `type` is `product_types`.", + "type": "[ProductType](ProductType.mdx)[]", + "description": "Product types associated with this condition if `type` is `product\\_types`.", "optional": false, "defaultValue": "", "expandable": true, @@ -449,7 +449,7 @@ Holds rule conditions for when a discount is applicable }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -478,7 +478,7 @@ Holds rule conditions for when a discount is applicable }, { "name": "products", - "type": "[`Product`](Product.mdx)[]", + "type": "[Product](Product.mdx)[]", "description": "products associated with this condition if `type` is `products`.", "optional": false, "defaultValue": "", @@ -486,7 +486,7 @@ Holds rule conditions for when a discount is applicable "children": [ { "name": "categories", - "type": "[`ProductCategory`](ProductCategory.mdx)[]", + "type": "[ProductCategory](ProductCategory.mdx)[]", "description": "The details of the product categories that this product belongs to.", "optional": false, "defaultValue": "", @@ -496,7 +496,7 @@ Holds rule conditions for when a discount is applicable }, { "name": "collection", - "type": "[`ProductCollection`](ProductCollection.mdx)", + "type": "[ProductCollection](ProductCollection.mdx)", "description": "The details of the product collection that the product belongs to.", "optional": false, "defaultValue": "", @@ -595,7 +595,7 @@ Holds rule conditions for when a discount is applicable }, { "name": "images", - "type": "[`Image`](Image.mdx)[]", + "type": "[Image](Image.mdx)[]", "description": "The details of the product's images.", "optional": false, "defaultValue": "", @@ -631,7 +631,7 @@ Holds rule conditions for when a discount is applicable }, { "name": "metadata", - "type": "``null`` \\| Record<`string`, `unknown`\\>", + "type": "``null`` \\| `Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -649,7 +649,7 @@ Holds rule conditions for when a discount is applicable }, { "name": "options", - "type": "[`ProductOption`](ProductOption.mdx)[]", + "type": "[ProductOption](ProductOption.mdx)[]", "description": "The details of the Product Options that are defined for the Product. The product's variants will have a unique combination of values of the product's options.", "optional": false, "defaultValue": "", @@ -667,7 +667,7 @@ Holds rule conditions for when a discount is applicable }, { "name": "profile", - "type": "[`ShippingProfile`](ShippingProfile.mdx)", + "type": "[ShippingProfile](ShippingProfile.mdx)", "description": "The details of the shipping profile that the product belongs to. The shipping profile has a set of defined shipping options that can be used to fulfill the product.", "optional": false, "defaultValue": "", @@ -685,7 +685,7 @@ Holds rule conditions for when a discount is applicable }, { "name": "profiles", - "type": "[`ShippingProfile`](ShippingProfile.mdx)[]", + "type": "[ShippingProfile](ShippingProfile.mdx)[]", "description": "Available if the relation `profiles` is expanded.", "optional": false, "defaultValue": "", @@ -694,7 +694,7 @@ Holds rule conditions for when a discount is applicable }, { "name": "sales_channels", - "type": "[`SalesChannel`](SalesChannel.mdx)[]", + "type": "[SalesChannel](SalesChannel.mdx)[]", "description": "The details of the sales channels this product is available in.", "optional": false, "defaultValue": "", @@ -703,7 +703,7 @@ Holds rule conditions for when a discount is applicable }, { "name": "status", - "type": "[`ProductStatus`](../enums/ProductStatus.mdx)", + "type": "[ProductStatus](../enums/ProductStatus.mdx)", "description": "The status of the product", "optional": false, "defaultValue": "draft", @@ -721,7 +721,7 @@ Holds rule conditions for when a discount is applicable }, { "name": "tags", - "type": "[`ProductTag`](ProductTag.mdx)[]", + "type": "[ProductTag](ProductTag.mdx)[]", "description": "The details of the product tags used in this product.", "optional": false, "defaultValue": "", @@ -748,7 +748,7 @@ Holds rule conditions for when a discount is applicable }, { "name": "type", - "type": "[`ProductType`](ProductType.mdx)", + "type": "[ProductType](ProductType.mdx)", "description": "The details of the product type that the product belongs to.", "optional": false, "defaultValue": "", @@ -775,7 +775,7 @@ Holds rule conditions for when a discount is applicable }, { "name": "variants", - "type": "[`ProductVariant`](ProductVariant.mdx)[]", + "type": "[ProductVariant](ProductVariant.mdx)[]", "description": "The details of the Product Variants that belong to the Product. Each will have a unique combination of values of the product's options.", "optional": false, "defaultValue": "", @@ -804,7 +804,7 @@ Holds rule conditions for when a discount is applicable }, { "name": "type", - "type": "[`DiscountConditionType`](../enums/DiscountConditionType.mdx)", + "type": "[DiscountConditionType](../enums/DiscountConditionType.mdx)", "description": "The type of the condition. The type affects the available resources associated with the condition. For example, if the type is `products`, that means the `products` relation will hold the products associated with this condition and other relations will be empty.", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/DiscountConditionCustomerGroup.mdx b/www/apps/docs/content/references/entities/classes/DiscountConditionCustomerGroup.mdx index d7786d8bf1..17e763a2ba 100644 --- a/www/apps/docs/content/references/entities/classes/DiscountConditionCustomerGroup.mdx +++ b/www/apps/docs/content/references/entities/classes/DiscountConditionCustomerGroup.mdx @@ -31,8 +31,8 @@ Associates a discount condition with a customer group }, { "name": "customer_group", - "type": "[`CustomerGroup`](CustomerGroup.mdx)", - "description": "Available if the relation `customer_group` is expanded.", + "type": "[CustomerGroup](CustomerGroup.mdx)", + "description": "Available if the relation `customer\\_group` is expanded.", "optional": true, "defaultValue": "", "expandable": false, @@ -48,7 +48,7 @@ Associates a discount condition with a customer group }, { "name": "customers", - "type": "[`Customer`](Customer.mdx)[]", + "type": "[Customer](Customer.mdx)[]", "description": "The details of the customers that belong to the customer group.", "optional": false, "defaultValue": "", @@ -75,7 +75,7 @@ Associates a discount condition with a customer group }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -93,7 +93,7 @@ Associates a discount condition with a customer group }, { "name": "price_lists", - "type": "[`PriceList`](PriceList.mdx)[]", + "type": "[PriceList](PriceList.mdx)[]", "description": "The price lists that are associated with the customer group.", "optional": false, "defaultValue": "", @@ -122,8 +122,8 @@ Associates a discount condition with a customer group }, { "name": "discount_condition", - "type": "[`DiscountCondition`](DiscountCondition.mdx)", - "description": "Available if the relation `discount_condition` is expanded.", + "type": "[DiscountCondition](DiscountCondition.mdx)", + "description": "Available if the relation `discount\\_condition` is expanded.", "optional": true, "defaultValue": "", "expandable": false, @@ -139,8 +139,8 @@ Associates a discount condition with a customer group }, { "name": "customer_groups", - "type": "[`CustomerGroup`](CustomerGroup.mdx)[]", - "description": "Customer groups associated with this condition if `type` is `customer_groups`.", + "type": "[CustomerGroup](CustomerGroup.mdx)[]", + "description": "Customer groups associated with this condition if `type` is `customer\\_groups`.", "optional": false, "defaultValue": "", "expandable": true, @@ -157,7 +157,7 @@ Associates a discount condition with a customer group }, { "name": "discount_rule", - "type": "[`DiscountRule`](DiscountRule.mdx)", + "type": "[DiscountRule](DiscountRule.mdx)", "description": "The details of the discount rule associated with the condition.", "optional": false, "defaultValue": "", @@ -184,7 +184,7 @@ Associates a discount condition with a customer group }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -193,8 +193,8 @@ Associates a discount condition with a customer group }, { "name": "operator", - "type": "[`DiscountConditionOperator`](../enums/DiscountConditionOperator.mdx)", - "description": "The operator of the condition. `in` indicates that discountable resources are within the specified resources. `not_in` indicates that discountable resources are everything but the specified resources.", + "type": "[DiscountConditionOperator](../enums/DiscountConditionOperator.mdx)", + "description": "The operator of the condition. `in` indicates that discountable resources are within the specified resources. `not\\_in` indicates that discountable resources are everything but the specified resources.", "optional": false, "defaultValue": "", "expandable": false, @@ -202,8 +202,8 @@ Associates a discount condition with a customer group }, { "name": "product_collections", - "type": "[`ProductCollection`](ProductCollection.mdx)[]", - "description": "Product collections associated with this condition if `type` is `product_collections`.", + "type": "[ProductCollection](ProductCollection.mdx)[]", + "description": "Product collections associated with this condition if `type` is `product\\_collections`.", "optional": false, "defaultValue": "", "expandable": true, @@ -211,8 +211,8 @@ Associates a discount condition with a customer group }, { "name": "product_tags", - "type": "[`ProductTag`](ProductTag.mdx)[]", - "description": "Product tags associated with this condition if `type` is `product_tags`.", + "type": "[ProductTag](ProductTag.mdx)[]", + "description": "Product tags associated with this condition if `type` is `product\\_tags`.", "optional": false, "defaultValue": "", "expandable": true, @@ -220,8 +220,8 @@ Associates a discount condition with a customer group }, { "name": "product_types", - "type": "[`ProductType`](ProductType.mdx)[]", - "description": "Product types associated with this condition if `type` is `product_types`.", + "type": "[ProductType](ProductType.mdx)[]", + "description": "Product types associated with this condition if `type` is `product\\_types`.", "optional": false, "defaultValue": "", "expandable": true, @@ -229,7 +229,7 @@ Associates a discount condition with a customer group }, { "name": "products", - "type": "[`Product`](Product.mdx)[]", + "type": "[Product](Product.mdx)[]", "description": "products associated with this condition if `type` is `products`.", "optional": false, "defaultValue": "", @@ -238,7 +238,7 @@ Associates a discount condition with a customer group }, { "name": "type", - "type": "[`DiscountConditionType`](../enums/DiscountConditionType.mdx)", + "type": "[DiscountConditionType](../enums/DiscountConditionType.mdx)", "description": "The type of the condition. The type affects the available resources associated with the condition. For example, if the type is `products`, that means the `products` relation will hold the products associated with this condition and other relations will be empty.", "optional": false, "defaultValue": "", @@ -258,7 +258,7 @@ Associates a discount condition with a customer group }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/DiscountConditionProduct.mdx b/www/apps/docs/content/references/entities/classes/DiscountConditionProduct.mdx index 19f64e32ec..b6107f921e 100644 --- a/www/apps/docs/content/references/entities/classes/DiscountConditionProduct.mdx +++ b/www/apps/docs/content/references/entities/classes/DiscountConditionProduct.mdx @@ -31,7 +31,7 @@ This represents the association between a discount condition and a product }, { "name": "discount_condition", - "type": "[`DiscountCondition`](DiscountCondition.mdx)", + "type": "[DiscountCondition](DiscountCondition.mdx)", "description": "The details of the discount condition.", "optional": true, "defaultValue": "", @@ -48,8 +48,8 @@ This represents the association between a discount condition and a product }, { "name": "customer_groups", - "type": "[`CustomerGroup`](CustomerGroup.mdx)[]", - "description": "Customer groups associated with this condition if `type` is `customer_groups`.", + "type": "[CustomerGroup](CustomerGroup.mdx)[]", + "description": "Customer groups associated with this condition if `type` is `customer\\_groups`.", "optional": false, "defaultValue": "", "expandable": true, @@ -66,7 +66,7 @@ This represents the association between a discount condition and a product }, { "name": "discount_rule", - "type": "[`DiscountRule`](DiscountRule.mdx)", + "type": "[DiscountRule](DiscountRule.mdx)", "description": "The details of the discount rule associated with the condition.", "optional": false, "defaultValue": "", @@ -93,7 +93,7 @@ This represents the association between a discount condition and a product }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -102,8 +102,8 @@ This represents the association between a discount condition and a product }, { "name": "operator", - "type": "[`DiscountConditionOperator`](../enums/DiscountConditionOperator.mdx)", - "description": "The operator of the condition. `in` indicates that discountable resources are within the specified resources. `not_in` indicates that discountable resources are everything but the specified resources.", + "type": "[DiscountConditionOperator](../enums/DiscountConditionOperator.mdx)", + "description": "The operator of the condition. `in` indicates that discountable resources are within the specified resources. `not\\_in` indicates that discountable resources are everything but the specified resources.", "optional": false, "defaultValue": "", "expandable": false, @@ -111,8 +111,8 @@ This represents the association between a discount condition and a product }, { "name": "product_collections", - "type": "[`ProductCollection`](ProductCollection.mdx)[]", - "description": "Product collections associated with this condition if `type` is `product_collections`.", + "type": "[ProductCollection](ProductCollection.mdx)[]", + "description": "Product collections associated with this condition if `type` is `product\\_collections`.", "optional": false, "defaultValue": "", "expandable": true, @@ -120,8 +120,8 @@ This represents the association between a discount condition and a product }, { "name": "product_tags", - "type": "[`ProductTag`](ProductTag.mdx)[]", - "description": "Product tags associated with this condition if `type` is `product_tags`.", + "type": "[ProductTag](ProductTag.mdx)[]", + "description": "Product tags associated with this condition if `type` is `product\\_tags`.", "optional": false, "defaultValue": "", "expandable": true, @@ -129,8 +129,8 @@ This represents the association between a discount condition and a product }, { "name": "product_types", - "type": "[`ProductType`](ProductType.mdx)[]", - "description": "Product types associated with this condition if `type` is `product_types`.", + "type": "[ProductType](ProductType.mdx)[]", + "description": "Product types associated with this condition if `type` is `product\\_types`.", "optional": false, "defaultValue": "", "expandable": true, @@ -138,7 +138,7 @@ This represents the association between a discount condition and a product }, { "name": "products", - "type": "[`Product`](Product.mdx)[]", + "type": "[Product](Product.mdx)[]", "description": "products associated with this condition if `type` is `products`.", "optional": false, "defaultValue": "", @@ -147,7 +147,7 @@ This represents the association between a discount condition and a product }, { "name": "type", - "type": "[`DiscountConditionType`](../enums/DiscountConditionType.mdx)", + "type": "[DiscountConditionType](../enums/DiscountConditionType.mdx)", "description": "The type of the condition. The type affects the available resources associated with the condition. For example, if the type is `products`, that means the `products` relation will hold the products associated with this condition and other relations will be empty.", "optional": false, "defaultValue": "", @@ -167,7 +167,7 @@ This represents the association between a discount condition and a product }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -176,7 +176,7 @@ This represents the association between a discount condition and a product }, { "name": "product", - "type": "[`Product`](Product.mdx)", + "type": "[Product](Product.mdx)", "description": "The details of the product.", "optional": true, "defaultValue": "", @@ -184,7 +184,7 @@ This represents the association between a discount condition and a product "children": [ { "name": "categories", - "type": "[`ProductCategory`](ProductCategory.mdx)[]", + "type": "[ProductCategory](ProductCategory.mdx)[]", "description": "The details of the product categories that this product belongs to.", "optional": false, "defaultValue": "", @@ -194,7 +194,7 @@ This represents the association between a discount condition and a product }, { "name": "collection", - "type": "[`ProductCollection`](ProductCollection.mdx)", + "type": "[ProductCollection](ProductCollection.mdx)", "description": "The details of the product collection that the product belongs to.", "optional": false, "defaultValue": "", @@ -293,7 +293,7 @@ This represents the association between a discount condition and a product }, { "name": "images", - "type": "[`Image`](Image.mdx)[]", + "type": "[Image](Image.mdx)[]", "description": "The details of the product's images.", "optional": false, "defaultValue": "", @@ -329,7 +329,7 @@ This represents the association between a discount condition and a product }, { "name": "metadata", - "type": "``null`` \\| Record<`string`, `unknown`\\>", + "type": "``null`` \\| `Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -347,7 +347,7 @@ This represents the association between a discount condition and a product }, { "name": "options", - "type": "[`ProductOption`](ProductOption.mdx)[]", + "type": "[ProductOption](ProductOption.mdx)[]", "description": "The details of the Product Options that are defined for the Product. The product's variants will have a unique combination of values of the product's options.", "optional": false, "defaultValue": "", @@ -365,7 +365,7 @@ This represents the association between a discount condition and a product }, { "name": "profile", - "type": "[`ShippingProfile`](ShippingProfile.mdx)", + "type": "[ShippingProfile](ShippingProfile.mdx)", "description": "The details of the shipping profile that the product belongs to. The shipping profile has a set of defined shipping options that can be used to fulfill the product.", "optional": false, "defaultValue": "", @@ -383,7 +383,7 @@ This represents the association between a discount condition and a product }, { "name": "profiles", - "type": "[`ShippingProfile`](ShippingProfile.mdx)[]", + "type": "[ShippingProfile](ShippingProfile.mdx)[]", "description": "Available if the relation `profiles` is expanded.", "optional": false, "defaultValue": "", @@ -392,7 +392,7 @@ This represents the association between a discount condition and a product }, { "name": "sales_channels", - "type": "[`SalesChannel`](SalesChannel.mdx)[]", + "type": "[SalesChannel](SalesChannel.mdx)[]", "description": "The details of the sales channels this product is available in.", "optional": false, "defaultValue": "", @@ -401,7 +401,7 @@ This represents the association between a discount condition and a product }, { "name": "status", - "type": "[`ProductStatus`](../enums/ProductStatus.mdx)", + "type": "[ProductStatus](../enums/ProductStatus.mdx)", "description": "The status of the product", "optional": false, "defaultValue": "draft", @@ -419,7 +419,7 @@ This represents the association between a discount condition and a product }, { "name": "tags", - "type": "[`ProductTag`](ProductTag.mdx)[]", + "type": "[ProductTag](ProductTag.mdx)[]", "description": "The details of the product tags used in this product.", "optional": false, "defaultValue": "", @@ -446,7 +446,7 @@ This represents the association between a discount condition and a product }, { "name": "type", - "type": "[`ProductType`](ProductType.mdx)", + "type": "[ProductType](ProductType.mdx)", "description": "The details of the product type that the product belongs to.", "optional": false, "defaultValue": "", @@ -473,7 +473,7 @@ This represents the association between a discount condition and a product }, { "name": "variants", - "type": "[`ProductVariant`](ProductVariant.mdx)[]", + "type": "[ProductVariant](ProductVariant.mdx)[]", "description": "The details of the Product Variants that belong to the Product. Each will have a unique combination of values of the product's options.", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/DiscountConditionProductCollection.mdx b/www/apps/docs/content/references/entities/classes/DiscountConditionProductCollection.mdx index 33d143c8a4..ed6ac0f3f5 100644 --- a/www/apps/docs/content/references/entities/classes/DiscountConditionProductCollection.mdx +++ b/www/apps/docs/content/references/entities/classes/DiscountConditionProductCollection.mdx @@ -31,7 +31,7 @@ This represents the association between a discount condition and a product colle }, { "name": "discount_condition", - "type": "[`DiscountCondition`](DiscountCondition.mdx)", + "type": "[DiscountCondition](DiscountCondition.mdx)", "description": "The details of the discount condition.", "optional": true, "defaultValue": "", @@ -48,8 +48,8 @@ This represents the association between a discount condition and a product colle }, { "name": "customer_groups", - "type": "[`CustomerGroup`](CustomerGroup.mdx)[]", - "description": "Customer groups associated with this condition if `type` is `customer_groups`.", + "type": "[CustomerGroup](CustomerGroup.mdx)[]", + "description": "Customer groups associated with this condition if `type` is `customer\\_groups`.", "optional": false, "defaultValue": "", "expandable": true, @@ -66,7 +66,7 @@ This represents the association between a discount condition and a product colle }, { "name": "discount_rule", - "type": "[`DiscountRule`](DiscountRule.mdx)", + "type": "[DiscountRule](DiscountRule.mdx)", "description": "The details of the discount rule associated with the condition.", "optional": false, "defaultValue": "", @@ -93,7 +93,7 @@ This represents the association between a discount condition and a product colle }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -102,8 +102,8 @@ This represents the association between a discount condition and a product colle }, { "name": "operator", - "type": "[`DiscountConditionOperator`](../enums/DiscountConditionOperator.mdx)", - "description": "The operator of the condition. `in` indicates that discountable resources are within the specified resources. `not_in` indicates that discountable resources are everything but the specified resources.", + "type": "[DiscountConditionOperator](../enums/DiscountConditionOperator.mdx)", + "description": "The operator of the condition. `in` indicates that discountable resources are within the specified resources. `not\\_in` indicates that discountable resources are everything but the specified resources.", "optional": false, "defaultValue": "", "expandable": false, @@ -111,8 +111,8 @@ This represents the association between a discount condition and a product colle }, { "name": "product_collections", - "type": "[`ProductCollection`](ProductCollection.mdx)[]", - "description": "Product collections associated with this condition if `type` is `product_collections`.", + "type": "[ProductCollection](ProductCollection.mdx)[]", + "description": "Product collections associated with this condition if `type` is `product\\_collections`.", "optional": false, "defaultValue": "", "expandable": true, @@ -120,8 +120,8 @@ This represents the association between a discount condition and a product colle }, { "name": "product_tags", - "type": "[`ProductTag`](ProductTag.mdx)[]", - "description": "Product tags associated with this condition if `type` is `product_tags`.", + "type": "[ProductTag](ProductTag.mdx)[]", + "description": "Product tags associated with this condition if `type` is `product\\_tags`.", "optional": false, "defaultValue": "", "expandable": true, @@ -129,8 +129,8 @@ This represents the association between a discount condition and a product colle }, { "name": "product_types", - "type": "[`ProductType`](ProductType.mdx)[]", - "description": "Product types associated with this condition if `type` is `product_types`.", + "type": "[ProductType](ProductType.mdx)[]", + "description": "Product types associated with this condition if `type` is `product\\_types`.", "optional": false, "defaultValue": "", "expandable": true, @@ -138,7 +138,7 @@ This represents the association between a discount condition and a product colle }, { "name": "products", - "type": "[`Product`](Product.mdx)[]", + "type": "[Product](Product.mdx)[]", "description": "products associated with this condition if `type` is `products`.", "optional": false, "defaultValue": "", @@ -147,7 +147,7 @@ This represents the association between a discount condition and a product colle }, { "name": "type", - "type": "[`DiscountConditionType`](../enums/DiscountConditionType.mdx)", + "type": "[DiscountConditionType](../enums/DiscountConditionType.mdx)", "description": "The type of the condition. The type affects the available resources associated with the condition. For example, if the type is `products`, that means the `products` relation will hold the products associated with this condition and other relations will be empty.", "optional": false, "defaultValue": "", @@ -167,7 +167,7 @@ This represents the association between a discount condition and a product colle }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -176,7 +176,7 @@ This represents the association between a discount condition and a product colle }, { "name": "product_collection", - "type": "[`ProductCollection`](ProductCollection.mdx)", + "type": "[ProductCollection](ProductCollection.mdx)", "description": "The details of the product collection.", "optional": true, "defaultValue": "", @@ -220,7 +220,7 @@ This represents the association between a discount condition and a product colle }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -229,7 +229,7 @@ This represents the association between a discount condition and a product colle }, { "name": "products", - "type": "[`Product`](Product.mdx)[]", + "type": "[Product](Product.mdx)[]", "description": "The details of the products that belong to this product collection.", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/DiscountConditionProductTag.mdx b/www/apps/docs/content/references/entities/classes/DiscountConditionProductTag.mdx index 5bf6d9b2b7..6534b84057 100644 --- a/www/apps/docs/content/references/entities/classes/DiscountConditionProductTag.mdx +++ b/www/apps/docs/content/references/entities/classes/DiscountConditionProductTag.mdx @@ -31,7 +31,7 @@ This represents the association between a discount condition and a product tag }, { "name": "discount_condition", - "type": "[`DiscountCondition`](DiscountCondition.mdx)", + "type": "[DiscountCondition](DiscountCondition.mdx)", "description": "The details of the discount condition.", "optional": true, "defaultValue": "", @@ -48,8 +48,8 @@ This represents the association between a discount condition and a product tag }, { "name": "customer_groups", - "type": "[`CustomerGroup`](CustomerGroup.mdx)[]", - "description": "Customer groups associated with this condition if `type` is `customer_groups`.", + "type": "[CustomerGroup](CustomerGroup.mdx)[]", + "description": "Customer groups associated with this condition if `type` is `customer\\_groups`.", "optional": false, "defaultValue": "", "expandable": true, @@ -66,7 +66,7 @@ This represents the association between a discount condition and a product tag }, { "name": "discount_rule", - "type": "[`DiscountRule`](DiscountRule.mdx)", + "type": "[DiscountRule](DiscountRule.mdx)", "description": "The details of the discount rule associated with the condition.", "optional": false, "defaultValue": "", @@ -93,7 +93,7 @@ This represents the association between a discount condition and a product tag }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -102,8 +102,8 @@ This represents the association between a discount condition and a product tag }, { "name": "operator", - "type": "[`DiscountConditionOperator`](../enums/DiscountConditionOperator.mdx)", - "description": "The operator of the condition. `in` indicates that discountable resources are within the specified resources. `not_in` indicates that discountable resources are everything but the specified resources.", + "type": "[DiscountConditionOperator](../enums/DiscountConditionOperator.mdx)", + "description": "The operator of the condition. `in` indicates that discountable resources are within the specified resources. `not\\_in` indicates that discountable resources are everything but the specified resources.", "optional": false, "defaultValue": "", "expandable": false, @@ -111,8 +111,8 @@ This represents the association between a discount condition and a product tag }, { "name": "product_collections", - "type": "[`ProductCollection`](ProductCollection.mdx)[]", - "description": "Product collections associated with this condition if `type` is `product_collections`.", + "type": "[ProductCollection](ProductCollection.mdx)[]", + "description": "Product collections associated with this condition if `type` is `product\\_collections`.", "optional": false, "defaultValue": "", "expandable": true, @@ -120,8 +120,8 @@ This represents the association between a discount condition and a product tag }, { "name": "product_tags", - "type": "[`ProductTag`](ProductTag.mdx)[]", - "description": "Product tags associated with this condition if `type` is `product_tags`.", + "type": "[ProductTag](ProductTag.mdx)[]", + "description": "Product tags associated with this condition if `type` is `product\\_tags`.", "optional": false, "defaultValue": "", "expandable": true, @@ -129,8 +129,8 @@ This represents the association between a discount condition and a product tag }, { "name": "product_types", - "type": "[`ProductType`](ProductType.mdx)[]", - "description": "Product types associated with this condition if `type` is `product_types`.", + "type": "[ProductType](ProductType.mdx)[]", + "description": "Product types associated with this condition if `type` is `product\\_types`.", "optional": false, "defaultValue": "", "expandable": true, @@ -138,7 +138,7 @@ This represents the association between a discount condition and a product tag }, { "name": "products", - "type": "[`Product`](Product.mdx)[]", + "type": "[Product](Product.mdx)[]", "description": "products associated with this condition if `type` is `products`.", "optional": false, "defaultValue": "", @@ -147,7 +147,7 @@ This represents the association between a discount condition and a product tag }, { "name": "type", - "type": "[`DiscountConditionType`](../enums/DiscountConditionType.mdx)", + "type": "[DiscountConditionType](../enums/DiscountConditionType.mdx)", "description": "The type of the condition. The type affects the available resources associated with the condition. For example, if the type is `products`, that means the `products` relation will hold the products associated with this condition and other relations will be empty.", "optional": false, "defaultValue": "", @@ -167,7 +167,7 @@ This represents the association between a discount condition and a product tag }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -176,7 +176,7 @@ This represents the association between a discount condition and a product tag }, { "name": "product_tag", - "type": "[`ProductTag`](ProductTag.mdx)", + "type": "[ProductTag](ProductTag.mdx)", "description": "The details of the product tag.", "optional": true, "defaultValue": "", @@ -211,7 +211,7 @@ This represents the association between a discount condition and a product tag }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/DiscountConditionProductType.mdx b/www/apps/docs/content/references/entities/classes/DiscountConditionProductType.mdx index a44ded9096..e6309294a9 100644 --- a/www/apps/docs/content/references/entities/classes/DiscountConditionProductType.mdx +++ b/www/apps/docs/content/references/entities/classes/DiscountConditionProductType.mdx @@ -31,7 +31,7 @@ This represents the association between a discount condition and a product type }, { "name": "discount_condition", - "type": "[`DiscountCondition`](DiscountCondition.mdx)", + "type": "[DiscountCondition](DiscountCondition.mdx)", "description": "The details of the discount condition.", "optional": true, "defaultValue": "", @@ -48,8 +48,8 @@ This represents the association between a discount condition and a product type }, { "name": "customer_groups", - "type": "[`CustomerGroup`](CustomerGroup.mdx)[]", - "description": "Customer groups associated with this condition if `type` is `customer_groups`.", + "type": "[CustomerGroup](CustomerGroup.mdx)[]", + "description": "Customer groups associated with this condition if `type` is `customer\\_groups`.", "optional": false, "defaultValue": "", "expandable": true, @@ -66,7 +66,7 @@ This represents the association between a discount condition and a product type }, { "name": "discount_rule", - "type": "[`DiscountRule`](DiscountRule.mdx)", + "type": "[DiscountRule](DiscountRule.mdx)", "description": "The details of the discount rule associated with the condition.", "optional": false, "defaultValue": "", @@ -93,7 +93,7 @@ This represents the association between a discount condition and a product type }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -102,8 +102,8 @@ This represents the association between a discount condition and a product type }, { "name": "operator", - "type": "[`DiscountConditionOperator`](../enums/DiscountConditionOperator.mdx)", - "description": "The operator of the condition. `in` indicates that discountable resources are within the specified resources. `not_in` indicates that discountable resources are everything but the specified resources.", + "type": "[DiscountConditionOperator](../enums/DiscountConditionOperator.mdx)", + "description": "The operator of the condition. `in` indicates that discountable resources are within the specified resources. `not\\_in` indicates that discountable resources are everything but the specified resources.", "optional": false, "defaultValue": "", "expandable": false, @@ -111,8 +111,8 @@ This represents the association between a discount condition and a product type }, { "name": "product_collections", - "type": "[`ProductCollection`](ProductCollection.mdx)[]", - "description": "Product collections associated with this condition if `type` is `product_collections`.", + "type": "[ProductCollection](ProductCollection.mdx)[]", + "description": "Product collections associated with this condition if `type` is `product\\_collections`.", "optional": false, "defaultValue": "", "expandable": true, @@ -120,8 +120,8 @@ This represents the association between a discount condition and a product type }, { "name": "product_tags", - "type": "[`ProductTag`](ProductTag.mdx)[]", - "description": "Product tags associated with this condition if `type` is `product_tags`.", + "type": "[ProductTag](ProductTag.mdx)[]", + "description": "Product tags associated with this condition if `type` is `product\\_tags`.", "optional": false, "defaultValue": "", "expandable": true, @@ -129,8 +129,8 @@ This represents the association between a discount condition and a product type }, { "name": "product_types", - "type": "[`ProductType`](ProductType.mdx)[]", - "description": "Product types associated with this condition if `type` is `product_types`.", + "type": "[ProductType](ProductType.mdx)[]", + "description": "Product types associated with this condition if `type` is `product\\_types`.", "optional": false, "defaultValue": "", "expandable": true, @@ -138,7 +138,7 @@ This represents the association between a discount condition and a product type }, { "name": "products", - "type": "[`Product`](Product.mdx)[]", + "type": "[Product](Product.mdx)[]", "description": "products associated with this condition if `type` is `products`.", "optional": false, "defaultValue": "", @@ -147,7 +147,7 @@ This represents the association between a discount condition and a product type }, { "name": "type", - "type": "[`DiscountConditionType`](../enums/DiscountConditionType.mdx)", + "type": "[DiscountConditionType](../enums/DiscountConditionType.mdx)", "description": "The type of the condition. The type affects the available resources associated with the condition. For example, if the type is `products`, that means the `products` relation will hold the products associated with this condition and other relations will be empty.", "optional": false, "defaultValue": "", @@ -167,7 +167,7 @@ This represents the association between a discount condition and a product type }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -176,7 +176,7 @@ This represents the association between a discount condition and a product type }, { "name": "product_type", - "type": "[`ProductType`](ProductType.mdx)", + "type": "[ProductType](ProductType.mdx)", "description": "The details of the product type.", "optional": true, "defaultValue": "", @@ -211,7 +211,7 @@ This represents the association between a discount condition and a product type }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/DiscountRule.mdx b/www/apps/docs/content/references/entities/classes/DiscountRule.mdx index 63ec989eee..c179fcba7b 100644 --- a/www/apps/docs/content/references/entities/classes/DiscountRule.mdx +++ b/www/apps/docs/content/references/entities/classes/DiscountRule.mdx @@ -13,7 +13,7 @@ A discount rule defines how a Discount is calculated when applied to a Cart. ", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -112,8 +112,8 @@ A discount rule defines how a Discount is calculated when applied to a Cart. }, { "name": "operator", - "type": "[`DiscountConditionOperator`](../enums/DiscountConditionOperator.mdx)", - "description": "The operator of the condition. `in` indicates that discountable resources are within the specified resources. `not_in` indicates that discountable resources are everything but the specified resources.", + "type": "[DiscountConditionOperator](../enums/DiscountConditionOperator.mdx)", + "description": "The operator of the condition. `in` indicates that discountable resources are within the specified resources. `not\\_in` indicates that discountable resources are everything but the specified resources.", "optional": false, "defaultValue": "", "expandable": false, @@ -121,8 +121,8 @@ A discount rule defines how a Discount is calculated when applied to a Cart. }, { "name": "product_collections", - "type": "[`ProductCollection`](ProductCollection.mdx)[]", - "description": "Product collections associated with this condition if `type` is `product_collections`.", + "type": "[ProductCollection](ProductCollection.mdx)[]", + "description": "Product collections associated with this condition if `type` is `product\\_collections`.", "optional": false, "defaultValue": "", "expandable": true, @@ -130,8 +130,8 @@ A discount rule defines how a Discount is calculated when applied to a Cart. }, { "name": "product_tags", - "type": "[`ProductTag`](ProductTag.mdx)[]", - "description": "Product tags associated with this condition if `type` is `product_tags`.", + "type": "[ProductTag](ProductTag.mdx)[]", + "description": "Product tags associated with this condition if `type` is `product\\_tags`.", "optional": false, "defaultValue": "", "expandable": true, @@ -139,8 +139,8 @@ A discount rule defines how a Discount is calculated when applied to a Cart. }, { "name": "product_types", - "type": "[`ProductType`](ProductType.mdx)[]", - "description": "Product types associated with this condition if `type` is `product_types`.", + "type": "[ProductType](ProductType.mdx)[]", + "description": "Product types associated with this condition if `type` is `product\\_types`.", "optional": false, "defaultValue": "", "expandable": true, @@ -148,7 +148,7 @@ A discount rule defines how a Discount is calculated when applied to a Cart. }, { "name": "products", - "type": "[`Product`](Product.mdx)[]", + "type": "[Product](Product.mdx)[]", "description": "products associated with this condition if `type` is `products`.", "optional": false, "defaultValue": "", @@ -157,7 +157,7 @@ A discount rule defines how a Discount is calculated when applied to a Cart. }, { "name": "type", - "type": "[`DiscountConditionType`](../enums/DiscountConditionType.mdx)", + "type": "[DiscountConditionType](../enums/DiscountConditionType.mdx)", "description": "The type of the condition. The type affects the available resources associated with the condition. For example, if the type is `products`, that means the `products` relation will hold the products associated with this condition and other relations will be empty.", "optional": false, "defaultValue": "", @@ -213,7 +213,7 @@ A discount rule defines how a Discount is calculated when applied to a Cart. }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -222,8 +222,8 @@ A discount rule defines how a Discount is calculated when applied to a Cart. }, { "name": "type", - "type": "[`DiscountRuleType`](../enums/DiscountRuleType.mdx)", - "description": "The type of the Discount, can be `fixed` for discounts that reduce the price by a fixed amount, `percentage` for percentage reductions or `free_shipping` for shipping vouchers.", + "type": "[DiscountRuleType](../enums/DiscountRuleType.mdx)", + "description": "The type of the Discount, can be `fixed` for discounts that reduce the price by a fixed amount, `percentage` for percentage reductions or `free\\_shipping` for shipping vouchers.", "optional": false, "defaultValue": "", "expandable": false, diff --git a/www/apps/docs/content/references/entities/classes/DraftOrder.mdx b/www/apps/docs/content/references/entities/classes/DraftOrder.mdx index 87554dedc7..b43170d7dd 100644 --- a/www/apps/docs/content/references/entities/classes/DraftOrder.mdx +++ b/www/apps/docs/content/references/entities/classes/DraftOrder.mdx @@ -22,7 +22,7 @@ A draft order is created by an admin without direct involvement of the customer. }, { "name": "cart", - "type": "[`Cart`](Cart.mdx)", + "type": "[Cart](Cart.mdx)", "description": "The details of the cart associated with the draft order.", "optional": false, "defaultValue": "", @@ -85,7 +85,7 @@ A draft order is created by an admin without direct involvement of the customer. }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -103,7 +103,7 @@ A draft order is created by an admin without direct involvement of the customer. }, { "name": "order", - "type": "[`Order`](Order.mdx)", + "type": "[Order](Order.mdx)", "description": "The details of the order created from the draft order when its payment is captured.", "optional": false, "defaultValue": "", @@ -121,7 +121,7 @@ A draft order is created by an admin without direct involvement of the customer. }, { "name": "status", - "type": "[`DraftOrderStatus`](../enums/DraftOrderStatus.mdx)", + "type": "[DraftOrderStatus](../enums/DraftOrderStatus.mdx)", "description": "The status of the draft order. It's changed to `completed` when it's transformed to an order.", "optional": false, "defaultValue": "open", diff --git a/www/apps/docs/content/references/entities/classes/Fulfillment.mdx b/www/apps/docs/content/references/entities/classes/Fulfillment.mdx index d244c64c44..18ebba490b 100644 --- a/www/apps/docs/content/references/entities/classes/Fulfillment.mdx +++ b/www/apps/docs/content/references/entities/classes/Fulfillment.mdx @@ -22,7 +22,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "claim_order", - "type": "[`ClaimOrder`](ClaimOrder.mdx)", + "type": "[ClaimOrder](ClaimOrder.mdx)", "description": "The details of the claim that the fulfillment may belong to.", "optional": false, "defaultValue": "", @@ -30,7 +30,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm "children": [ { "name": "additional_items", - "type": "[`LineItem`](LineItem.mdx)[]", + "type": "[LineItem](LineItem.mdx)[]", "description": "The details of the new items to be shipped when the claim's type is `replace`", "optional": false, "defaultValue": "", @@ -48,7 +48,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "claim_items", - "type": "[`ClaimItem`](ClaimItem.mdx)[]", + "type": "[ClaimItem](ClaimItem.mdx)[]", "description": "The details of the items that should be replaced or refunded.", "optional": false, "defaultValue": "", @@ -75,7 +75,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "fulfillment_status", - "type": "[`ClaimFulfillmentStatus`](../enums/ClaimFulfillmentStatus.mdx)", + "type": "[ClaimFulfillmentStatus](../enums/ClaimFulfillmentStatus.mdx)", "description": "The claim's fulfillment status", "optional": false, "defaultValue": "not_fulfilled", @@ -84,7 +84,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "fulfillments", - "type": "[`Fulfillment`](Fulfillment.mdx)[]", + "type": "[Fulfillment](Fulfillment.mdx)[]", "description": "The fulfillments of the new items to be shipped", "optional": false, "defaultValue": "", @@ -111,7 +111,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -129,7 +129,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "order", - "type": "[`Order`](Order.mdx)", + "type": "[Order](Order.mdx)", "description": "The details of the order that this claim was created for.", "optional": false, "defaultValue": "", @@ -147,7 +147,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "payment_status", - "type": "[`ClaimPaymentStatus`](../enums/ClaimPaymentStatus.mdx)", + "type": "[ClaimPaymentStatus](../enums/ClaimPaymentStatus.mdx)", "description": "The status of the claim's payment", "optional": false, "defaultValue": "na", @@ -165,7 +165,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "return_order", - "type": "[`Return`](Return.mdx)", + "type": "[Return](Return.mdx)", "description": "The details of the return associated with the claim if the claim's type is `replace`.", "optional": false, "defaultValue": "", @@ -174,7 +174,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "shipping_address", - "type": "[`Address`](Address.mdx)", + "type": "[Address](Address.mdx)", "description": "The details of the address that new items should be shipped to.", "optional": false, "defaultValue": "", @@ -192,7 +192,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "shipping_methods", - "type": "[`ShippingMethod`](ShippingMethod.mdx)[]", + "type": "[ShippingMethod](ShippingMethod.mdx)[]", "description": "The details of the shipping methods that the claim order will be shipped with.", "optional": false, "defaultValue": "", @@ -201,7 +201,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "type", - "type": "[`ClaimType`](../enums/ClaimType.mdx)", + "type": "[ClaimType](../enums/ClaimType.mdx)", "description": "The claim's type", "optional": false, "defaultValue": "", @@ -239,7 +239,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "data", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "This contains all the data necessary for the Fulfillment provider to handle the fulfillment.", "optional": false, "defaultValue": "", @@ -266,7 +266,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "items", - "type": "[`FulfillmentItem`](FulfillmentItem.mdx)[]", + "type": "[FulfillmentItem](FulfillmentItem.mdx)[]", "description": "The Fulfillment Items in the Fulfillment. These hold information about how many of each Line Item has been fulfilled.", "optional": false, "defaultValue": "", @@ -274,7 +274,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm "children": [ { "name": "fulfillment", - "type": "[`Fulfillment`](Fulfillment.mdx)", + "type": "[Fulfillment](Fulfillment.mdx)", "description": "The details of the fulfillment.", "optional": false, "defaultValue": "", @@ -292,7 +292,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "item", - "type": "[`LineItem`](LineItem.mdx)", + "type": "[LineItem](LineItem.mdx)", "description": "The details of the line item.", "optional": false, "defaultValue": "", @@ -330,7 +330,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -348,7 +348,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "order", - "type": "[`Order`](Order.mdx)", + "type": "[Order](Order.mdx)", "description": "The details of the order that the fulfillment may belong to.", "optional": false, "defaultValue": "", @@ -356,7 +356,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm "children": [ { "name": "billing_address", - "type": "[`Address`](Address.mdx)", + "type": "[Address](Address.mdx)", "description": "The details of the billing address associated with the order.", "optional": false, "defaultValue": "", @@ -383,7 +383,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "cart", - "type": "[`Cart`](Cart.mdx)", + "type": "[Cart](Cart.mdx)", "description": "The details of the cart associated with the order.", "optional": false, "defaultValue": "", @@ -401,7 +401,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "claims", - "type": "[`ClaimOrder`](ClaimOrder.mdx)[]", + "type": "[ClaimOrder](ClaimOrder.mdx)[]", "description": "The details of the claims created for the order.", "optional": false, "defaultValue": "", @@ -419,7 +419,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "currency", - "type": "[`Currency`](Currency.mdx)", + "type": "[Currency](Currency.mdx)", "description": "The details of the currency used in the order.", "optional": false, "defaultValue": "", @@ -437,7 +437,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "customer", - "type": "[`Customer`](Customer.mdx)", + "type": "[Customer](Customer.mdx)", "description": "The details of the customer associated with the order.", "optional": false, "defaultValue": "", @@ -464,7 +464,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "discounts", - "type": "[`Discount`](Discount.mdx)[]", + "type": "[Discount](Discount.mdx)[]", "description": "The details of the discounts applied on the order.", "optional": false, "defaultValue": "", @@ -482,7 +482,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "draft_order", - "type": "[`DraftOrder`](DraftOrder.mdx)", + "type": "[DraftOrder](DraftOrder.mdx)", "description": "The details of the draft order this order was created from.", "optional": false, "defaultValue": "", @@ -500,7 +500,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "edits", - "type": "[`OrderEdit`](OrderEdit.mdx)[]", + "type": "[OrderEdit](OrderEdit.mdx)[]", "description": "The details of the order edits done on the order.", "optional": false, "defaultValue": "", @@ -527,7 +527,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "fulfillment_status", - "type": "[`FulfillmentStatus`](../enums/FulfillmentStatus.mdx)", + "type": "[FulfillmentStatus](../enums/FulfillmentStatus.mdx)", "description": "The order's fulfillment status", "optional": false, "defaultValue": "not_fulfilled", @@ -536,7 +536,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "fulfillments", - "type": "[`Fulfillment`](Fulfillment.mdx)[]", + "type": "[Fulfillment](Fulfillment.mdx)[]", "description": "The details of the fulfillments created for the order.", "optional": false, "defaultValue": "", @@ -563,7 +563,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "gift_card_transactions", - "type": "[`GiftCardTransaction`](GiftCardTransaction.mdx)[]", + "type": "[GiftCardTransaction](GiftCardTransaction.mdx)[]", "description": "The gift card transactions made in the order.", "optional": false, "defaultValue": "", @@ -572,7 +572,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "gift_cards", - "type": "[`GiftCard`](GiftCard.mdx)[]", + "type": "[GiftCard](GiftCard.mdx)[]", "description": "The details of the gift card used in the order.", "optional": false, "defaultValue": "", @@ -608,7 +608,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "items", - "type": "[`LineItem`](LineItem.mdx)[]", + "type": "[LineItem](LineItem.mdx)[]", "description": "The details of the line items that belong to the order.", "optional": false, "defaultValue": "", @@ -617,7 +617,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -653,7 +653,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "payment_status", - "type": "[`PaymentStatus`](../enums/PaymentStatus.mdx)", + "type": "[PaymentStatus](../enums/PaymentStatus.mdx)", "description": "The order's payment status", "optional": false, "defaultValue": "not_paid", @@ -662,7 +662,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "payments", - "type": "[`Payment`](Payment.mdx)[]", + "type": "[Payment](Payment.mdx)[]", "description": "The details of the payments used in the order.", "optional": false, "defaultValue": "", @@ -698,7 +698,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "refunds", - "type": "[`Refund`](Refund.mdx)[]", + "type": "[Refund](Refund.mdx)[]", "description": "The details of the refunds created for the order.", "optional": false, "defaultValue": "", @@ -707,7 +707,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "region", - "type": "[`Region`](Region.mdx)", + "type": "[Region](Region.mdx)", "description": "The details of the region this order was created in.", "optional": false, "defaultValue": "", @@ -725,7 +725,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "returnable_items", - "type": "[`LineItem`](LineItem.mdx)[]", + "type": "[LineItem](LineItem.mdx)[]", "description": "The details of the line items that are returnable as part of the order, swaps, or claims", "optional": true, "defaultValue": "", @@ -734,7 +734,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "returns", - "type": "[`Return`](Return.mdx)[]", + "type": "[Return](Return.mdx)[]", "description": "The details of the returns created for the order.", "optional": false, "defaultValue": "", @@ -743,7 +743,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "sales_channel", - "type": "[`SalesChannel`](SalesChannel.mdx)", + "type": "[SalesChannel](SalesChannel.mdx)", "description": "The details of the sales channel this order belongs to.", "optional": false, "defaultValue": "", @@ -761,7 +761,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "shipping_address", - "type": "[`Address`](Address.mdx)", + "type": "[Address](Address.mdx)", "description": "The details of the shipping address associated with the order.", "optional": false, "defaultValue": "", @@ -779,7 +779,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "shipping_methods", - "type": "[`ShippingMethod`](ShippingMethod.mdx)[]", + "type": "[ShippingMethod](ShippingMethod.mdx)[]", "description": "The details of the shipping methods used in the order.", "optional": false, "defaultValue": "", @@ -806,7 +806,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "status", - "type": "[`OrderStatus`](../enums/OrderStatus.mdx)", + "type": "[OrderStatus](../enums/OrderStatus.mdx)", "description": "The order's status", "optional": false, "defaultValue": "pending", @@ -824,7 +824,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "swaps", - "type": "[`Swap`](Swap.mdx)[]", + "type": "[Swap](Swap.mdx)[]", "description": "The details of the swaps created for the order.", "optional": false, "defaultValue": "", @@ -880,7 +880,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "provider", - "type": "[`FulfillmentProvider`](FulfillmentProvider.mdx)", + "type": "[FulfillmentProvider](FulfillmentProvider.mdx)", "description": "The details of the fulfillment provider responsible for handling the fulfillment.", "optional": false, "defaultValue": "", @@ -898,7 +898,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm { "name": "is_installed", "type": "`boolean`", - "description": "Whether the fulfillment service is installed in the current version. If a fulfillment service is no longer installed, the `is_installed` attribute is set to `false`.", + "description": "Whether the fulfillment service is installed in the current version. If a fulfillment service is no longer installed, the `is\\_installed` attribute is set to `false`.", "optional": false, "defaultValue": "true", "expandable": false, @@ -926,7 +926,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "swap", - "type": "[`Swap`](Swap.mdx)", + "type": "[Swap](Swap.mdx)", "description": "The details of the swap that the fulfillment may belong to.", "optional": false, "defaultValue": "", @@ -934,7 +934,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm "children": [ { "name": "additional_items", - "type": "[`LineItem`](LineItem.mdx)[]", + "type": "[LineItem](LineItem.mdx)[]", "description": "The details of the new products to send to the customer, represented as line items.", "optional": false, "defaultValue": "", @@ -961,7 +961,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "cart", - "type": "[`Cart`](Cart.mdx)", + "type": "[Cart](Cart.mdx)", "description": "The details of the cart that the customer uses to complete the swap.", "optional": false, "defaultValue": "", @@ -1015,7 +1015,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "fulfillment_status", - "type": "[`SwapFulfillmentStatus`](../enums/SwapFulfillmentStatus.mdx)", + "type": "[SwapFulfillmentStatus](../enums/SwapFulfillmentStatus.mdx)", "description": "The status of the Fulfillment of the Swap.", "optional": false, "defaultValue": "", @@ -1024,7 +1024,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "fulfillments", - "type": "[`Fulfillment`](Fulfillment.mdx)[]", + "type": "[Fulfillment](Fulfillment.mdx)[]", "description": "The details of the fulfillments that are used to send the new items to the customer.", "optional": false, "defaultValue": "", @@ -1051,7 +1051,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -1069,7 +1069,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "order", - "type": "[`Order`](Order.mdx)", + "type": "[Order](Order.mdx)", "description": "The details of the order that the swap belongs to.", "optional": false, "defaultValue": "", @@ -1087,8 +1087,8 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "payment", - "type": "[`Payment`](Payment.mdx)", - "description": "The details of the additional payment authorized by the customer when `difference_due` is positive.", + "type": "[Payment](Payment.mdx)", + "description": "The details of the additional payment authorized by the customer when `difference\\_due` is positive.", "optional": false, "defaultValue": "", "expandable": true, @@ -1096,7 +1096,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "payment_status", - "type": "[`SwapPaymentStatus`](../enums/SwapPaymentStatus.mdx)", + "type": "[SwapPaymentStatus](../enums/SwapPaymentStatus.mdx)", "description": "The status of the Payment of the Swap. The payment may either refer to the refund of an amount or the authorization of a new amount.", "optional": false, "defaultValue": "", @@ -1105,7 +1105,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "return_order", - "type": "[`Return`](Return.mdx)", + "type": "[Return](Return.mdx)", "description": "The details of the return that belongs to the swap, which holds the details on the items being returned.", "optional": false, "defaultValue": "", @@ -1114,7 +1114,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "shipping_address", - "type": "[`Address`](Address.mdx)", + "type": "[Address](Address.mdx)", "description": "The details of the shipping address that the new items should be sent to.", "optional": false, "defaultValue": "", @@ -1132,7 +1132,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "shipping_methods", - "type": "[`ShippingMethod`](ShippingMethod.mdx)[]", + "type": "[ShippingMethod](ShippingMethod.mdx)[]", "description": "The details of the shipping methods used to fulfill the additional items purchased.", "optional": false, "defaultValue": "", @@ -1161,7 +1161,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "tracking_links", - "type": "[`TrackingLink`](TrackingLink.mdx)[]", + "type": "[TrackingLink](TrackingLink.mdx)[]", "description": "The Tracking Links that can be used to track the status of the Fulfillment. These will usually be provided by the Fulfillment Provider.", "optional": false, "defaultValue": "", @@ -1187,7 +1187,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "fulfillment", - "type": "[`Fulfillment`](Fulfillment.mdx)", + "type": "[Fulfillment](Fulfillment.mdx)", "description": "The details of the fulfillment that the tracking link belongs to.", "optional": false, "defaultValue": "", @@ -1223,7 +1223,7 @@ A Fulfillment is created once an admin can prepare the purchased goods. Fulfillm }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/FulfillmentItem.mdx b/www/apps/docs/content/references/entities/classes/FulfillmentItem.mdx index 85f2bca2b3..0a06777c66 100644 --- a/www/apps/docs/content/references/entities/classes/FulfillmentItem.mdx +++ b/www/apps/docs/content/references/entities/classes/FulfillmentItem.mdx @@ -13,7 +13,7 @@ This represents the association between a Line Item and a Fulfillment. ", + "type": "`Record`", "description": "This contains all the data necessary for the Fulfillment provider to handle the fulfillment.", "optional": false, "defaultValue": "", @@ -84,7 +84,7 @@ This represents the association between a Line Item and a Fulfillment. }, { "name": "items", - "type": "[`FulfillmentItem`](FulfillmentItem.mdx)[]", + "type": "[FulfillmentItem](FulfillmentItem.mdx)[]", "description": "The Fulfillment Items in the Fulfillment. These hold information about how many of each Line Item has been fulfilled.", "optional": false, "defaultValue": "", @@ -102,7 +102,7 @@ This represents the association between a Line Item and a Fulfillment. }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -120,7 +120,7 @@ This represents the association between a Line Item and a Fulfillment. }, { "name": "order", - "type": "[`Order`](Order.mdx)", + "type": "[Order](Order.mdx)", "description": "The details of the order that the fulfillment may belong to.", "optional": false, "defaultValue": "", @@ -138,7 +138,7 @@ This represents the association between a Line Item and a Fulfillment. }, { "name": "provider", - "type": "[`FulfillmentProvider`](FulfillmentProvider.mdx)", + "type": "[FulfillmentProvider](FulfillmentProvider.mdx)", "description": "The details of the fulfillment provider responsible for handling the fulfillment.", "optional": false, "defaultValue": "", @@ -165,7 +165,7 @@ This represents the association between a Line Item and a Fulfillment. }, { "name": "swap", - "type": "[`Swap`](Swap.mdx)", + "type": "[Swap](Swap.mdx)", "description": "The details of the swap that the fulfillment may belong to.", "optional": false, "defaultValue": "", @@ -183,7 +183,7 @@ This represents the association between a Line Item and a Fulfillment. }, { "name": "tracking_links", - "type": "[`TrackingLink`](TrackingLink.mdx)[]", + "type": "[TrackingLink](TrackingLink.mdx)[]", "description": "The Tracking Links that can be used to track the status of the Fulfillment. These will usually be provided by the Fulfillment Provider.", "optional": false, "defaultValue": "", @@ -221,7 +221,7 @@ This represents the association between a Line Item and a Fulfillment. }, { "name": "item", - "type": "[`LineItem`](LineItem.mdx)", + "type": "[LineItem](LineItem.mdx)", "description": "The details of the line item.", "optional": false, "defaultValue": "", @@ -229,7 +229,7 @@ This represents the association between a Line Item and a Fulfillment. "children": [ { "name": "adjustments", - "type": "[`LineItemAdjustment`](LineItemAdjustment.mdx)[]", + "type": "[LineItemAdjustment](LineItemAdjustment.mdx)[]", "description": "The details of the item's adjustments, which are available when a discount is applied on the item.", "optional": false, "defaultValue": "", @@ -247,7 +247,7 @@ This represents the association between a Line Item and a Fulfillment. }, { "name": "cart", - "type": "[`Cart`](Cart.mdx)", + "type": "[Cart](Cart.mdx)", "description": "The details of the cart that the line item may belongs to.", "optional": false, "defaultValue": "", @@ -265,7 +265,7 @@ This represents the association between a Line Item and a Fulfillment. }, { "name": "claim_order", - "type": "[`ClaimOrder`](ClaimOrder.mdx)", + "type": "[ClaimOrder](ClaimOrder.mdx)", "description": "The details of the claim that the line item may belong to.", "optional": false, "defaultValue": "", @@ -347,7 +347,7 @@ This represents the association between a Line Item and a Fulfillment. { "name": "includes_tax", "type": "`boolean`", - "description": "Indicates if the line item unit_price include tax", + "description": "Indicates if the line item unit\\_price include tax", "optional": false, "defaultValue": "false", "expandable": false, @@ -374,7 +374,7 @@ This represents the association between a Line Item and a Fulfillment. }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -383,7 +383,7 @@ This represents the association between a Line Item and a Fulfillment. }, { "name": "order", - "type": "[`Order`](Order.mdx)", + "type": "[Order](Order.mdx)", "description": "The details of the order that the line item may belongs to.", "optional": false, "defaultValue": "", @@ -392,7 +392,7 @@ This represents the association between a Line Item and a Fulfillment. }, { "name": "order_edit", - "type": "``null`` \\| [`OrderEdit`](OrderEdit.mdx)", + "type": "``null`` \\| [OrderEdit](OrderEdit.mdx)", "description": "The details of the order edit.", "optional": true, "defaultValue": "", @@ -518,7 +518,7 @@ This represents the association between a Line Item and a Fulfillment. }, { "name": "swap", - "type": "[`Swap`](Swap.mdx)", + "type": "[Swap](Swap.mdx)", "description": "The details of the swap that the line item may belong to.", "optional": false, "defaultValue": "", @@ -536,7 +536,7 @@ This represents the association between a Line Item and a Fulfillment. }, { "name": "tax_lines", - "type": "[`LineItemTaxLine`](LineItemTaxLine.mdx)[]", + "type": "[LineItemTaxLine](LineItemTaxLine.mdx)[]", "description": "The details of the item's tax lines.", "optional": false, "defaultValue": "", @@ -599,7 +599,7 @@ This represents the association between a Line Item and a Fulfillment. }, { "name": "variant", - "type": "[`ProductVariant`](ProductVariant.mdx)", + "type": "[ProductVariant](ProductVariant.mdx)", "description": "The details of the product variant that this item was created from.", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/FulfillmentProvider.mdx b/www/apps/docs/content/references/entities/classes/FulfillmentProvider.mdx index c8d8a2baee..55bf7006c9 100644 --- a/www/apps/docs/content/references/entities/classes/FulfillmentProvider.mdx +++ b/www/apps/docs/content/references/entities/classes/FulfillmentProvider.mdx @@ -23,7 +23,7 @@ A fulfillment provider represents a fulfillment service installed in the Medusa { "name": "is_installed", "type": "`boolean`", - "description": "Whether the fulfillment service is installed in the current version. If a fulfillment service is no longer installed, the `is_installed` attribute is set to `false`.", + "description": "Whether the fulfillment service is installed in the current version. If a fulfillment service is no longer installed, the `is\\_installed` attribute is set to `false`.", "optional": false, "defaultValue": "true", "expandable": false, diff --git a/www/apps/docs/content/references/entities/classes/GiftCard.mdx b/www/apps/docs/content/references/entities/classes/GiftCard.mdx index db48bcb7a6..110f58f62c 100644 --- a/www/apps/docs/content/references/entities/classes/GiftCard.mdx +++ b/www/apps/docs/content/references/entities/classes/GiftCard.mdx @@ -76,7 +76,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -85,7 +85,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "order", - "type": "[`Order`](Order.mdx)", + "type": "[Order](Order.mdx)", "description": "The details of the order that the gift card was purchased in.", "optional": false, "defaultValue": "", @@ -93,7 +93,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay "children": [ { "name": "billing_address", - "type": "[`Address`](Address.mdx)", + "type": "[Address](Address.mdx)", "description": "The details of the billing address associated with the order.", "optional": false, "defaultValue": "", @@ -120,7 +120,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "cart", - "type": "[`Cart`](Cart.mdx)", + "type": "[Cart](Cart.mdx)", "description": "The details of the cart associated with the order.", "optional": false, "defaultValue": "", @@ -138,7 +138,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "claims", - "type": "[`ClaimOrder`](ClaimOrder.mdx)[]", + "type": "[ClaimOrder](ClaimOrder.mdx)[]", "description": "The details of the claims created for the order.", "optional": false, "defaultValue": "", @@ -156,7 +156,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "currency", - "type": "[`Currency`](Currency.mdx)", + "type": "[Currency](Currency.mdx)", "description": "The details of the currency used in the order.", "optional": false, "defaultValue": "", @@ -174,7 +174,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "customer", - "type": "[`Customer`](Customer.mdx)", + "type": "[Customer](Customer.mdx)", "description": "The details of the customer associated with the order.", "optional": false, "defaultValue": "", @@ -201,7 +201,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "discounts", - "type": "[`Discount`](Discount.mdx)[]", + "type": "[Discount](Discount.mdx)[]", "description": "The details of the discounts applied on the order.", "optional": false, "defaultValue": "", @@ -219,7 +219,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "draft_order", - "type": "[`DraftOrder`](DraftOrder.mdx)", + "type": "[DraftOrder](DraftOrder.mdx)", "description": "The details of the draft order this order was created from.", "optional": false, "defaultValue": "", @@ -237,7 +237,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "edits", - "type": "[`OrderEdit`](OrderEdit.mdx)[]", + "type": "[OrderEdit](OrderEdit.mdx)[]", "description": "The details of the order edits done on the order.", "optional": false, "defaultValue": "", @@ -264,7 +264,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "fulfillment_status", - "type": "[`FulfillmentStatus`](../enums/FulfillmentStatus.mdx)", + "type": "[FulfillmentStatus](../enums/FulfillmentStatus.mdx)", "description": "The order's fulfillment status", "optional": false, "defaultValue": "not_fulfilled", @@ -273,7 +273,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "fulfillments", - "type": "[`Fulfillment`](Fulfillment.mdx)[]", + "type": "[Fulfillment](Fulfillment.mdx)[]", "description": "The details of the fulfillments created for the order.", "optional": false, "defaultValue": "", @@ -300,7 +300,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "gift_card_transactions", - "type": "[`GiftCardTransaction`](GiftCardTransaction.mdx)[]", + "type": "[GiftCardTransaction](GiftCardTransaction.mdx)[]", "description": "The gift card transactions made in the order.", "optional": false, "defaultValue": "", @@ -309,7 +309,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "gift_cards", - "type": "[`GiftCard`](GiftCard.mdx)[]", + "type": "[GiftCard](GiftCard.mdx)[]", "description": "The details of the gift card used in the order.", "optional": false, "defaultValue": "", @@ -345,7 +345,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "items", - "type": "[`LineItem`](LineItem.mdx)[]", + "type": "[LineItem](LineItem.mdx)[]", "description": "The details of the line items that belong to the order.", "optional": false, "defaultValue": "", @@ -354,7 +354,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -390,7 +390,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "payment_status", - "type": "[`PaymentStatus`](../enums/PaymentStatus.mdx)", + "type": "[PaymentStatus](../enums/PaymentStatus.mdx)", "description": "The order's payment status", "optional": false, "defaultValue": "not_paid", @@ -399,7 +399,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "payments", - "type": "[`Payment`](Payment.mdx)[]", + "type": "[Payment](Payment.mdx)[]", "description": "The details of the payments used in the order.", "optional": false, "defaultValue": "", @@ -435,7 +435,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "refunds", - "type": "[`Refund`](Refund.mdx)[]", + "type": "[Refund](Refund.mdx)[]", "description": "The details of the refunds created for the order.", "optional": false, "defaultValue": "", @@ -444,7 +444,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "region", - "type": "[`Region`](Region.mdx)", + "type": "[Region](Region.mdx)", "description": "The details of the region this order was created in.", "optional": false, "defaultValue": "", @@ -462,7 +462,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "returnable_items", - "type": "[`LineItem`](LineItem.mdx)[]", + "type": "[LineItem](LineItem.mdx)[]", "description": "The details of the line items that are returnable as part of the order, swaps, or claims", "optional": true, "defaultValue": "", @@ -471,7 +471,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "returns", - "type": "[`Return`](Return.mdx)[]", + "type": "[Return](Return.mdx)[]", "description": "The details of the returns created for the order.", "optional": false, "defaultValue": "", @@ -480,7 +480,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "sales_channel", - "type": "[`SalesChannel`](SalesChannel.mdx)", + "type": "[SalesChannel](SalesChannel.mdx)", "description": "The details of the sales channel this order belongs to.", "optional": false, "defaultValue": "", @@ -498,7 +498,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "shipping_address", - "type": "[`Address`](Address.mdx)", + "type": "[Address](Address.mdx)", "description": "The details of the shipping address associated with the order.", "optional": false, "defaultValue": "", @@ -516,7 +516,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "shipping_methods", - "type": "[`ShippingMethod`](ShippingMethod.mdx)[]", + "type": "[ShippingMethod](ShippingMethod.mdx)[]", "description": "The details of the shipping methods used in the order.", "optional": false, "defaultValue": "", @@ -543,7 +543,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "status", - "type": "[`OrderStatus`](../enums/OrderStatus.mdx)", + "type": "[OrderStatus](../enums/OrderStatus.mdx)", "description": "The order's status", "optional": false, "defaultValue": "pending", @@ -561,7 +561,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "swaps", - "type": "[`Swap`](Swap.mdx)[]", + "type": "[Swap](Swap.mdx)[]", "description": "The details of the swaps created for the order.", "optional": false, "defaultValue": "", @@ -617,7 +617,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "region", - "type": "[`Region`](Region.mdx)", + "type": "[Region](Region.mdx)", "description": "The details of the region this gift card is available in.", "optional": false, "defaultValue": "", @@ -634,7 +634,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "countries", - "type": "[`Country`](Country.mdx)[]", + "type": "[Country](Country.mdx)[]", "description": "The details of the countries included in this region.", "optional": false, "defaultValue": "", @@ -652,7 +652,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "currency", - "type": "[`Currency`](Currency.mdx)", + "type": "[Currency](Currency.mdx)", "description": "The details of the currency used in the region.", "optional": false, "defaultValue": "", @@ -679,7 +679,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "fulfillment_providers", - "type": "[`FulfillmentProvider`](FulfillmentProvider.mdx)[]", + "type": "[FulfillmentProvider](FulfillmentProvider.mdx)[]", "description": "The details of the fulfillment providers that can be used to fulfill items of orders and similar resources in the region.", "optional": false, "defaultValue": "", @@ -716,7 +716,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -734,7 +734,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "payment_providers", - "type": "[`PaymentProvider`](PaymentProvider.mdx)[]", + "type": "[PaymentProvider](PaymentProvider.mdx)[]", "description": "The details of the payment providers that can be used to process payments in the region.", "optional": false, "defaultValue": "", @@ -752,7 +752,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "tax_provider", - "type": "[`TaxProvider`](TaxProvider.mdx)", + "type": "[TaxProvider](TaxProvider.mdx)", "description": "The details of the tax provider used in the region.", "optional": false, "defaultValue": "", @@ -779,7 +779,7 @@ Gift Cards are redeemable and represent a value that can be used towards the pay }, { "name": "tax_rates", - "type": "``null`` \\| [`TaxRate`](TaxRate.mdx)[]", + "type": "``null`` \\| [TaxRate](TaxRate.mdx)[]", "description": "The details of the tax rates used in the region, aside from the default rate.", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/GiftCardTransaction.mdx b/www/apps/docs/content/references/entities/classes/GiftCardTransaction.mdx index 7e82ae4aaf..1736183ede 100644 --- a/www/apps/docs/content/references/entities/classes/GiftCardTransaction.mdx +++ b/www/apps/docs/content/references/entities/classes/GiftCardTransaction.mdx @@ -31,7 +31,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "gift_card", - "type": "[`GiftCard`](GiftCard.mdx)", + "type": "[GiftCard](GiftCard.mdx)", "description": "The details of the gift card associated used in this transaction.", "optional": false, "defaultValue": "", @@ -102,7 +102,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -111,7 +111,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "order", - "type": "[`Order`](Order.mdx)", + "type": "[Order](Order.mdx)", "description": "The details of the order that the gift card was purchased in.", "optional": false, "defaultValue": "", @@ -129,7 +129,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "region", - "type": "[`Region`](Region.mdx)", + "type": "[Region](Region.mdx)", "description": "The details of the region this gift card is available in.", "optional": false, "defaultValue": "", @@ -203,7 +203,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "order", - "type": "[`Order`](Order.mdx)", + "type": "[Order](Order.mdx)", "description": "The details of the order that the gift card was used for payment.", "optional": false, "defaultValue": "", @@ -211,7 +211,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t "children": [ { "name": "billing_address", - "type": "[`Address`](Address.mdx)", + "type": "[Address](Address.mdx)", "description": "The details of the billing address associated with the order.", "optional": false, "defaultValue": "", @@ -238,7 +238,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "cart", - "type": "[`Cart`](Cart.mdx)", + "type": "[Cart](Cart.mdx)", "description": "The details of the cart associated with the order.", "optional": false, "defaultValue": "", @@ -256,7 +256,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "claims", - "type": "[`ClaimOrder`](ClaimOrder.mdx)[]", + "type": "[ClaimOrder](ClaimOrder.mdx)[]", "description": "The details of the claims created for the order.", "optional": false, "defaultValue": "", @@ -274,7 +274,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "currency", - "type": "[`Currency`](Currency.mdx)", + "type": "[Currency](Currency.mdx)", "description": "The details of the currency used in the order.", "optional": false, "defaultValue": "", @@ -292,7 +292,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "customer", - "type": "[`Customer`](Customer.mdx)", + "type": "[Customer](Customer.mdx)", "description": "The details of the customer associated with the order.", "optional": false, "defaultValue": "", @@ -319,7 +319,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "discounts", - "type": "[`Discount`](Discount.mdx)[]", + "type": "[Discount](Discount.mdx)[]", "description": "The details of the discounts applied on the order.", "optional": false, "defaultValue": "", @@ -337,7 +337,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "draft_order", - "type": "[`DraftOrder`](DraftOrder.mdx)", + "type": "[DraftOrder](DraftOrder.mdx)", "description": "The details of the draft order this order was created from.", "optional": false, "defaultValue": "", @@ -355,7 +355,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "edits", - "type": "[`OrderEdit`](OrderEdit.mdx)[]", + "type": "[OrderEdit](OrderEdit.mdx)[]", "description": "The details of the order edits done on the order.", "optional": false, "defaultValue": "", @@ -382,7 +382,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "fulfillment_status", - "type": "[`FulfillmentStatus`](../enums/FulfillmentStatus.mdx)", + "type": "[FulfillmentStatus](../enums/FulfillmentStatus.mdx)", "description": "The order's fulfillment status", "optional": false, "defaultValue": "not_fulfilled", @@ -391,7 +391,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "fulfillments", - "type": "[`Fulfillment`](Fulfillment.mdx)[]", + "type": "[Fulfillment](Fulfillment.mdx)[]", "description": "The details of the fulfillments created for the order.", "optional": false, "defaultValue": "", @@ -418,7 +418,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "gift_card_transactions", - "type": "[`GiftCardTransaction`](GiftCardTransaction.mdx)[]", + "type": "[GiftCardTransaction](GiftCardTransaction.mdx)[]", "description": "The gift card transactions made in the order.", "optional": false, "defaultValue": "", @@ -427,7 +427,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "gift_cards", - "type": "[`GiftCard`](GiftCard.mdx)[]", + "type": "[GiftCard](GiftCard.mdx)[]", "description": "The details of the gift card used in the order.", "optional": false, "defaultValue": "", @@ -463,7 +463,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "items", - "type": "[`LineItem`](LineItem.mdx)[]", + "type": "[LineItem](LineItem.mdx)[]", "description": "The details of the line items that belong to the order.", "optional": false, "defaultValue": "", @@ -472,7 +472,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -508,7 +508,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "payment_status", - "type": "[`PaymentStatus`](../enums/PaymentStatus.mdx)", + "type": "[PaymentStatus](../enums/PaymentStatus.mdx)", "description": "The order's payment status", "optional": false, "defaultValue": "not_paid", @@ -517,7 +517,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "payments", - "type": "[`Payment`](Payment.mdx)[]", + "type": "[Payment](Payment.mdx)[]", "description": "The details of the payments used in the order.", "optional": false, "defaultValue": "", @@ -553,7 +553,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "refunds", - "type": "[`Refund`](Refund.mdx)[]", + "type": "[Refund](Refund.mdx)[]", "description": "The details of the refunds created for the order.", "optional": false, "defaultValue": "", @@ -562,7 +562,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "region", - "type": "[`Region`](Region.mdx)", + "type": "[Region](Region.mdx)", "description": "The details of the region this order was created in.", "optional": false, "defaultValue": "", @@ -580,7 +580,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "returnable_items", - "type": "[`LineItem`](LineItem.mdx)[]", + "type": "[LineItem](LineItem.mdx)[]", "description": "The details of the line items that are returnable as part of the order, swaps, or claims", "optional": true, "defaultValue": "", @@ -589,7 +589,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "returns", - "type": "[`Return`](Return.mdx)[]", + "type": "[Return](Return.mdx)[]", "description": "The details of the returns created for the order.", "optional": false, "defaultValue": "", @@ -598,7 +598,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "sales_channel", - "type": "[`SalesChannel`](SalesChannel.mdx)", + "type": "[SalesChannel](SalesChannel.mdx)", "description": "The details of the sales channel this order belongs to.", "optional": false, "defaultValue": "", @@ -616,7 +616,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "shipping_address", - "type": "[`Address`](Address.mdx)", + "type": "[Address](Address.mdx)", "description": "The details of the shipping address associated with the order.", "optional": false, "defaultValue": "", @@ -634,7 +634,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "shipping_methods", - "type": "[`ShippingMethod`](ShippingMethod.mdx)[]", + "type": "[ShippingMethod](ShippingMethod.mdx)[]", "description": "The details of the shipping methods used in the order.", "optional": false, "defaultValue": "", @@ -661,7 +661,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "status", - "type": "[`OrderStatus`](../enums/OrderStatus.mdx)", + "type": "[OrderStatus](../enums/OrderStatus.mdx)", "description": "The order's status", "optional": false, "defaultValue": "pending", @@ -679,7 +679,7 @@ Gift Card Transactions are created once a Customer uses a Gift Card to pay for t }, { "name": "swaps", - "type": "[`Swap`](Swap.mdx)[]", + "type": "[Swap](Swap.mdx)[]", "description": "The details of the swaps created for the order.", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/IdempotencyKey.mdx b/www/apps/docs/content/references/entities/classes/IdempotencyKey.mdx index 0803bc97af..b889e467c9 100644 --- a/www/apps/docs/content/references/entities/classes/IdempotencyKey.mdx +++ b/www/apps/docs/content/references/entities/classes/IdempotencyKey.mdx @@ -67,7 +67,7 @@ Idempotency Key is used to continue a process in case of any failure that might }, { "name": "request_params", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "The parameters passed to the request", "optional": false, "defaultValue": "", @@ -85,7 +85,7 @@ Idempotency Key is used to continue a process in case of any failure that might }, { "name": "response_body", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "The response's body", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/Image.mdx b/www/apps/docs/content/references/entities/classes/Image.mdx index 7746677398..b4b27fd280 100644 --- a/www/apps/docs/content/references/entities/classes/Image.mdx +++ b/www/apps/docs/content/references/entities/classes/Image.mdx @@ -40,7 +40,7 @@ An Image is used to store details about uploaded images. Images are uploaded by }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/Invite.mdx b/www/apps/docs/content/references/entities/classes/Invite.mdx index 483a131db2..d92dc49a9e 100644 --- a/www/apps/docs/content/references/entities/classes/Invite.mdx +++ b/www/apps/docs/content/references/entities/classes/Invite.mdx @@ -58,7 +58,7 @@ An invite is created when an admin user invites a new user to join the store's t }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -67,7 +67,7 @@ An invite is created when an admin user invites a new user to join the store's t }, { "name": "role", - "type": "[`UserRoles`](../enums/UserRoles.mdx)", + "type": "[UserRoles](../enums/UserRoles.mdx)", "description": "The user's role. These roles don't change the privileges of the user.", "optional": false, "defaultValue": "member", diff --git a/www/apps/docs/content/references/entities/classes/LineItem.mdx b/www/apps/docs/content/references/entities/classes/LineItem.mdx index e09d9b361f..dfad6369f2 100644 --- a/www/apps/docs/content/references/entities/classes/LineItem.mdx +++ b/www/apps/docs/content/references/entities/classes/LineItem.mdx @@ -13,7 +13,7 @@ Line Items are created when a product is added to a Cart. When Line Items are pu ", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -167,7 +167,7 @@ Line Items are created when a product is added to a Cart. When Line Items are pu }, { "name": "order", - "type": "[`Order`](Order.mdx)", + "type": "[Order](Order.mdx)", "description": "The details of the order that the line item may belongs to.", "optional": false, "defaultValue": "", @@ -176,7 +176,7 @@ Line Items are created when a product is added to a Cart. When Line Items are pu }, { "name": "order_edit", - "type": "``null`` \\| [`OrderEdit`](OrderEdit.mdx)", + "type": "``null`` \\| [OrderEdit](OrderEdit.mdx)", "description": "The details of the order edit.", "optional": true, "defaultValue": "", @@ -302,7 +302,7 @@ Line Items are created when a product is added to a Cart. When Line Items are pu }, { "name": "swap", - "type": "[`Swap`](Swap.mdx)", + "type": "[Swap](Swap.mdx)", "description": "The details of the swap that the line item may belong to.", "optional": false, "defaultValue": "", @@ -320,7 +320,7 @@ Line Items are created when a product is added to a Cart. When Line Items are pu }, { "name": "tax_lines", - "type": "[`LineItemTaxLine`](LineItemTaxLine.mdx)[]", + "type": "[LineItemTaxLine](LineItemTaxLine.mdx)[]", "description": "The details of the item's tax lines.", "optional": false, "defaultValue": "", @@ -383,7 +383,7 @@ Line Items are created when a product is added to a Cart. When Line Items are pu }, { "name": "variant", - "type": "[`ProductVariant`](ProductVariant.mdx)", + "type": "[ProductVariant](ProductVariant.mdx)", "description": "The details of the product variant that this item was created from.", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/LineItemAdjustment.mdx b/www/apps/docs/content/references/entities/classes/LineItemAdjustment.mdx index 5f58fab75d..95b0d027c5 100644 --- a/www/apps/docs/content/references/entities/classes/LineItemAdjustment.mdx +++ b/www/apps/docs/content/references/entities/classes/LineItemAdjustment.mdx @@ -31,7 +31,7 @@ A Line Item Adjustment includes details on discounts applied on a line item. }, { "name": "discount", - "type": "[`Discount`](Discount.mdx)", + "type": "[Discount](Discount.mdx)", "description": "The details of the discount associated with the adjustment.", "optional": false, "defaultValue": "", @@ -58,7 +58,7 @@ A Line Item Adjustment includes details on discounts applied on a line item. }, { "name": "item", - "type": "[`LineItem`](LineItem.mdx)", + "type": "[LineItem](LineItem.mdx)", "description": "The details of the line item.", "optional": false, "defaultValue": "", @@ -76,7 +76,7 @@ A Line Item Adjustment includes details on discounts applied on a line item. }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/LineItemTaxLine.mdx b/www/apps/docs/content/references/entities/classes/LineItemTaxLine.mdx index af4673c09c..f055d4c171 100644 --- a/www/apps/docs/content/references/entities/classes/LineItemTaxLine.mdx +++ b/www/apps/docs/content/references/entities/classes/LineItemTaxLine.mdx @@ -40,7 +40,7 @@ A Line Item Tax Line represents the taxes applied on a line item. }, { "name": "item", - "type": "[`LineItem`](LineItem.mdx)", + "type": "[LineItem](LineItem.mdx)", "description": "The details of the line item.", "optional": false, "defaultValue": "", @@ -58,7 +58,7 @@ A Line Item Tax Line represents the taxes applied on a line item. }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/MoneyAmount.mdx b/www/apps/docs/content/references/entities/classes/MoneyAmount.mdx index 7cee56a567..7e69e4f825 100644 --- a/www/apps/docs/content/references/entities/classes/MoneyAmount.mdx +++ b/www/apps/docs/content/references/entities/classes/MoneyAmount.mdx @@ -31,7 +31,7 @@ A Money Amount represent a price amount, for example, a product variant's price }, { "name": "currency", - "type": "[`Currency`](Currency.mdx)", + "type": "[Currency](Currency.mdx)", "description": "The details of the currency that the money amount may belong to.", "optional": true, "defaultValue": "", @@ -132,7 +132,7 @@ A Money Amount represent a price amount, for example, a product variant's price }, { "name": "price_list", - "type": "``null`` \\| [`PriceList`](PriceList.mdx)", + "type": "``null`` \\| [PriceList](PriceList.mdx)", "description": "The details of the price list that the money amount may belong to.", "optional": false, "defaultValue": "", @@ -150,7 +150,7 @@ A Money Amount represent a price amount, for example, a product variant's price }, { "name": "region", - "type": "[`Region`](Region.mdx)", + "type": "[Region](Region.mdx)", "description": "The details of the region that the money amount may belong to.", "optional": true, "defaultValue": "", @@ -167,7 +167,7 @@ A Money Amount represent a price amount, for example, a product variant's price }, { "name": "countries", - "type": "[`Country`](Country.mdx)[]", + "type": "[Country](Country.mdx)[]", "description": "The details of the countries included in this region.", "optional": false, "defaultValue": "", @@ -185,7 +185,7 @@ A Money Amount represent a price amount, for example, a product variant's price }, { "name": "currency", - "type": "[`Currency`](Currency.mdx)", + "type": "[Currency](Currency.mdx)", "description": "The details of the currency used in the region.", "optional": false, "defaultValue": "", @@ -212,7 +212,7 @@ A Money Amount represent a price amount, for example, a product variant's price }, { "name": "fulfillment_providers", - "type": "[`FulfillmentProvider`](FulfillmentProvider.mdx)[]", + "type": "[FulfillmentProvider](FulfillmentProvider.mdx)[]", "description": "The details of the fulfillment providers that can be used to fulfill items of orders and similar resources in the region.", "optional": false, "defaultValue": "", @@ -249,7 +249,7 @@ A Money Amount represent a price amount, for example, a product variant's price }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -267,7 +267,7 @@ A Money Amount represent a price amount, for example, a product variant's price }, { "name": "payment_providers", - "type": "[`PaymentProvider`](PaymentProvider.mdx)[]", + "type": "[PaymentProvider](PaymentProvider.mdx)[]", "description": "The details of the payment providers that can be used to process payments in the region.", "optional": false, "defaultValue": "", @@ -285,7 +285,7 @@ A Money Amount represent a price amount, for example, a product variant's price }, { "name": "tax_provider", - "type": "[`TaxProvider`](TaxProvider.mdx)", + "type": "[TaxProvider](TaxProvider.mdx)", "description": "The details of the tax provider used in the region.", "optional": false, "defaultValue": "", @@ -312,7 +312,7 @@ A Money Amount represent a price amount, for example, a product variant's price }, { "name": "tax_rates", - "type": "``null`` \\| [`TaxRate`](TaxRate.mdx)[]", + "type": "``null`` \\| [TaxRate](TaxRate.mdx)[]", "description": "The details of the tax rates used in the region, aside from the default rate.", "optional": false, "defaultValue": "", @@ -350,7 +350,7 @@ A Money Amount represent a price amount, for example, a product variant's price }, { "name": "variant", - "type": "[`ProductVariant`](ProductVariant.mdx)", + "type": "[ProductVariant](ProductVariant.mdx)", "description": "The details of the product variant that the money amount may belong to.", "optional": false, "defaultValue": "", @@ -359,7 +359,7 @@ A Money Amount represent a price amount, for example, a product variant's price { "name": "allow_backorder", "type": "`boolean`", - "description": "Whether the Product Variant should be purchasable when `inventory_quantity` is 0.", + "description": "Whether the Product Variant should be purchasable when `inventory\\_quantity` is 0.", "optional": false, "defaultValue": "false", "expandable": false, @@ -430,7 +430,7 @@ A Money Amount represent a price amount, for example, a product variant's price }, { "name": "inventory_items", - "type": "[`ProductVariantInventoryItem`](ProductVariantInventoryItem.mdx)[]", + "type": "[ProductVariantInventoryItem](ProductVariantInventoryItem.mdx)[]", "description": "The details inventory items of the product variant.", "optional": false, "defaultValue": "", @@ -475,7 +475,7 @@ A Money Amount represent a price amount, for example, a product variant's price }, { "name": "metadata", - "type": "``null`` \\| Record<`string`, `unknown`\\>", + "type": "``null`` \\| `Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -493,7 +493,7 @@ A Money Amount represent a price amount, for example, a product variant's price }, { "name": "options", - "type": "[`ProductOptionValue`](ProductOptionValue.mdx)[]", + "type": "[ProductOptionValue](ProductOptionValue.mdx)[]", "description": "The details of the product options that this product variant defines values for.", "optional": false, "defaultValue": "", @@ -511,7 +511,7 @@ A Money Amount represent a price amount, for example, a product variant's price }, { "name": "prices", - "type": "[`MoneyAmount`](MoneyAmount.mdx)[]", + "type": "[MoneyAmount](MoneyAmount.mdx)[]", "description": "The details of the prices of the Product Variant, each represented as a Money Amount. Each Money Amount represents a price in a given currency or a specific Region.", "optional": false, "defaultValue": "", @@ -520,7 +520,7 @@ A Money Amount represent a price amount, for example, a product variant's price }, { "name": "product", - "type": "[`Product`](Product.mdx)", + "type": "[Product](Product.mdx)", "description": "The details of the product that the product variant belongs to.", "optional": false, "defaultValue": "", @@ -621,7 +621,7 @@ A Money Amount represent a price amount, for example, a product variant's price }, { "name": "variants", - "type": "[`ProductVariant`](ProductVariant.mdx)[]", + "type": "[ProductVariant](ProductVariant.mdx)[]", "description": "", "optional": false, "defaultValue": "", @@ -630,7 +630,7 @@ A Money Amount represent a price amount, for example, a product variant's price { "name": "allow_backorder", "type": "`boolean`", - "description": "Whether the Product Variant should be purchasable when `inventory_quantity` is 0.", + "description": "Whether the Product Variant should be purchasable when `inventory\\_quantity` is 0.", "optional": false, "defaultValue": "false", "expandable": false, @@ -701,7 +701,7 @@ A Money Amount represent a price amount, for example, a product variant's price }, { "name": "inventory_items", - "type": "[`ProductVariantInventoryItem`](ProductVariantInventoryItem.mdx)[]", + "type": "[ProductVariantInventoryItem](ProductVariantInventoryItem.mdx)[]", "description": "The details inventory items of the product variant.", "optional": false, "defaultValue": "", @@ -746,7 +746,7 @@ A Money Amount represent a price amount, for example, a product variant's price }, { "name": "metadata", - "type": "``null`` \\| Record<`string`, `unknown`\\>", + "type": "``null`` \\| `Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -764,7 +764,7 @@ A Money Amount represent a price amount, for example, a product variant's price }, { "name": "options", - "type": "[`ProductOptionValue`](ProductOptionValue.mdx)[]", + "type": "[ProductOptionValue](ProductOptionValue.mdx)[]", "description": "The details of the product options that this product variant defines values for.", "optional": false, "defaultValue": "", @@ -782,7 +782,7 @@ A Money Amount represent a price amount, for example, a product variant's price }, { "name": "prices", - "type": "[`MoneyAmount`](MoneyAmount.mdx)[]", + "type": "[MoneyAmount](MoneyAmount.mdx)[]", "description": "The details of the prices of the Product Variant, each represented as a Money Amount. Each Money Amount represents a price in a given currency or a specific Region.", "optional": false, "defaultValue": "", @@ -791,7 +791,7 @@ A Money Amount represent a price amount, for example, a product variant's price }, { "name": "product", - "type": "[`Product`](Product.mdx)", + "type": "[Product](Product.mdx)", "description": "The details of the product that the product variant belongs to.", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/Note.mdx b/www/apps/docs/content/references/entities/classes/Note.mdx index c22fd24e9d..edd7640be6 100644 --- a/www/apps/docs/content/references/entities/classes/Note.mdx +++ b/www/apps/docs/content/references/entities/classes/Note.mdx @@ -13,7 +13,7 @@ A Note is an element that can be used in association with different resources to ", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -102,7 +102,7 @@ A Note is an element that can be used in association with different resources to }, { "name": "role", - "type": "[`UserRoles`](../enums/UserRoles.mdx)", + "type": "[UserRoles](../enums/UserRoles.mdx)", "description": "The user's role. These roles don't provide any different privileges.", "optional": false, "defaultValue": "member", @@ -158,7 +158,7 @@ A Note is an element that can be used in association with different resources to }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/Notification.mdx b/www/apps/docs/content/references/entities/classes/Notification.mdx index cbb30f1e0e..be59026cea 100644 --- a/www/apps/docs/content/references/entities/classes/Notification.mdx +++ b/www/apps/docs/content/references/entities/classes/Notification.mdx @@ -22,7 +22,7 @@ A notification is an alert sent, typically to customers, using the installed Not }, { "name": "customer", - "type": "[`Customer`](Customer.mdx)", + "type": "[Customer](Customer.mdx)", "description": "The details of the customer that this notification was sent to.", "optional": false, "defaultValue": "", @@ -30,7 +30,7 @@ A notification is an alert sent, typically to customers, using the installed Not "children": [ { "name": "billing_address", - "type": "[`Address`](Address.mdx)", + "type": "[Address](Address.mdx)", "description": "The details of the billing address associated with the customer.", "optional": false, "defaultValue": "", @@ -84,7 +84,7 @@ A notification is an alert sent, typically to customers, using the installed Not }, { "name": "groups", - "type": "[`CustomerGroup`](CustomerGroup.mdx)[]", + "type": "[CustomerGroup](CustomerGroup.mdx)[]", "description": "The customer groups the customer belongs to.", "optional": false, "defaultValue": "", @@ -120,7 +120,7 @@ A notification is an alert sent, typically to customers, using the installed Not }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -129,7 +129,7 @@ A notification is an alert sent, typically to customers, using the installed Not }, { "name": "orders", - "type": "[`Order`](Order.mdx)[]", + "type": "[Order](Order.mdx)[]", "description": "The details of the orders this customer placed.", "optional": false, "defaultValue": "", @@ -156,7 +156,7 @@ A notification is an alert sent, typically to customers, using the installed Not }, { "name": "shipping_addresses", - "type": "[`Address`](Address.mdx)[]", + "type": "[Address](Address.mdx)[]", "description": "The details of the shipping addresses associated with the customer.", "optional": false, "defaultValue": "", @@ -185,7 +185,7 @@ A notification is an alert sent, typically to customers, using the installed Not }, { "name": "data", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "The data that the Notification was sent with. This contains all the data necessary for the Notification Provider to initiate a resend.", "optional": false, "defaultValue": "", @@ -221,7 +221,7 @@ A notification is an alert sent, typically to customers, using the installed Not }, { "name": "parent_notification", - "type": "[`Notification`](Notification.mdx)", + "type": "[Notification](Notification.mdx)", "description": "The details of the parent notification.", "optional": false, "defaultValue": "", @@ -238,7 +238,7 @@ A notification is an alert sent, typically to customers, using the installed Not }, { "name": "customer", - "type": "[`Customer`](Customer.mdx)", + "type": "[Customer](Customer.mdx)", "description": "The details of the customer that this notification was sent to.", "optional": false, "defaultValue": "", @@ -256,7 +256,7 @@ A notification is an alert sent, typically to customers, using the installed Not }, { "name": "data", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "The data that the Notification was sent with. This contains all the data necessary for the Notification Provider to initiate a resend.", "optional": false, "defaultValue": "", @@ -292,7 +292,7 @@ A notification is an alert sent, typically to customers, using the installed Not }, { "name": "parent_notification", - "type": "[`Notification`](Notification.mdx)", + "type": "[Notification](Notification.mdx)", "description": "The details of the parent notification.", "optional": false, "defaultValue": "", @@ -301,7 +301,7 @@ A notification is an alert sent, typically to customers, using the installed Not }, { "name": "provider", - "type": "[`NotificationProvider`](NotificationProvider.mdx)", + "type": "[NotificationProvider](NotificationProvider.mdx)", "description": "The notification provider used to send the notification.", "optional": false, "defaultValue": "", @@ -319,7 +319,7 @@ A notification is an alert sent, typically to customers, using the installed Not }, { "name": "resends", - "type": "[`Notification`](Notification.mdx)[]", + "type": "[Notification](Notification.mdx)[]", "description": "The details of all resends of the notification.", "optional": false, "defaultValue": "", @@ -366,7 +366,7 @@ A notification is an alert sent, typically to customers, using the installed Not }, { "name": "provider", - "type": "[`NotificationProvider`](NotificationProvider.mdx)", + "type": "[NotificationProvider](NotificationProvider.mdx)", "description": "The notification provider used to send the notification.", "optional": false, "defaultValue": "", @@ -384,7 +384,7 @@ A notification is an alert sent, typically to customers, using the installed Not { "name": "is_installed", "type": "`boolean`", - "description": "Whether the notification service is installed in the current version. If a notification service is no longer installed, the `is_installed` attribute is set to `false`.", + "description": "Whether the notification service is installed in the current version. If a notification service is no longer installed, the `is\\_installed` attribute is set to `false`.", "optional": false, "defaultValue": "true", "expandable": false, @@ -403,7 +403,7 @@ A notification is an alert sent, typically to customers, using the installed Not }, { "name": "resends", - "type": "[`Notification`](Notification.mdx)[]", + "type": "[Notification](Notification.mdx)[]", "description": "The details of all resends of the notification.", "optional": false, "defaultValue": "", @@ -420,7 +420,7 @@ A notification is an alert sent, typically to customers, using the installed Not }, { "name": "customer", - "type": "[`Customer`](Customer.mdx)", + "type": "[Customer](Customer.mdx)", "description": "The details of the customer that this notification was sent to.", "optional": false, "defaultValue": "", @@ -438,7 +438,7 @@ A notification is an alert sent, typically to customers, using the installed Not }, { "name": "data", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "The data that the Notification was sent with. This contains all the data necessary for the Notification Provider to initiate a resend.", "optional": false, "defaultValue": "", @@ -474,7 +474,7 @@ A notification is an alert sent, typically to customers, using the installed Not }, { "name": "parent_notification", - "type": "[`Notification`](Notification.mdx)", + "type": "[Notification](Notification.mdx)", "description": "The details of the parent notification.", "optional": false, "defaultValue": "", @@ -483,7 +483,7 @@ A notification is an alert sent, typically to customers, using the installed Not }, { "name": "provider", - "type": "[`NotificationProvider`](NotificationProvider.mdx)", + "type": "[NotificationProvider](NotificationProvider.mdx)", "description": "The notification provider used to send the notification.", "optional": false, "defaultValue": "", @@ -501,7 +501,7 @@ A notification is an alert sent, typically to customers, using the installed Not }, { "name": "resends", - "type": "[`Notification`](Notification.mdx)[]", + "type": "[Notification](Notification.mdx)[]", "description": "The details of all resends of the notification.", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/NotificationProvider.mdx b/www/apps/docs/content/references/entities/classes/NotificationProvider.mdx index de44f91b35..de9d359265 100644 --- a/www/apps/docs/content/references/entities/classes/NotificationProvider.mdx +++ b/www/apps/docs/content/references/entities/classes/NotificationProvider.mdx @@ -23,7 +23,7 @@ A notification provider represents a notification service installed in the Medus { "name": "is_installed", "type": "`boolean`", - "description": "Whether the notification service is installed in the current version. If a notification service is no longer installed, the `is_installed` attribute is set to `false`.", + "description": "Whether the notification service is installed in the current version. If a notification service is no longer installed, the `is\\_installed` attribute is set to `false`.", "optional": false, "defaultValue": "true", "expandable": false, diff --git a/www/apps/docs/content/references/entities/classes/Oauth.mdx b/www/apps/docs/content/references/entities/classes/Oauth.mdx index 7ce99a6fad..343e3cff04 100644 --- a/www/apps/docs/content/references/entities/classes/Oauth.mdx +++ b/www/apps/docs/content/references/entities/classes/Oauth.mdx @@ -20,7 +20,7 @@ import ParameterTypes from "@site/src/components/ParameterTypes" }, { "name": "data", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/Order.mdx b/www/apps/docs/content/references/entities/classes/Order.mdx index da523dd070..8bc66a31bb 100644 --- a/www/apps/docs/content/references/entities/classes/Order.mdx +++ b/www/apps/docs/content/references/entities/classes/Order.mdx @@ -13,7 +13,7 @@ An order is a purchase made by a customer. It holds details about payment and fu ", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -310,7 +310,7 @@ An order is a purchase made by a customer. It holds details about payment and fu }, { "name": "payment_status", - "type": "[`PaymentStatus`](../enums/PaymentStatus.mdx)", + "type": "[PaymentStatus](../enums/PaymentStatus.mdx)", "description": "The order's payment status", "optional": false, "defaultValue": "not_paid", @@ -319,7 +319,7 @@ An order is a purchase made by a customer. It holds details about payment and fu }, { "name": "payments", - "type": "[`Payment`](Payment.mdx)[]", + "type": "[Payment](Payment.mdx)[]", "description": "The details of the payments used in the order.", "optional": false, "defaultValue": "", @@ -355,7 +355,7 @@ An order is a purchase made by a customer. It holds details about payment and fu }, { "name": "refunds", - "type": "[`Refund`](Refund.mdx)[]", + "type": "[Refund](Refund.mdx)[]", "description": "The details of the refunds created for the order.", "optional": false, "defaultValue": "", @@ -364,7 +364,7 @@ An order is a purchase made by a customer. It holds details about payment and fu }, { "name": "region", - "type": "[`Region`](Region.mdx)", + "type": "[Region](Region.mdx)", "description": "The details of the region this order was created in.", "optional": false, "defaultValue": "", @@ -382,7 +382,7 @@ An order is a purchase made by a customer. It holds details about payment and fu }, { "name": "returnable_items", - "type": "[`LineItem`](LineItem.mdx)[]", + "type": "[LineItem](LineItem.mdx)[]", "description": "The details of the line items that are returnable as part of the order, swaps, or claims", "optional": true, "defaultValue": "", @@ -391,7 +391,7 @@ An order is a purchase made by a customer. It holds details about payment and fu }, { "name": "returns", - "type": "[`Return`](Return.mdx)[]", + "type": "[Return](Return.mdx)[]", "description": "The details of the returns created for the order.", "optional": false, "defaultValue": "", @@ -400,7 +400,7 @@ An order is a purchase made by a customer. It holds details about payment and fu }, { "name": "sales_channel", - "type": "[`SalesChannel`](SalesChannel.mdx)", + "type": "[SalesChannel](SalesChannel.mdx)", "description": "The details of the sales channel this order belongs to.", "optional": false, "defaultValue": "", @@ -418,7 +418,7 @@ An order is a purchase made by a customer. It holds details about payment and fu }, { "name": "shipping_address", - "type": "[`Address`](Address.mdx)", + "type": "[Address](Address.mdx)", "description": "The details of the shipping address associated with the order.", "optional": false, "defaultValue": "", @@ -436,7 +436,7 @@ An order is a purchase made by a customer. It holds details about payment and fu }, { "name": "shipping_methods", - "type": "[`ShippingMethod`](ShippingMethod.mdx)[]", + "type": "[ShippingMethod](ShippingMethod.mdx)[]", "description": "The details of the shipping methods used in the order.", "optional": false, "defaultValue": "", @@ -463,7 +463,7 @@ An order is a purchase made by a customer. It holds details about payment and fu }, { "name": "status", - "type": "[`OrderStatus`](../enums/OrderStatus.mdx)", + "type": "[OrderStatus](../enums/OrderStatus.mdx)", "description": "The order's status", "optional": false, "defaultValue": "pending", @@ -481,7 +481,7 @@ An order is a purchase made by a customer. It holds details about payment and fu }, { "name": "swaps", - "type": "[`Swap`](Swap.mdx)[]", + "type": "[Swap](Swap.mdx)[]", "description": "The details of the swaps created for the order.", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/OrderEdit.mdx b/www/apps/docs/content/references/entities/classes/OrderEdit.mdx index 97a15459b3..4d7d416ca2 100644 --- a/www/apps/docs/content/references/entities/classes/OrderEdit.mdx +++ b/www/apps/docs/content/references/entities/classes/OrderEdit.mdx @@ -31,7 +31,7 @@ Order edit allows modifying items in an order, such as adding, updating, or dele }, { "name": "changes", - "type": "[`OrderItemChange`](OrderItemChange.mdx)[]", + "type": "[OrderItemChange](OrderItemChange.mdx)[]", "description": "The details of all the changes on the original order's line items.", "optional": false, "defaultValue": "", @@ -157,7 +157,7 @@ Order edit allows modifying items in an order, such as adding, updating, or dele }, { "name": "items", - "type": "[`LineItem`](LineItem.mdx)[]", + "type": "[LineItem](LineItem.mdx)[]", "description": "The details of the cloned items from the original order with the new changes. Once the order edit is confirmed, these line items are associated with the original order.", "optional": false, "defaultValue": "", @@ -166,7 +166,7 @@ Order edit allows modifying items in an order, such as adding, updating, or dele }, { "name": "order", - "type": "[`Order`](Order.mdx)", + "type": "[Order](Order.mdx)", "description": "The details of the order that this order edit was created for.", "optional": false, "defaultValue": "", @@ -184,7 +184,7 @@ Order edit allows modifying items in an order, such as adding, updating, or dele }, { "name": "payment_collection", - "type": "[`PaymentCollection`](PaymentCollection.mdx)", + "type": "[PaymentCollection](PaymentCollection.mdx)", "description": "The details of the payment collection used to authorize additional payment if necessary.", "optional": false, "defaultValue": "", @@ -229,7 +229,7 @@ Order edit allows modifying items in an order, such as adding, updating, or dele }, { "name": "status", - "type": "[`OrderEditStatus`](../enums/OrderEditStatus.mdx)", + "type": "[OrderEditStatus](../enums/OrderEditStatus.mdx)", "description": "The status of the order edit.", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/OrderItemChange.mdx b/www/apps/docs/content/references/entities/classes/OrderItemChange.mdx index d86737c1e4..a103f2fdb2 100644 --- a/www/apps/docs/content/references/entities/classes/OrderItemChange.mdx +++ b/www/apps/docs/content/references/entities/classes/OrderItemChange.mdx @@ -40,7 +40,7 @@ An order item change is a change made within an order edit to an order's items. }, { "name": "line_item", - "type": "[`LineItem`](LineItem.mdx)", + "type": "[LineItem](LineItem.mdx)", "description": "The details of the resulting line item after the item change. This line item is then used in the original order once the order edit is confirmed.", "optional": true, "defaultValue": "", @@ -58,7 +58,7 @@ An order item change is a change made within an order edit to an order's items. }, { "name": "order_edit", - "type": "[`OrderEdit`](OrderEdit.mdx)", + "type": "[OrderEdit](OrderEdit.mdx)", "description": "The details of the order edit the item change is associated with.", "optional": false, "defaultValue": "", @@ -76,7 +76,7 @@ An order item change is a change made within an order edit to an order's items. }, { "name": "original_line_item", - "type": "[`LineItem`](LineItem.mdx)", + "type": "[LineItem](LineItem.mdx)", "description": "The details of the original line item this item change references. This is used if the item change updates or deletes the original item.", "optional": true, "defaultValue": "", @@ -94,7 +94,7 @@ An order item change is a change made within an order edit to an order's items. }, { "name": "type", - "type": "[`OrderEditItemChangeType`](../enums/OrderEditItemChangeType.mdx)", + "type": "[OrderEditItemChangeType](../enums/OrderEditItemChangeType.mdx)", "description": "The order item change's status", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/Payment.mdx b/www/apps/docs/content/references/entities/classes/Payment.mdx index 9738ca80b3..cffa4d2988 100644 --- a/www/apps/docs/content/references/entities/classes/Payment.mdx +++ b/www/apps/docs/content/references/entities/classes/Payment.mdx @@ -49,7 +49,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "cart", - "type": "[`Cart`](Cart.mdx)", + "type": "[Cart](Cart.mdx)", "description": "The details of the cart that the payment session was potentially created for.", "optional": false, "defaultValue": "", @@ -57,7 +57,7 @@ A payment is originally created from a payment session. Once a payment session i "children": [ { "name": "billing_address", - "type": "[`Address`](Address.mdx)", + "type": "[Address](Address.mdx)", "description": "The details of the billing address associated with the cart.", "optional": false, "defaultValue": "", @@ -84,7 +84,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "context", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "The context of the cart which can include info like IP or user agent.", "optional": false, "defaultValue": "", @@ -102,7 +102,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "customer", - "type": "[`Customer`](Customer.mdx)", + "type": "[Customer](Customer.mdx)", "description": "The details of the customer the cart belongs to.", "optional": false, "defaultValue": "", @@ -138,7 +138,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "discounts", - "type": "[`Discount`](Discount.mdx)[]", + "type": "[Discount](Discount.mdx)[]", "description": "An array of details of all discounts applied to the cart.", "optional": false, "defaultValue": "", @@ -174,7 +174,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "gift_cards", - "type": "[`GiftCard`](GiftCard.mdx)[]", + "type": "[GiftCard](GiftCard.mdx)[]", "description": "An array of details of all gift cards applied to the cart.", "optional": false, "defaultValue": "", @@ -210,7 +210,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "items", - "type": "[`LineItem`](LineItem.mdx)[]", + "type": "[LineItem](LineItem.mdx)[]", "description": "The line items added to the cart.", "optional": false, "defaultValue": "", @@ -219,7 +219,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -237,7 +237,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "payment", - "type": "[`Payment`](Payment.mdx)", + "type": "[Payment](Payment.mdx)", "description": "The details of the payment associated with the cart.", "optional": false, "defaultValue": "", @@ -264,7 +264,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "payment_session", - "type": "``null`` \\| [`PaymentSession`](PaymentSession.mdx)", + "type": "``null`` \\| [PaymentSession](PaymentSession.mdx)", "description": "The details of the selected payment session in the cart.", "optional": false, "defaultValue": "", @@ -273,7 +273,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "payment_sessions", - "type": "[`PaymentSession`](PaymentSession.mdx)[]", + "type": "[PaymentSession](PaymentSession.mdx)[]", "description": "The details of all payment sessions created on the cart.", "optional": false, "defaultValue": "", @@ -309,7 +309,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "region", - "type": "[`Region`](Region.mdx)", + "type": "[Region](Region.mdx)", "description": "The details of the region associated with the cart.", "optional": false, "defaultValue": "", @@ -327,7 +327,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "sales_channel", - "type": "[`SalesChannel`](SalesChannel.mdx)", + "type": "[SalesChannel](SalesChannel.mdx)", "description": "The details of the sales channel associated with the cart.", "optional": false, "defaultValue": "", @@ -345,7 +345,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "shipping_address", - "type": "``null`` \\| [`Address`](Address.mdx)", + "type": "``null`` \\| [Address](Address.mdx)", "description": "The details of the shipping address associated with the cart.", "optional": false, "defaultValue": "", @@ -363,7 +363,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "shipping_methods", - "type": "[`ShippingMethod`](ShippingMethod.mdx)[]", + "type": "[ShippingMethod](ShippingMethod.mdx)[]", "description": "The details of the shipping methods added to the cart.", "optional": false, "defaultValue": "", @@ -417,7 +417,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "type", - "type": "[`CartType`](../enums/CartType.mdx)", + "type": "[CartType](../enums/CartType.mdx)", "description": "The cart's type.", "optional": false, "defaultValue": "default", @@ -455,7 +455,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "currency", - "type": "[`Currency`](Currency.mdx)", + "type": "[Currency](Currency.mdx)", "description": "The details of the currency of the payment.", "optional": false, "defaultValue": "", @@ -520,7 +520,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "data", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "The data required for the Payment Provider to identify, modify and process the Payment. Typically this will be an object that holds an id to the external payment session, but can be an empty object if the Payment Provider doesn't hold any state.", "optional": false, "defaultValue": "", @@ -547,7 +547,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -556,7 +556,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "order", - "type": "[`Order`](Order.mdx)", + "type": "[Order](Order.mdx)", "description": "The details of the order that the payment session was potentially created for.", "optional": false, "defaultValue": "", @@ -564,7 +564,7 @@ A payment is originally created from a payment session. Once a payment session i "children": [ { "name": "billing_address", - "type": "[`Address`](Address.mdx)", + "type": "[Address](Address.mdx)", "description": "The details of the billing address associated with the order.", "optional": false, "defaultValue": "", @@ -591,7 +591,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "cart", - "type": "[`Cart`](Cart.mdx)", + "type": "[Cart](Cart.mdx)", "description": "The details of the cart associated with the order.", "optional": false, "defaultValue": "", @@ -609,7 +609,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "claims", - "type": "[`ClaimOrder`](ClaimOrder.mdx)[]", + "type": "[ClaimOrder](ClaimOrder.mdx)[]", "description": "The details of the claims created for the order.", "optional": false, "defaultValue": "", @@ -627,7 +627,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "currency", - "type": "[`Currency`](Currency.mdx)", + "type": "[Currency](Currency.mdx)", "description": "The details of the currency used in the order.", "optional": false, "defaultValue": "", @@ -645,7 +645,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "customer", - "type": "[`Customer`](Customer.mdx)", + "type": "[Customer](Customer.mdx)", "description": "The details of the customer associated with the order.", "optional": false, "defaultValue": "", @@ -672,7 +672,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "discounts", - "type": "[`Discount`](Discount.mdx)[]", + "type": "[Discount](Discount.mdx)[]", "description": "The details of the discounts applied on the order.", "optional": false, "defaultValue": "", @@ -690,7 +690,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "draft_order", - "type": "[`DraftOrder`](DraftOrder.mdx)", + "type": "[DraftOrder](DraftOrder.mdx)", "description": "The details of the draft order this order was created from.", "optional": false, "defaultValue": "", @@ -708,7 +708,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "edits", - "type": "[`OrderEdit`](OrderEdit.mdx)[]", + "type": "[OrderEdit](OrderEdit.mdx)[]", "description": "The details of the order edits done on the order.", "optional": false, "defaultValue": "", @@ -735,7 +735,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "fulfillment_status", - "type": "[`FulfillmentStatus`](../enums/FulfillmentStatus.mdx)", + "type": "[FulfillmentStatus](../enums/FulfillmentStatus.mdx)", "description": "The order's fulfillment status", "optional": false, "defaultValue": "not_fulfilled", @@ -744,7 +744,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "fulfillments", - "type": "[`Fulfillment`](Fulfillment.mdx)[]", + "type": "[Fulfillment](Fulfillment.mdx)[]", "description": "The details of the fulfillments created for the order.", "optional": false, "defaultValue": "", @@ -771,7 +771,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "gift_card_transactions", - "type": "[`GiftCardTransaction`](GiftCardTransaction.mdx)[]", + "type": "[GiftCardTransaction](GiftCardTransaction.mdx)[]", "description": "The gift card transactions made in the order.", "optional": false, "defaultValue": "", @@ -780,7 +780,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "gift_cards", - "type": "[`GiftCard`](GiftCard.mdx)[]", + "type": "[GiftCard](GiftCard.mdx)[]", "description": "The details of the gift card used in the order.", "optional": false, "defaultValue": "", @@ -816,7 +816,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "items", - "type": "[`LineItem`](LineItem.mdx)[]", + "type": "[LineItem](LineItem.mdx)[]", "description": "The details of the line items that belong to the order.", "optional": false, "defaultValue": "", @@ -825,7 +825,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -861,7 +861,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "payment_status", - "type": "[`PaymentStatus`](../enums/PaymentStatus.mdx)", + "type": "[PaymentStatus](../enums/PaymentStatus.mdx)", "description": "The order's payment status", "optional": false, "defaultValue": "not_paid", @@ -870,7 +870,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "payments", - "type": "[`Payment`](Payment.mdx)[]", + "type": "[Payment](Payment.mdx)[]", "description": "The details of the payments used in the order.", "optional": false, "defaultValue": "", @@ -906,7 +906,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "refunds", - "type": "[`Refund`](Refund.mdx)[]", + "type": "[Refund](Refund.mdx)[]", "description": "The details of the refunds created for the order.", "optional": false, "defaultValue": "", @@ -915,7 +915,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "region", - "type": "[`Region`](Region.mdx)", + "type": "[Region](Region.mdx)", "description": "The details of the region this order was created in.", "optional": false, "defaultValue": "", @@ -933,7 +933,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "returnable_items", - "type": "[`LineItem`](LineItem.mdx)[]", + "type": "[LineItem](LineItem.mdx)[]", "description": "The details of the line items that are returnable as part of the order, swaps, or claims", "optional": true, "defaultValue": "", @@ -942,7 +942,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "returns", - "type": "[`Return`](Return.mdx)[]", + "type": "[Return](Return.mdx)[]", "description": "The details of the returns created for the order.", "optional": false, "defaultValue": "", @@ -951,7 +951,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "sales_channel", - "type": "[`SalesChannel`](SalesChannel.mdx)", + "type": "[SalesChannel](SalesChannel.mdx)", "description": "The details of the sales channel this order belongs to.", "optional": false, "defaultValue": "", @@ -969,7 +969,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "shipping_address", - "type": "[`Address`](Address.mdx)", + "type": "[Address](Address.mdx)", "description": "The details of the shipping address associated with the order.", "optional": false, "defaultValue": "", @@ -987,7 +987,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "shipping_methods", - "type": "[`ShippingMethod`](ShippingMethod.mdx)[]", + "type": "[ShippingMethod](ShippingMethod.mdx)[]", "description": "The details of the shipping methods used in the order.", "optional": false, "defaultValue": "", @@ -1014,7 +1014,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "status", - "type": "[`OrderStatus`](../enums/OrderStatus.mdx)", + "type": "[OrderStatus](../enums/OrderStatus.mdx)", "description": "The order's status", "optional": false, "defaultValue": "pending", @@ -1032,7 +1032,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "swaps", - "type": "[`Swap`](Swap.mdx)[]", + "type": "[Swap](Swap.mdx)[]", "description": "The details of the swaps created for the order.", "optional": false, "defaultValue": "", @@ -1097,7 +1097,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "swap", - "type": "[`Swap`](Swap.mdx)", + "type": "[Swap](Swap.mdx)", "description": "The details of the swap that this payment was potentially created for.", "optional": false, "defaultValue": "", @@ -1105,7 +1105,7 @@ A payment is originally created from a payment session. Once a payment session i "children": [ { "name": "additional_items", - "type": "[`LineItem`](LineItem.mdx)[]", + "type": "[LineItem](LineItem.mdx)[]", "description": "The details of the new products to send to the customer, represented as line items.", "optional": false, "defaultValue": "", @@ -1132,7 +1132,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "cart", - "type": "[`Cart`](Cart.mdx)", + "type": "[Cart](Cart.mdx)", "description": "The details of the cart that the customer uses to complete the swap.", "optional": false, "defaultValue": "", @@ -1186,7 +1186,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "fulfillment_status", - "type": "[`SwapFulfillmentStatus`](../enums/SwapFulfillmentStatus.mdx)", + "type": "[SwapFulfillmentStatus](../enums/SwapFulfillmentStatus.mdx)", "description": "The status of the Fulfillment of the Swap.", "optional": false, "defaultValue": "", @@ -1195,7 +1195,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "fulfillments", - "type": "[`Fulfillment`](Fulfillment.mdx)[]", + "type": "[Fulfillment](Fulfillment.mdx)[]", "description": "The details of the fulfillments that are used to send the new items to the customer.", "optional": false, "defaultValue": "", @@ -1222,7 +1222,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -1240,7 +1240,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "order", - "type": "[`Order`](Order.mdx)", + "type": "[Order](Order.mdx)", "description": "The details of the order that the swap belongs to.", "optional": false, "defaultValue": "", @@ -1258,8 +1258,8 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "payment", - "type": "[`Payment`](Payment.mdx)", - "description": "The details of the additional payment authorized by the customer when `difference_due` is positive.", + "type": "[Payment](Payment.mdx)", + "description": "The details of the additional payment authorized by the customer when `difference\\_due` is positive.", "optional": false, "defaultValue": "", "expandable": true, @@ -1267,7 +1267,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "payment_status", - "type": "[`SwapPaymentStatus`](../enums/SwapPaymentStatus.mdx)", + "type": "[SwapPaymentStatus](../enums/SwapPaymentStatus.mdx)", "description": "The status of the Payment of the Swap. The payment may either refer to the refund of an amount or the authorization of a new amount.", "optional": false, "defaultValue": "", @@ -1276,7 +1276,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "return_order", - "type": "[`Return`](Return.mdx)", + "type": "[Return](Return.mdx)", "description": "The details of the return that belongs to the swap, which holds the details on the items being returned.", "optional": false, "defaultValue": "", @@ -1285,7 +1285,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "shipping_address", - "type": "[`Address`](Address.mdx)", + "type": "[Address](Address.mdx)", "description": "The details of the shipping address that the new items should be sent to.", "optional": false, "defaultValue": "", @@ -1303,7 +1303,7 @@ A payment is originally created from a payment session. Once a payment session i }, { "name": "shipping_methods", - "type": "[`ShippingMethod`](ShippingMethod.mdx)[]", + "type": "[ShippingMethod](ShippingMethod.mdx)[]", "description": "The details of the shipping methods used to fulfill the additional items purchased.", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/PaymentCollection.mdx b/www/apps/docs/content/references/entities/classes/PaymentCollection.mdx index 7f922efd58..47b13fa15b 100644 --- a/www/apps/docs/content/references/entities/classes/PaymentCollection.mdx +++ b/www/apps/docs/content/references/entities/classes/PaymentCollection.mdx @@ -49,7 +49,7 @@ A payment collection allows grouping and managing a list of payments at one. Thi }, { "name": "currency", - "type": "[`Currency`](Currency.mdx)", + "type": "[Currency](Currency.mdx)", "description": "The details of the currency this payment collection is associated with.", "optional": false, "defaultValue": "", @@ -141,7 +141,7 @@ A payment collection allows grouping and managing a list of payments at one. Thi }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -150,7 +150,7 @@ A payment collection allows grouping and managing a list of payments at one. Thi }, { "name": "payment_sessions", - "type": "[`PaymentSession`](PaymentSession.mdx)[]", + "type": "[PaymentSession](PaymentSession.mdx)[]", "description": "The details of the payment sessions created as part of the payment collection.", "optional": false, "defaultValue": "", @@ -167,7 +167,7 @@ A payment collection allows grouping and managing a list of payments at one. Thi }, { "name": "cart", - "type": "[`Cart`](Cart.mdx)", + "type": "[Cart](Cart.mdx)", "description": "The details of the cart that the payment session was created for.", "optional": false, "defaultValue": "", @@ -194,7 +194,7 @@ A payment collection allows grouping and managing a list of payments at one. Thi }, { "name": "data", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "The data required for the Payment Provider to identify, modify and process the Payment Session. Typically this will be an object that holds an id to the external payment session, but can be an empty object if the Payment Provider doesn't hold any state.", "optional": false, "defaultValue": "", @@ -258,7 +258,7 @@ A payment collection allows grouping and managing a list of payments at one. Thi { "name": "status", "type": "`string`", - "description": "Indicates the status of the Payment Session. Will default to `pending`, and will eventually become `authorized`. Payment Sessions may have the status of `requires_more` to indicate that further actions are to be completed by the Customer.", + "description": "Indicates the status of the Payment Session. Will default to `pending`, and will eventually become `authorized`. Payment Sessions may have the status of `requires\\_more` to indicate that further actions are to be completed by the Customer.", "optional": false, "defaultValue": "", "expandable": false, @@ -277,7 +277,7 @@ A payment collection allows grouping and managing a list of payments at one. Thi }, { "name": "payments", - "type": "[`Payment`](Payment.mdx)[]", + "type": "[Payment](Payment.mdx)[]", "description": "The details of the payments created as part of the payment collection.", "optional": false, "defaultValue": "", @@ -321,7 +321,7 @@ A payment collection allows grouping and managing a list of payments at one. Thi }, { "name": "cart", - "type": "[`Cart`](Cart.mdx)", + "type": "[Cart](Cart.mdx)", "description": "The details of the cart that the payment session was potentially created for.", "optional": false, "defaultValue": "", @@ -348,7 +348,7 @@ A payment collection allows grouping and managing a list of payments at one. Thi }, { "name": "currency", - "type": "[`Currency`](Currency.mdx)", + "type": "[Currency](Currency.mdx)", "description": "The details of the currency of the payment.", "optional": false, "defaultValue": "", @@ -366,7 +366,7 @@ A payment collection allows grouping and managing a list of payments at one. Thi }, { "name": "data", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "The data required for the Payment Provider to identify, modify and process the Payment. Typically this will be an object that holds an id to the external payment session, but can be an empty object if the Payment Provider doesn't hold any state.", "optional": false, "defaultValue": "", @@ -393,7 +393,7 @@ A payment collection allows grouping and managing a list of payments at one. Thi }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -402,7 +402,7 @@ A payment collection allows grouping and managing a list of payments at one. Thi }, { "name": "order", - "type": "[`Order`](Order.mdx)", + "type": "[Order](Order.mdx)", "description": "The details of the order that the payment session was potentially created for.", "optional": false, "defaultValue": "", @@ -429,7 +429,7 @@ A payment collection allows grouping and managing a list of payments at one. Thi }, { "name": "swap", - "type": "[`Swap`](Swap.mdx)", + "type": "[Swap](Swap.mdx)", "description": "The details of the swap that this payment was potentially created for.", "optional": false, "defaultValue": "", @@ -458,7 +458,7 @@ A payment collection allows grouping and managing a list of payments at one. Thi }, { "name": "region", - "type": "[`Region`](Region.mdx)", + "type": "[Region](Region.mdx)", "description": "The details of the region this payment collection is associated with.", "optional": false, "defaultValue": "", @@ -475,7 +475,7 @@ A payment collection allows grouping and managing a list of payments at one. Thi }, { "name": "countries", - "type": "[`Country`](Country.mdx)[]", + "type": "[Country](Country.mdx)[]", "description": "The details of the countries included in this region.", "optional": false, "defaultValue": "", @@ -493,7 +493,7 @@ A payment collection allows grouping and managing a list of payments at one. Thi }, { "name": "currency", - "type": "[`Currency`](Currency.mdx)", + "type": "[Currency](Currency.mdx)", "description": "The details of the currency used in the region.", "optional": false, "defaultValue": "", @@ -520,7 +520,7 @@ A payment collection allows grouping and managing a list of payments at one. Thi }, { "name": "fulfillment_providers", - "type": "[`FulfillmentProvider`](FulfillmentProvider.mdx)[]", + "type": "[FulfillmentProvider](FulfillmentProvider.mdx)[]", "description": "The details of the fulfillment providers that can be used to fulfill items of orders and similar resources in the region.", "optional": false, "defaultValue": "", @@ -557,7 +557,7 @@ A payment collection allows grouping and managing a list of payments at one. Thi }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -575,7 +575,7 @@ A payment collection allows grouping and managing a list of payments at one. Thi }, { "name": "payment_providers", - "type": "[`PaymentProvider`](PaymentProvider.mdx)[]", + "type": "[PaymentProvider](PaymentProvider.mdx)[]", "description": "The details of the payment providers that can be used to process payments in the region.", "optional": false, "defaultValue": "", @@ -593,7 +593,7 @@ A payment collection allows grouping and managing a list of payments at one. Thi }, { "name": "tax_provider", - "type": "[`TaxProvider`](TaxProvider.mdx)", + "type": "[TaxProvider](TaxProvider.mdx)", "description": "The details of the tax provider used in the region.", "optional": false, "defaultValue": "", @@ -620,7 +620,7 @@ A payment collection allows grouping and managing a list of payments at one. Thi }, { "name": "tax_rates", - "type": "``null`` \\| [`TaxRate`](TaxRate.mdx)[]", + "type": "``null`` \\| [TaxRate](TaxRate.mdx)[]", "description": "The details of the tax rates used in the region, aside from the default rate.", "optional": false, "defaultValue": "", @@ -649,7 +649,7 @@ A payment collection allows grouping and managing a list of payments at one. Thi }, { "name": "status", - "type": "[`PaymentCollectionStatus`](../enums/PaymentCollectionStatus.mdx)", + "type": "[PaymentCollectionStatus](../enums/PaymentCollectionStatus.mdx)", "description": "The type of the payment collection", "optional": false, "defaultValue": "", @@ -704,7 +704,7 @@ A payment collection allows grouping and managing a list of payments at one. Thi }, { "name": "type", - "type": "[`ORDER_EDIT`](../enums/PaymentCollectionType.mdx#order_edit)", + "type": "[ORDER_EDIT](../enums/PaymentCollectionType.mdx#order_edit)", "description": "The type of the payment collection", "optional": false, "defaultValue": "", diff --git a/www/apps/docs/content/references/entities/classes/PaymentProvider.mdx b/www/apps/docs/content/references/entities/classes/PaymentProvider.mdx index 972c749d70..11e8a83456 100644 --- a/www/apps/docs/content/references/entities/classes/PaymentProvider.mdx +++ b/www/apps/docs/content/references/entities/classes/PaymentProvider.mdx @@ -23,7 +23,7 @@ A payment provider represents a payment service installed in the Medusa backend, { "name": "is_installed", "type": "`boolean`", - "description": "Whether the payment service is installed in the current version. If a payment service is no longer installed, the `is_installed` attribute is set to `false`.", + "description": "Whether the payment service is installed in the current version. If a payment service is no longer installed, the `is\\_installed` attribute is set to `false`.", "optional": false, "defaultValue": "true", "expandable": false, diff --git a/www/apps/docs/content/references/entities/classes/PaymentSession.mdx b/www/apps/docs/content/references/entities/classes/PaymentSession.mdx index 9e9d0d158b..a84827834b 100644 --- a/www/apps/docs/content/references/entities/classes/PaymentSession.mdx +++ b/www/apps/docs/content/references/entities/classes/PaymentSession.mdx @@ -22,7 +22,7 @@ A Payment Session is created when a Customer initilizes the checkout flow, and c }, { "name": "cart", - "type": "[`Cart`](Cart.mdx)", + "type": "[Cart](Cart.mdx)", "description": "The details of the cart that the payment session was created for.", "optional": false, "defaultValue": "", @@ -30,7 +30,7 @@ A Payment Session is created when a Customer initilizes the checkout flow, and c "children": [ { "name": "billing_address", - "type": "[`Address`](Address.mdx)", + "type": "[Address](Address.mdx)", "description": "The details of the billing address associated with the cart.", "optional": false, "defaultValue": "", @@ -57,7 +57,7 @@ A Payment Session is created when a Customer initilizes the checkout flow, and c }, { "name": "context", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "The context of the cart which can include info like IP or user agent.", "optional": false, "defaultValue": "", @@ -75,7 +75,7 @@ A Payment Session is created when a Customer initilizes the checkout flow, and c }, { "name": "customer", - "type": "[`Customer`](Customer.mdx)", + "type": "[Customer](Customer.mdx)", "description": "The details of the customer the cart belongs to.", "optional": false, "defaultValue": "", @@ -111,7 +111,7 @@ A Payment Session is created when a Customer initilizes the checkout flow, and c }, { "name": "discounts", - "type": "[`Discount`](Discount.mdx)[]", + "type": "[Discount](Discount.mdx)[]", "description": "An array of details of all discounts applied to the cart.", "optional": false, "defaultValue": "", @@ -147,7 +147,7 @@ A Payment Session is created when a Customer initilizes the checkout flow, and c }, { "name": "gift_cards", - "type": "[`GiftCard`](GiftCard.mdx)[]", + "type": "[GiftCard](GiftCard.mdx)[]", "description": "An array of details of all gift cards applied to the cart.", "optional": false, "defaultValue": "", @@ -183,7 +183,7 @@ A Payment Session is created when a Customer initilizes the checkout flow, and c }, { "name": "items", - "type": "[`LineItem`](LineItem.mdx)[]", + "type": "[LineItem](LineItem.mdx)[]", "description": "The line items added to the cart.", "optional": false, "defaultValue": "", @@ -192,7 +192,7 @@ A Payment Session is created when a Customer initilizes the checkout flow, and c }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -210,7 +210,7 @@ A Payment Session is created when a Customer initilizes the checkout flow, and c }, { "name": "payment", - "type": "[`Payment`](Payment.mdx)", + "type": "[Payment](Payment.mdx)", "description": "The details of the payment associated with the cart.", "optional": false, "defaultValue": "", @@ -237,7 +237,7 @@ A Payment Session is created when a Customer initilizes the checkout flow, and c }, { "name": "payment_session", - "type": "``null`` \\| [`PaymentSession`](PaymentSession.mdx)", + "type": "``null`` \\| [PaymentSession](PaymentSession.mdx)", "description": "The details of the selected payment session in the cart.", "optional": false, "defaultValue": "", @@ -246,7 +246,7 @@ A Payment Session is created when a Customer initilizes the checkout flow, and c }, { "name": "payment_sessions", - "type": "[`PaymentSession`](PaymentSession.mdx)[]", + "type": "[PaymentSession](PaymentSession.mdx)[]", "description": "The details of all payment sessions created on the cart.", "optional": false, "defaultValue": "", @@ -282,7 +282,7 @@ A Payment Session is created when a Customer initilizes the checkout flow, and c }, { "name": "region", - "type": "[`Region`](Region.mdx)", + "type": "[Region](Region.mdx)", "description": "The details of the region associated with the cart.", "optional": false, "defaultValue": "", @@ -300,7 +300,7 @@ A Payment Session is created when a Customer initilizes the checkout flow, and c }, { "name": "sales_channel", - "type": "[`SalesChannel`](SalesChannel.mdx)", + "type": "[SalesChannel](SalesChannel.mdx)", "description": "The details of the sales channel associated with the cart.", "optional": false, "defaultValue": "", @@ -318,7 +318,7 @@ A Payment Session is created when a Customer initilizes the checkout flow, and c }, { "name": "shipping_address", - "type": "``null`` \\| [`Address`](Address.mdx)", + "type": "``null`` \\| [Address](Address.mdx)", "description": "The details of the shipping address associated with the cart.", "optional": false, "defaultValue": "", @@ -336,7 +336,7 @@ A Payment Session is created when a Customer initilizes the checkout flow, and c }, { "name": "shipping_methods", - "type": "[`ShippingMethod`](ShippingMethod.mdx)[]", + "type": "[ShippingMethod](ShippingMethod.mdx)[]", "description": "The details of the shipping methods added to the cart.", "optional": false, "defaultValue": "", @@ -390,7 +390,7 @@ A Payment Session is created when a Customer initilizes the checkout flow, and c }, { "name": "type", - "type": "[`CartType`](../enums/CartType.mdx)", + "type": "[CartType](../enums/CartType.mdx)", "description": "The cart's type.", "optional": false, "defaultValue": "default", @@ -428,7 +428,7 @@ A Payment Session is created when a Customer initilizes the checkout flow, and c }, { "name": "data", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "The data required for the Payment Provider to identify, modify and process the Payment Session. Typically this will be an object that holds an id to the external payment session, but can be an empty object if the Payment Provider doesn't hold any state.", "optional": false, "defaultValue": "", @@ -492,7 +492,7 @@ A Payment Session is created when a Customer initilizes the checkout flow, and c { "name": "status", "type": "`string`", - "description": "Indicates the status of the Payment Session. Will default to `pending`, and will eventually become `authorized`. Payment Sessions may have the status of `requires_more` to indicate that further actions are to be completed by the Customer.", + "description": "Indicates the status of the Payment Session. Will default to `pending`, and will eventually become `authorized`. Payment Sessions may have the status of `requires\\_more` to indicate that further actions are to be completed by the Customer.", "optional": false, "defaultValue": "", "expandable": false, diff --git a/www/apps/docs/content/references/entities/classes/PriceList.mdx b/www/apps/docs/content/references/entities/classes/PriceList.mdx index 38ce5f74dd..b17803c0b0 100644 --- a/www/apps/docs/content/references/entities/classes/PriceList.mdx +++ b/www/apps/docs/content/references/entities/classes/PriceList.mdx @@ -22,7 +22,7 @@ A Price List represents a set of prices that override the default price for one }, { "name": "customer_groups", - "type": "[`CustomerGroup`](CustomerGroup.mdx)[]", + "type": "[CustomerGroup](CustomerGroup.mdx)[]", "description": "The details of the customer groups that the Price List can apply to.", "optional": false, "defaultValue": "", @@ -39,7 +39,7 @@ A Price List represents a set of prices that override the default price for one }, { "name": "customers", - "type": "[`Customer`](Customer.mdx)[]", + "type": "[Customer](Customer.mdx)[]", "description": "The details of the customers that belong to the customer group.", "optional": false, "defaultValue": "", @@ -66,7 +66,7 @@ A Price List represents a set of prices that override the default price for one }, { "name": "metadata", - "type": "Record<`string`, `unknown`\\>", + "type": "`Record`", "description": "An optional key-value map with additional details", "optional": false, "defaultValue": "", @@ -84,7 +84,7 @@ A Price List represents a set of prices that override the default price for one }, { "name": "price_lists", - "type": "[`PriceList`](PriceList.mdx)[]", + "type": "[PriceList](PriceList.mdx)[]", "description": "The price lists that are associated with the customer group.", "optional": false, "defaultValue": "", @@ -159,7 +159,7 @@ A Price List represents a set of prices that override the default price for one }, { "name": "prices", - "type": "[`MoneyAmount`](MoneyAmount.mdx)[]", + "type": "[MoneyAmount](MoneyAmount.mdx)[]", "description": "The prices that belong to the price list, represented as a Money Amount.", "optional": false, "defaultValue": "", @@ -185,7 +185,7 @@ A Price List represents a set of prices that override the default price for one }, { "name": "currency", - "type": "[`Currency`](Currency.mdx)", + "type": "[Currency](Currency.mdx)", "description": "The details of the currency that the money amount may belong to.", "optional": true, "defaultValue": "", @@ -239,7 +239,7 @@ A Price List represents a set of prices that override the default price for one }, { "name": "price_list", - "type": "``null`` \\| [`PriceList`](PriceList.mdx)", + "type": "``null`` \\| [PriceList](PriceList.mdx)", "description": "The details of the price list that the money amount may belong to.", "optional": false, "defaultValue": "", @@ -257,7 +257,7 @@ A Price List represents a set of prices that override the default price for one }, { "name": "region", - "type": "[`Region`](Region.mdx)", + "type": "[Region](Region.mdx)", "description": "The details of the region that the money amount may belong to.", "optional": true, "defaultValue": "", @@ -284,7 +284,7 @@ A Price List represents a set of prices that override the default price for one }, { "name": "variant", - "type": "[`ProductVariant`](ProductVariant.mdx)", + "type": "[ProductVariant](ProductVariant.mdx)", "description": "The details of the product variant that the money amount may belong to.", "optional": false, "defaultValue": "", @@ -302,7 +302,7 @@ A Price List represents a set of prices that override the default price for one }, { "name": "variants", - "type": "[`ProductVariant`](ProductVariant.mdx)[]", + "type": "[ProductVariant](ProductVariant.mdx)[]", "description": "", "optional": false, "defaultValue": "", @@ -322,7 +322,7 @@ A Price List represents a set of prices that override the default price for one }, { "name": "status", - "type": "[`PriceListStatus`](../enums/PriceListStatus.mdx)", + "type": "[PriceListStatus](../enums/PriceListStatus.mdx)", "description": "The status of the Price List", "optional": false, "defaultValue": "draft", @@ -350,7 +350,7 @@ A Price List represents a set of prices that override the default price for one }, { "name": "type", - "type": "[`PriceListType`](../enums/PriceListType.mdx)", + "type": "[PriceListType](../enums/PriceListType.mdx)", "description": "The type of Price List. This can be one of either `sale` or `override`.", "optional": false, "defaultValue": "sale", diff --git a/www/apps/docs/content/references/entities/classes/Product.mdx b/www/apps/docs/content/references/entities/classes/Product.mdx index fe005540ea..241a804d48 100644 --- a/www/apps/docs/content/references/entities/classes/Product.mdx +++ b/www/apps/docs/content/references/entities/classes/Product.mdx @@ -13,7 +13,7 @@ A product is a saleable item that holds general information such as name or desc