@salifbiaye/create-boutique 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/cli/dist/commands.js +382 -0
- package/cli/dist/create.js +194 -0
- package/cli/dist/docker.js +19 -0
- package/cli/dist/generate.js +322 -0
- package/cli/dist/guide.js +72 -0
- package/cli/dist/index.js +156 -0
- package/cli/dist/paths.js +29 -0
- package/cli/dist/ports.js +54 -0
- package/cli/dist/project.js +119 -0
- package/cli/dist/themes.js +24 -0
- package/docs/fiche-client.en.html +137 -0
- package/docs/fiche-client.html +137 -0
- package/docs/guide-complet.en.html +259 -0
- package/docs/guide-complet.fr.html +259 -0
- package/package.json +51 -0
- package/templates/backend/.dockerignore +9 -0
- package/templates/backend/Dockerfile +30 -0
- package/templates/backend/README.md +78 -0
- package/templates/backend/TEMPLATE_VERSION +1 -0
- package/templates/backend/docker/entrypoint.sh +28 -0
- package/templates/backend/instrumentation.ts +24 -0
- package/templates/backend/medusa-config.ts +114 -0
- package/templates/backend/package-lock.json +16222 -0
- package/templates/backend/package.json +39 -0
- package/templates/backend/src/admin/README.md +33 -0
- package/templates/backend/src/admin/components/image-field.tsx +61 -0
- package/templates/backend/src/admin/i18n/README.md +58 -0
- package/templates/backend/src/admin/i18n/index.ts +8 -0
- package/templates/backend/src/admin/i18n/json/en.json +66 -0
- package/templates/backend/src/admin/i18n/json/fr.json +66 -0
- package/templates/backend/src/admin/lib/client.ts +9 -0
- package/templates/backend/src/admin/routes/boutique-campaigns/campaign-drawer.tsx +286 -0
- package/templates/backend/src/admin/routes/boutique-campaigns/page.tsx +113 -0
- package/templates/backend/src/admin/tsconfig.json +24 -0
- package/templates/backend/src/admin/vite-env.d.ts +1 -0
- package/templates/backend/src/admin/widgets/category-image.tsx +56 -0
- package/templates/backend/src/api/README.md +135 -0
- package/templates/backend/src/api/admin/boutique-campaigns/[salesChannelId]/route.ts +30 -0
- package/templates/backend/src/api/admin/boutique-campaigns/route.ts +24 -0
- package/templates/backend/src/api/middlewares.ts +28 -0
- package/templates/backend/src/api/rate-limit.ts +30 -0
- package/templates/backend/src/api/route.ts +6 -0
- package/templates/backend/src/api/store/campaign/route.ts +25 -0
- package/templates/backend/src/api/store/order-lookup/route.ts +74 -0
- package/templates/backend/src/emails/en.json +64 -0
- package/templates/backend/src/emails/fr.json +64 -0
- package/templates/backend/src/jobs/README.md +38 -0
- package/templates/backend/src/lib/emails.ts +94 -0
- package/templates/backend/src/lib/notify.ts +148 -0
- package/templates/backend/src/lib/project.ts +146 -0
- package/templates/backend/src/links/README.md +26 -0
- package/templates/backend/src/links/campaign-sales-channel.ts +9 -0
- package/templates/backend/src/modules/README.md +117 -0
- package/templates/backend/src/modules/campaign/index.ts +9 -0
- package/templates/backend/src/modules/campaign/migrations/.snapshot-boutique-campaign.json +272 -0
- package/templates/backend/src/modules/campaign/migrations/Migration20260928141440.ts +16 -0
- package/templates/backend/src/modules/campaign/migrations/Migration20260928145243.ts +13 -0
- package/templates/backend/src/modules/campaign/models/campaign.ts +28 -0
- package/templates/backend/src/modules/campaign/service.ts +6 -0
- package/templates/backend/src/modules/campaign/validators.ts +94 -0
- package/templates/backend/src/modules/resend/index.ts +6 -0
- package/templates/backend/src/modules/resend/service.ts +63 -0
- package/templates/backend/src/scripts/README.md +63 -0
- package/templates/backend/src/scripts/campaign-export.ts +15 -0
- package/templates/backend/src/scripts/campaign-import.ts +38 -0
- package/templates/backend/src/scripts/price-report.ts +34 -0
- package/templates/backend/src/scripts/seed.ts +418 -0
- package/templates/backend/src/scripts/storage.ts +63 -0
- package/templates/backend/src/subscribers/README.md +61 -0
- package/templates/backend/src/subscribers/account-emails.ts +27 -0
- package/templates/backend/src/subscribers/fulfillment-emails.ts +42 -0
- package/templates/backend/src/subscribers/order-emails.ts +12 -0
- package/templates/backend/src/subscribers/return-refund-emails.ts +50 -0
- package/templates/backend/src/workflows/README.md +81 -0
- package/templates/backend/src/workflows/steps/upsert-campaign.ts +53 -0
- package/templates/backend/src/workflows/upsert-campaign.ts +30 -0
- package/templates/backend/tsconfig.json +36 -0
- package/templates/storefront/.dockerignore +7 -0
- package/templates/storefront/.github/ISSUE_TEMPLATE/bug-report.yml +71 -0
- package/templates/storefront/.prettierrc +8 -0
- package/templates/storefront/Dockerfile +37 -0
- package/templates/storefront/LICENSE +21 -0
- package/templates/storefront/README.md +127 -0
- package/templates/storefront/locales/en.json +269 -0
- package/templates/storefront/locales/fr.json +269 -0
- package/templates/storefront/next-env.d.ts +7 -0
- package/templates/storefront/next-sitemap.js +19 -0
- package/templates/storefront/next.config.js +29 -0
- package/templates/storefront/package-lock.json +9031 -0
- package/templates/storefront/package.json +49 -0
- package/templates/storefront/postcss.config.js +6 -0
- package/templates/storefront/public/favicon.ico +0 -0
- package/templates/storefront/scripts/sync-design.mjs +30 -0
- package/templates/storefront/src/app/(checkout)/checkout/page.tsx +31 -0
- package/templates/storefront/src/app/(checkout)/layout.tsx +29 -0
- package/templates/storefront/src/app/(checkout)/not-found.tsx +20 -0
- package/templates/storefront/src/app/(main)/account/@dashboard/addresses/page.tsx +34 -0
- package/templates/storefront/src/app/(main)/account/@dashboard/loading.tsx +9 -0
- package/templates/storefront/src/app/(main)/account/@dashboard/orders/details/[id]/page.tsx +33 -0
- package/templates/storefront/src/app/(main)/account/@dashboard/orders/page.tsx +37 -0
- package/templates/storefront/src/app/(main)/account/@dashboard/page.tsx +22 -0
- package/templates/storefront/src/app/(main)/account/@dashboard/profile/page.tsx +53 -0
- package/templates/storefront/src/app/(main)/account/@login/page.tsx +12 -0
- package/templates/storefront/src/app/(main)/account/layout.tsx +20 -0
- package/templates/storefront/src/app/(main)/account/loading.tsx +9 -0
- package/templates/storefront/src/app/(main)/cart/loading.tsx +5 -0
- package/templates/storefront/src/app/(main)/cart/not-found.tsx +21 -0
- package/templates/storefront/src/app/(main)/cart/page.tsx +21 -0
- package/templates/storefront/src/app/(main)/categories/[...category]/page.tsx +55 -0
- package/templates/storefront/src/app/(main)/collections/[handle]/page.tsx +55 -0
- package/templates/storefront/src/app/(main)/layout.tsx +43 -0
- package/templates/storefront/src/app/(main)/legal/[page]/page.tsx +42 -0
- package/templates/storefront/src/app/(main)/not-found.tsx +21 -0
- package/templates/storefront/src/app/(main)/order/[id]/confirmed/loading.tsx +5 -0
- package/templates/storefront/src/app/(main)/order/[id]/confirmed/page.tsx +23 -0
- package/templates/storefront/src/app/(main)/order/[id]/transfer/[token]/accept/page.tsx +42 -0
- package/templates/storefront/src/app/(main)/order/[id]/transfer/[token]/decline/page.tsx +42 -0
- package/templates/storefront/src/app/(main)/order/[id]/transfer/[token]/page.tsx +35 -0
- package/templates/storefront/src/app/(main)/order/track/page.tsx +32 -0
- package/templates/storefront/src/app/(main)/page.tsx +68 -0
- package/templates/storefront/src/app/(main)/products/[handle]/page.tsx +86 -0
- package/templates/storefront/src/app/(main)/store/page.tsx +28 -0
- package/templates/storefront/src/app/api/health/route.ts +13 -0
- package/templates/storefront/src/app/layout.tsx +42 -0
- package/templates/storefront/src/app/not-found.tsx +21 -0
- package/templates/storefront/src/app/opengraph-image.jpg +0 -0
- package/templates/storefront/src/app/twitter-image.jpg +0 -0
- package/templates/storefront/src/instrumentation-node.ts +18 -0
- package/templates/storefront/src/instrumentation.ts +9 -0
- package/templates/storefront/src/lib/boutique/campaign.ts +116 -0
- package/templates/storefront/src/lib/boutique/config.ts +152 -0
- package/templates/storefront/src/lib/boutique/fonts.ts +29 -0
- package/templates/storefront/src/lib/boutique/i18n-client.tsx +34 -0
- package/templates/storefront/src/lib/boutique/i18n.ts +43 -0
- package/templates/storefront/src/lib/boutique/schema.ts +131 -0
- package/templates/storefront/src/lib/config.ts +39 -0
- package/templates/storefront/src/lib/constants.tsx +75 -0
- package/templates/storefront/src/lib/context/modal-context.tsx +34 -0
- package/templates/storefront/src/lib/data/cart.ts +434 -0
- package/templates/storefront/src/lib/data/categories.ts +49 -0
- package/templates/storefront/src/lib/data/collections.ts +59 -0
- package/templates/storefront/src/lib/data/cookies.ts +103 -0
- package/templates/storefront/src/lib/data/customer.ts +261 -0
- package/templates/storefront/src/lib/data/fulfillment.ts +68 -0
- package/templates/storefront/src/lib/data/onboarding.ts +9 -0
- package/templates/storefront/src/lib/data/order-lookup.ts +34 -0
- package/templates/storefront/src/lib/data/orders.ts +112 -0
- package/templates/storefront/src/lib/data/payment.ts +35 -0
- package/templates/storefront/src/lib/data/products.ts +127 -0
- package/templates/storefront/src/lib/data/regions.ts +70 -0
- package/templates/storefront/src/lib/data/variants.ts +38 -0
- package/templates/storefront/src/lib/hooks/use-in-view.tsx +29 -0
- package/templates/storefront/src/lib/hooks/use-toggle-state.tsx +46 -0
- package/templates/storefront/src/lib/util/compare-addresses.ts +28 -0
- package/templates/storefront/src/lib/util/get-percentage-diff.ts +6 -0
- package/templates/storefront/src/lib/util/get-product-price.ts +79 -0
- package/templates/storefront/src/lib/util/isEmpty.ts +11 -0
- package/templates/storefront/src/lib/util/medusa-error.ts +22 -0
- package/templates/storefront/src/lib/util/money.ts +35 -0
- package/templates/storefront/src/lib/util/product.ts +5 -0
- package/templates/storefront/src/lib/util/repeat.ts +5 -0
- package/templates/storefront/src/lib/util/sort-products.ts +50 -0
- package/templates/storefront/src/modules/account/components/account-info/index.tsx +140 -0
- package/templates/storefront/src/modules/account/components/account-nav/index.tsx +198 -0
- package/templates/storefront/src/modules/account/components/address-book/index.tsx +28 -0
- package/templates/storefront/src/modules/account/components/address-card/add-address.tsx +169 -0
- package/templates/storefront/src/modules/account/components/address-card/edit-address-modal.tsx +241 -0
- package/templates/storefront/src/modules/account/components/login/index.tsx +65 -0
- package/templates/storefront/src/modules/account/components/order-card/index.tsx +88 -0
- package/templates/storefront/src/modules/account/components/order-overview/index.tsx +47 -0
- package/templates/storefront/src/modules/account/components/overview/index.tsx +169 -0
- package/templates/storefront/src/modules/account/components/profile-billing-address/index.tsx +193 -0
- package/templates/storefront/src/modules/account/components/profile-email/index.tsx +75 -0
- package/templates/storefront/src/modules/account/components/profile-name/index.tsx +79 -0
- package/templates/storefront/src/modules/account/components/profile-password/index.tsx +72 -0
- package/templates/storefront/src/modules/account/components/profile-phone/index.tsx +74 -0
- package/templates/storefront/src/modules/account/components/register/index.tsx +107 -0
- package/templates/storefront/src/modules/account/components/transfer-request-form/index.tsx +83 -0
- package/templates/storefront/src/modules/account/templates/account-layout.tsx +43 -0
- package/templates/storefront/src/modules/account/templates/login-template.tsx +27 -0
- package/templates/storefront/src/modules/cart/components/cart-item-select/index.tsx +75 -0
- package/templates/storefront/src/modules/cart/components/empty-cart-message/index.tsx +25 -0
- package/templates/storefront/src/modules/cart/components/item/index.tsx +144 -0
- package/templates/storefront/src/modules/cart/components/sign-in-prompt/index.tsx +27 -0
- package/templates/storefront/src/modules/cart/templates/index.tsx +51 -0
- package/templates/storefront/src/modules/cart/templates/items.tsx +58 -0
- package/templates/storefront/src/modules/cart/templates/preview.tsx +51 -0
- package/templates/storefront/src/modules/cart/templates/summary.tsx +50 -0
- package/templates/storefront/src/modules/categories/templates/index.tsx +94 -0
- package/templates/storefront/src/modules/checkout/components/address-select/index.tsx +117 -0
- package/templates/storefront/src/modules/checkout/components/addresses/index.tsx +186 -0
- package/templates/storefront/src/modules/checkout/components/billing_address/index.tsx +114 -0
- package/templates/storefront/src/modules/checkout/components/country-select/index.tsx +50 -0
- package/templates/storefront/src/modules/checkout/components/discount-code/index.tsx +181 -0
- package/templates/storefront/src/modules/checkout/components/error-message/index.tsx +13 -0
- package/templates/storefront/src/modules/checkout/components/payment/index.tsx +261 -0
- package/templates/storefront/src/modules/checkout/components/payment-button/index.tsx +195 -0
- package/templates/storefront/src/modules/checkout/components/payment-container/index.tsx +130 -0
- package/templates/storefront/src/modules/checkout/components/payment-test/index.tsx +12 -0
- package/templates/storefront/src/modules/checkout/components/payment-wrapper/index.tsx +42 -0
- package/templates/storefront/src/modules/checkout/components/payment-wrapper/stripe-wrapper.tsx +54 -0
- package/templates/storefront/src/modules/checkout/components/review/index.tsx +54 -0
- package/templates/storefront/src/modules/checkout/components/shipping/index.tsx +417 -0
- package/templates/storefront/src/modules/checkout/components/shipping-address/index.tsx +219 -0
- package/templates/storefront/src/modules/checkout/components/submit-button/index.tsx +32 -0
- package/templates/storefront/src/modules/checkout/templates/checkout-form/index.tsx +38 -0
- package/templates/storefront/src/modules/checkout/templates/checkout-summary/index.tsx +31 -0
- package/templates/storefront/src/modules/collections/templates/index.tsx +44 -0
- package/templates/storefront/src/modules/common/components/cart-totals/index.tsx +84 -0
- package/templates/storefront/src/modules/common/components/checkbox/index.tsx +44 -0
- package/templates/storefront/src/modules/common/components/delete-button/index.tsx +42 -0
- package/templates/storefront/src/modules/common/components/divider/index.tsx +9 -0
- package/templates/storefront/src/modules/common/components/filter-radio-group/index.tsx +61 -0
- package/templates/storefront/src/modules/common/components/input/index.tsx +79 -0
- package/templates/storefront/src/modules/common/components/interactive-link/index.tsx +33 -0
- package/templates/storefront/src/modules/common/components/line-item-options/index.tsx +26 -0
- package/templates/storefront/src/modules/common/components/line-item-price/index.tsx +63 -0
- package/templates/storefront/src/modules/common/components/line-item-unit-price/index.tsx +62 -0
- package/templates/storefront/src/modules/common/components/localized-client-link/index.tsx +29 -0
- package/templates/storefront/src/modules/common/components/modal/index.tsx +118 -0
- package/templates/storefront/src/modules/common/components/native-select/index.tsx +76 -0
- package/templates/storefront/src/modules/common/components/radio/index.tsx +27 -0
- package/templates/storefront/src/modules/common/icons/back.tsx +37 -0
- package/templates/storefront/src/modules/common/icons/bancontact.tsx +26 -0
- package/templates/storefront/src/modules/common/icons/chevron-down.tsx +30 -0
- package/templates/storefront/src/modules/common/icons/eye-off.tsx +37 -0
- package/templates/storefront/src/modules/common/icons/eye.tsx +37 -0
- package/templates/storefront/src/modules/common/icons/fast-delivery.tsx +65 -0
- package/templates/storefront/src/modules/common/icons/ideal.tsx +26 -0
- package/templates/storefront/src/modules/common/icons/map-pin.tsx +37 -0
- package/templates/storefront/src/modules/common/icons/package.tsx +44 -0
- package/templates/storefront/src/modules/common/icons/paypal.tsx +30 -0
- package/templates/storefront/src/modules/common/icons/placeholder-image.tsx +44 -0
- package/templates/storefront/src/modules/common/icons/refresh.tsx +51 -0
- package/templates/storefront/src/modules/common/icons/spinner.tsx +37 -0
- package/templates/storefront/src/modules/common/icons/trash.tsx +51 -0
- package/templates/storefront/src/modules/common/icons/user.tsx +37 -0
- package/templates/storefront/src/modules/common/icons/x.tsx +37 -0
- package/templates/storefront/src/modules/layout/components/cart-mismatch-banner/index.tsx +59 -0
- package/templates/storefront/src/modules/order/components/help/index.tsx +26 -0
- package/templates/storefront/src/modules/order/components/item/index.tsx +57 -0
- package/templates/storefront/src/modules/order/components/items/index.tsx +44 -0
- package/templates/storefront/src/modules/order/components/onboarding-cta/index.tsx +28 -0
- package/templates/storefront/src/modules/order/components/order-details/index.tsx +64 -0
- package/templates/storefront/src/modules/order/components/order-summary/index.tsx +61 -0
- package/templates/storefront/src/modules/order/components/payment-details/index.tsx +64 -0
- package/templates/storefront/src/modules/order/components/shipping-details/index.tsx +74 -0
- package/templates/storefront/src/modules/order/components/transfer-actions/index.tsx +83 -0
- package/templates/storefront/src/modules/order/components/transfer-image/index.tsx +275 -0
- package/templates/storefront/src/modules/order/templates/order-completed-template.tsx +53 -0
- package/templates/storefront/src/modules/order/templates/order-details-template.tsx +46 -0
- package/templates/storefront/src/modules/products/components/thumbnail/index.tsx +70 -0
- package/templates/storefront/src/modules/products/templates/index.tsx +118 -0
- package/templates/storefront/src/modules/shipping/components/free-shipping-price-nudge/index.tsx +285 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-button/index.tsx +5 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-card-details/index.tsx +10 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-cart-item/index.tsx +35 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-cart-totals/index.tsx +30 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-code-form/index.tsx +13 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-line-item/index.tsx +35 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-order-confirmed-header/index.tsx +14 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-order-information/index.tsx +36 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-order-items/index.tsx +43 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-order-summary/index.tsx +15 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-product-preview/index.tsx +15 -0
- package/templates/storefront/src/modules/skeletons/templates/skeleton-cart-page/index.tsx +65 -0
- package/templates/storefront/src/modules/skeletons/templates/skeleton-order-confirmed/index.tsx +21 -0
- package/templates/storefront/src/modules/skeletons/templates/skeleton-product-grid/index.tsx +23 -0
- package/templates/storefront/src/modules/store/components/pagination/index.tsx +114 -0
- package/templates/storefront/src/modules/store/components/refinement-list/index.tsx +41 -0
- package/templates/storefront/src/modules/store/components/refinement-list/sort-products/index.tsx +48 -0
- package/templates/storefront/src/modules/store/templates/index.tsx +42 -0
- package/templates/storefront/src/modules/store/templates/paginated-products.tsx +80 -0
- package/templates/storefront/src/modules/ub/button.tsx +41 -0
- package/templates/storefront/src/modules/ub/campaign-blocks.tsx +197 -0
- package/templates/storefront/src/modules/ub/campaign-ended.tsx +28 -0
- package/templates/storefront/src/modules/ub/category-tiles.tsx +41 -0
- package/templates/storefront/src/modules/ub/countdown.tsx +46 -0
- package/templates/storefront/src/modules/ub/footer.tsx +56 -0
- package/templates/storefront/src/modules/ub/icons.tsx +42 -0
- package/templates/storefront/src/modules/ub/nav.tsx +90 -0
- package/templates/storefront/src/modules/ub/pdp/buy-box.tsx +140 -0
- package/templates/storefront/src/modules/ub/pdp/gallery.tsx +40 -0
- package/templates/storefront/src/modules/ub/product-card.tsx +66 -0
- package/templates/storefront/src/modules/ub/top-bar.tsx +20 -0
- package/templates/storefront/src/modules/ub/track-form.tsx +92 -0
- package/templates/storefront/src/proxy.ts +89 -0
- package/templates/storefront/src/styles/globals.css +98 -0
- package/templates/storefront/src/styles/ub/bundle.css +372 -0
- package/templates/storefront/src/styles/ub/fonts.css +17 -0
- package/templates/storefront/src/styles/ub/medusa-ui.css +90 -0
- package/templates/storefront/src/styles/ub/overrides.css +12 -0
- package/templates/storefront/src/styles/ub/tokens.css +9 -0
- package/templates/storefront/src/types/global.ts +24 -0
- package/templates/storefront/src/types/icon.ts +4 -0
- package/templates/storefront/tailwind.config.js +164 -0
- package/templates/storefront/themes/black-friday/campaign.en.json +31 -0
- package/templates/storefront/themes/black-friday/campaign.fr.json +31 -0
- package/templates/storefront/themes/black-friday/theme.json +9 -0
- package/templates/storefront/themes/cyber-monday/campaign.en.json +31 -0
- package/templates/storefront/themes/cyber-monday/campaign.fr.json +31 -0
- package/templates/storefront/themes/cyber-monday/theme.json +9 -0
- package/templates/storefront/themes/halloween/campaign.en.json +31 -0
- package/templates/storefront/themes/halloween/campaign.fr.json +31 -0
- package/templates/storefront/themes/halloween/theme.json +9 -0
- package/templates/storefront/themes/noel/campaign.en.json +31 -0
- package/templates/storefront/themes/noel/campaign.fr.json +31 -0
- package/templates/storefront/themes/noel/theme.json +9 -0
- package/templates/storefront/themes/nouvel-an/campaign.en.json +31 -0
- package/templates/storefront/themes/nouvel-an/campaign.fr.json +31 -0
- package/templates/storefront/themes/nouvel-an/theme.json +9 -0
- package/templates/storefront/themes/thanksgiving/campaign.en.json +31 -0
- package/templates/storefront/themes/thanksgiving/campaign.fr.json +31 -0
- package/templates/storefront/themes/thanksgiving/theme.json +9 -0
- package/templates/storefront/tsconfig.json +53 -0
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
"use server"
|
|
2
|
+
|
|
3
|
+
import { sdk } from "@lib/config"
|
|
4
|
+
import medusaError from "@lib/util/medusa-error"
|
|
5
|
+
import { HttpTypes } from "@medusajs/types"
|
|
6
|
+
import { updateTag } from "next/cache"
|
|
7
|
+
import { redirect } from "next/navigation"
|
|
8
|
+
import {
|
|
9
|
+
getAuthHeaders,
|
|
10
|
+
getCacheOptions,
|
|
11
|
+
getCacheTag,
|
|
12
|
+
getCartId,
|
|
13
|
+
removeCartId,
|
|
14
|
+
setCartId,
|
|
15
|
+
} from "./cookies"
|
|
16
|
+
import { getRegion } from "./regions"
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Retrieves a cart by its ID. If no ID is provided, it will use the cart ID from the cookies.
|
|
20
|
+
* @param cartId - optional - The ID of the cart to retrieve.
|
|
21
|
+
* @returns The cart object if found, or null if not found.
|
|
22
|
+
*/
|
|
23
|
+
export async function retrieveCart(cartId?: string, fields?: string) {
|
|
24
|
+
const id = cartId || (await getCartId())
|
|
25
|
+
fields ??=
|
|
26
|
+
"*items, *region, *items.product, *items.variant, *items.thumbnail, *items.metadata, +items.total, *promotions, +shipping_methods.name"
|
|
27
|
+
|
|
28
|
+
if (!id) {
|
|
29
|
+
return null
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const headers = {
|
|
33
|
+
...(await getAuthHeaders()),
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const next = {
|
|
37
|
+
...(await getCacheOptions("carts")),
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return await sdk.client
|
|
41
|
+
.fetch<HttpTypes.StoreCartResponse>(`/store/carts/${id}`, {
|
|
42
|
+
method: "GET",
|
|
43
|
+
query: {
|
|
44
|
+
fields,
|
|
45
|
+
},
|
|
46
|
+
headers,
|
|
47
|
+
next,
|
|
48
|
+
cache: "force-cache",
|
|
49
|
+
})
|
|
50
|
+
.then(({ cart }: { cart: HttpTypes.StoreCart }) => cart)
|
|
51
|
+
.catch(() => null)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export async function getOrSetCart() {
|
|
55
|
+
const region = await getRegion()
|
|
56
|
+
|
|
57
|
+
let cart = await retrieveCart(undefined, "id,region_id")
|
|
58
|
+
|
|
59
|
+
const headers = {
|
|
60
|
+
...(await getAuthHeaders()),
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (!cart) {
|
|
64
|
+
const cartResp = await sdk.store.cart.create(
|
|
65
|
+
{ region_id: region.id },
|
|
66
|
+
{},
|
|
67
|
+
headers
|
|
68
|
+
)
|
|
69
|
+
cart = cartResp.cart
|
|
70
|
+
|
|
71
|
+
await setCartId(cart.id)
|
|
72
|
+
|
|
73
|
+
const cartCacheTag = await getCacheTag("carts")
|
|
74
|
+
updateTag(cartCacheTag)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (cart && cart?.region_id !== region.id) {
|
|
78
|
+
await sdk.store.cart.update(cart.id, { region_id: region.id }, {}, headers)
|
|
79
|
+
const cartCacheTag = await getCacheTag("carts")
|
|
80
|
+
updateTag(cartCacheTag)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return cart
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export async function updateCart(data: HttpTypes.StoreUpdateCart) {
|
|
87
|
+
const cartId = await getCartId()
|
|
88
|
+
|
|
89
|
+
if (!cartId) {
|
|
90
|
+
throw new Error("No existing cart found, please create one before updating")
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const headers = {
|
|
94
|
+
...(await getAuthHeaders()),
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return sdk.store.cart
|
|
98
|
+
.update(cartId, data, {}, headers)
|
|
99
|
+
.then(async ({ cart }: { cart: HttpTypes.StoreCart }) => {
|
|
100
|
+
const cartCacheTag = await getCacheTag("carts")
|
|
101
|
+
updateTag(cartCacheTag)
|
|
102
|
+
|
|
103
|
+
const fulfillmentCacheTag = await getCacheTag("fulfillment")
|
|
104
|
+
updateTag(fulfillmentCacheTag)
|
|
105
|
+
|
|
106
|
+
return cart
|
|
107
|
+
})
|
|
108
|
+
.catch(medusaError)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export async function addToCart({
|
|
112
|
+
variantId,
|
|
113
|
+
quantity,
|
|
114
|
+
}: {
|
|
115
|
+
variantId: string
|
|
116
|
+
quantity: number
|
|
117
|
+
}) {
|
|
118
|
+
if (!variantId) {
|
|
119
|
+
throw new Error("Missing variant ID when adding to cart")
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const cart = await getOrSetCart()
|
|
123
|
+
|
|
124
|
+
if (!cart) {
|
|
125
|
+
throw new Error("Error retrieving or creating cart")
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const headers = {
|
|
129
|
+
...(await getAuthHeaders()),
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
await sdk.store.cart
|
|
133
|
+
.createLineItem(
|
|
134
|
+
cart.id,
|
|
135
|
+
{
|
|
136
|
+
variant_id: variantId,
|
|
137
|
+
quantity,
|
|
138
|
+
},
|
|
139
|
+
{},
|
|
140
|
+
headers
|
|
141
|
+
)
|
|
142
|
+
.then(async () => {
|
|
143
|
+
const cartCacheTag = await getCacheTag("carts")
|
|
144
|
+
updateTag(cartCacheTag)
|
|
145
|
+
|
|
146
|
+
const fulfillmentCacheTag = await getCacheTag("fulfillment")
|
|
147
|
+
updateTag(fulfillmentCacheTag)
|
|
148
|
+
})
|
|
149
|
+
.catch(medusaError)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export async function updateLineItem({
|
|
153
|
+
lineId,
|
|
154
|
+
quantity,
|
|
155
|
+
}: {
|
|
156
|
+
lineId: string
|
|
157
|
+
quantity: number
|
|
158
|
+
}) {
|
|
159
|
+
if (!lineId) {
|
|
160
|
+
throw new Error("Missing lineItem ID when updating line item")
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const cartId = await getCartId()
|
|
164
|
+
|
|
165
|
+
if (!cartId) {
|
|
166
|
+
throw new Error("Missing cart ID when updating line item")
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const headers = {
|
|
170
|
+
...(await getAuthHeaders()),
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
await sdk.store.cart
|
|
174
|
+
.updateLineItem(cartId, lineId, { quantity }, {}, headers)
|
|
175
|
+
.then(async () => {
|
|
176
|
+
const cartCacheTag = await getCacheTag("carts")
|
|
177
|
+
updateTag(cartCacheTag)
|
|
178
|
+
|
|
179
|
+
const fulfillmentCacheTag = await getCacheTag("fulfillment")
|
|
180
|
+
updateTag(fulfillmentCacheTag)
|
|
181
|
+
})
|
|
182
|
+
.catch(medusaError)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export async function deleteLineItem(lineId: string) {
|
|
186
|
+
if (!lineId) {
|
|
187
|
+
throw new Error("Missing lineItem ID when deleting line item")
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const cartId = await getCartId()
|
|
191
|
+
|
|
192
|
+
if (!cartId) {
|
|
193
|
+
throw new Error("Missing cart ID when deleting line item")
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const headers = {
|
|
197
|
+
...(await getAuthHeaders()),
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
await sdk.store.cart
|
|
201
|
+
.deleteLineItem(cartId, lineId, {}, headers)
|
|
202
|
+
.then(async () => {
|
|
203
|
+
const cartCacheTag = await getCacheTag("carts")
|
|
204
|
+
updateTag(cartCacheTag)
|
|
205
|
+
|
|
206
|
+
const fulfillmentCacheTag = await getCacheTag("fulfillment")
|
|
207
|
+
updateTag(fulfillmentCacheTag)
|
|
208
|
+
})
|
|
209
|
+
.catch(medusaError)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export async function setShippingMethod({
|
|
213
|
+
cartId,
|
|
214
|
+
shippingMethodId,
|
|
215
|
+
}: {
|
|
216
|
+
cartId: string
|
|
217
|
+
shippingMethodId: string
|
|
218
|
+
}) {
|
|
219
|
+
const headers = {
|
|
220
|
+
...(await getAuthHeaders()),
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return sdk.store.cart
|
|
224
|
+
.addShippingMethod(cartId, { option_id: shippingMethodId }, {}, headers)
|
|
225
|
+
.then(async () => {
|
|
226
|
+
const cartCacheTag = await getCacheTag("carts")
|
|
227
|
+
updateTag(cartCacheTag)
|
|
228
|
+
})
|
|
229
|
+
.catch(medusaError)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export async function initiatePaymentSession(
|
|
233
|
+
cart: HttpTypes.StoreCart,
|
|
234
|
+
data: HttpTypes.StoreInitializePaymentSession
|
|
235
|
+
) {
|
|
236
|
+
const headers = {
|
|
237
|
+
...(await getAuthHeaders()),
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return sdk.store.payment
|
|
241
|
+
.initiatePaymentSession(cart, data, {}, headers)
|
|
242
|
+
.then(async (resp) => {
|
|
243
|
+
const cartCacheTag = await getCacheTag("carts")
|
|
244
|
+
updateTag(cartCacheTag)
|
|
245
|
+
return resp
|
|
246
|
+
})
|
|
247
|
+
.catch(medusaError)
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export async function applyPromotions(codes: string[]) {
|
|
251
|
+
const cartId = await getCartId()
|
|
252
|
+
|
|
253
|
+
if (!cartId) {
|
|
254
|
+
throw new Error("No existing cart found")
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const headers = {
|
|
258
|
+
...(await getAuthHeaders()),
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return sdk.store.cart
|
|
262
|
+
.update(cartId, { promo_codes: codes }, {}, headers)
|
|
263
|
+
.then(async () => {
|
|
264
|
+
const cartCacheTag = await getCacheTag("carts")
|
|
265
|
+
updateTag(cartCacheTag)
|
|
266
|
+
|
|
267
|
+
const fulfillmentCacheTag = await getCacheTag("fulfillment")
|
|
268
|
+
updateTag(fulfillmentCacheTag)
|
|
269
|
+
})
|
|
270
|
+
.catch(medusaError)
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export async function applyGiftCard(code: string) {
|
|
274
|
+
// const cartId = getCartId()
|
|
275
|
+
// if (!cartId) return "No cartId cookie found"
|
|
276
|
+
// try {
|
|
277
|
+
// await updateCart(cartId, { gift_cards: [{ code }] }).then(() => {
|
|
278
|
+
// revalidateTag("cart")
|
|
279
|
+
// })
|
|
280
|
+
// } catch (error: any) {
|
|
281
|
+
// throw error
|
|
282
|
+
// }
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export async function removeDiscount(code: string) {
|
|
286
|
+
// const cartId = getCartId()
|
|
287
|
+
// if (!cartId) return "No cartId cookie found"
|
|
288
|
+
// try {
|
|
289
|
+
// await deleteDiscount(cartId, code)
|
|
290
|
+
// revalidateTag("cart")
|
|
291
|
+
// } catch (error: any) {
|
|
292
|
+
// throw error
|
|
293
|
+
// }
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export async function removeGiftCard(
|
|
297
|
+
codeToRemove: string,
|
|
298
|
+
giftCards: any[]
|
|
299
|
+
// giftCards: GiftCard[]
|
|
300
|
+
) {
|
|
301
|
+
// const cartId = getCartId()
|
|
302
|
+
// if (!cartId) return "No cartId cookie found"
|
|
303
|
+
// try {
|
|
304
|
+
// await updateCart(cartId, {
|
|
305
|
+
// gift_cards: [...giftCards]
|
|
306
|
+
// .filter((gc) => gc.code !== codeToRemove)
|
|
307
|
+
// .map((gc) => ({ code: gc.code })),
|
|
308
|
+
// }).then(() => {
|
|
309
|
+
// revalidateTag("cart")
|
|
310
|
+
// })
|
|
311
|
+
// } catch (error: any) {
|
|
312
|
+
// throw error
|
|
313
|
+
// }
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export async function submitPromotionForm(
|
|
317
|
+
currentState: unknown,
|
|
318
|
+
formData: FormData
|
|
319
|
+
) {
|
|
320
|
+
const code = formData.get("code") as string
|
|
321
|
+
try {
|
|
322
|
+
await applyPromotions([code])
|
|
323
|
+
} catch (e: any) {
|
|
324
|
+
return e.message
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// TODO: Pass a POJO instead of a form entity here
|
|
329
|
+
export async function setAddresses(currentState: unknown, formData: FormData) {
|
|
330
|
+
try {
|
|
331
|
+
if (!formData) {
|
|
332
|
+
throw new Error("No form data found when setting addresses")
|
|
333
|
+
}
|
|
334
|
+
const cartId = getCartId()
|
|
335
|
+
if (!cartId) {
|
|
336
|
+
throw new Error("No existing cart found when setting addresses")
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
const data = {
|
|
340
|
+
shipping_address: {
|
|
341
|
+
first_name: formData.get("shipping_address.first_name"),
|
|
342
|
+
last_name: formData.get("shipping_address.last_name"),
|
|
343
|
+
address_1: formData.get("shipping_address.address_1"),
|
|
344
|
+
address_2: "",
|
|
345
|
+
company: formData.get("shipping_address.company"),
|
|
346
|
+
postal_code: formData.get("shipping_address.postal_code"),
|
|
347
|
+
city: formData.get("shipping_address.city"),
|
|
348
|
+
country_code: formData.get("shipping_address.country_code"),
|
|
349
|
+
province: formData.get("shipping_address.province"),
|
|
350
|
+
phone: formData.get("shipping_address.phone"),
|
|
351
|
+
},
|
|
352
|
+
email: formData.get("email"),
|
|
353
|
+
} as any
|
|
354
|
+
|
|
355
|
+
const sameAsBilling = formData.get("same_as_billing")
|
|
356
|
+
if (sameAsBilling === "on") data.billing_address = data.shipping_address
|
|
357
|
+
|
|
358
|
+
if (sameAsBilling !== "on")
|
|
359
|
+
data.billing_address = {
|
|
360
|
+
first_name: formData.get("billing_address.first_name"),
|
|
361
|
+
last_name: formData.get("billing_address.last_name"),
|
|
362
|
+
address_1: formData.get("billing_address.address_1"),
|
|
363
|
+
address_2: "",
|
|
364
|
+
company: formData.get("billing_address.company"),
|
|
365
|
+
postal_code: formData.get("billing_address.postal_code"),
|
|
366
|
+
city: formData.get("billing_address.city"),
|
|
367
|
+
country_code: formData.get("billing_address.country_code"),
|
|
368
|
+
province: formData.get("billing_address.province"),
|
|
369
|
+
phone: formData.get("billing_address.phone"),
|
|
370
|
+
}
|
|
371
|
+
await updateCart(data)
|
|
372
|
+
} catch (e: any) {
|
|
373
|
+
return e.message
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
redirect(
|
|
377
|
+
`/checkout?step=delivery`
|
|
378
|
+
)
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Places an order for a cart. If no cart ID is provided, it will use the cart ID from the cookies.
|
|
383
|
+
* @param cartId - optional - The ID of the cart to place an order for.
|
|
384
|
+
* @returns The cart object if the order was successful, or null if not.
|
|
385
|
+
*/
|
|
386
|
+
export async function placeOrder(cartId?: string) {
|
|
387
|
+
const id = cartId || (await getCartId())
|
|
388
|
+
|
|
389
|
+
if (!id) {
|
|
390
|
+
throw new Error("No existing cart found when placing an order")
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
const headers = {
|
|
394
|
+
...(await getAuthHeaders()),
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
const cartRes = await sdk.store.cart
|
|
398
|
+
.complete(id, {}, headers)
|
|
399
|
+
.then(async (cartRes) => {
|
|
400
|
+
const cartCacheTag = await getCacheTag("carts")
|
|
401
|
+
updateTag(cartCacheTag)
|
|
402
|
+
return cartRes
|
|
403
|
+
})
|
|
404
|
+
.catch(medusaError)
|
|
405
|
+
|
|
406
|
+
if (cartRes?.type === "order") {
|
|
407
|
+
const orderCacheTag = await getCacheTag("orders")
|
|
408
|
+
updateTag(orderCacheTag)
|
|
409
|
+
|
|
410
|
+
removeCartId()
|
|
411
|
+
redirect(`/order/${cartRes?.order.id}/confirmed`)
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
return cartRes.cart
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
export async function listCartOptions() {
|
|
418
|
+
const cartId = await getCartId()
|
|
419
|
+
const headers = {
|
|
420
|
+
...(await getAuthHeaders()),
|
|
421
|
+
}
|
|
422
|
+
const next = {
|
|
423
|
+
...(await getCacheOptions("shippingOptions")),
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
return await sdk.client.fetch<{
|
|
427
|
+
shipping_options: HttpTypes.StoreCartShippingOption[]
|
|
428
|
+
}>("/store/shipping-options", {
|
|
429
|
+
query: { cart_id: cartId },
|
|
430
|
+
next,
|
|
431
|
+
headers,
|
|
432
|
+
cache: "force-cache",
|
|
433
|
+
})
|
|
434
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { sdk } from "@lib/config"
|
|
2
|
+
import { HttpTypes } from "@medusajs/types"
|
|
3
|
+
import { getCacheOptions } from "./cookies"
|
|
4
|
+
|
|
5
|
+
export const listCategories = async (query?: Record<string, any>) => {
|
|
6
|
+
const next = {
|
|
7
|
+
...(await getCacheOptions("categories")),
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const limit = query?.limit || 100
|
|
11
|
+
|
|
12
|
+
return sdk.client
|
|
13
|
+
.fetch<{ product_categories: HttpTypes.StoreProductCategory[] }>(
|
|
14
|
+
"/store/product-categories",
|
|
15
|
+
{
|
|
16
|
+
query: {
|
|
17
|
+
fields:
|
|
18
|
+
"+metadata, *category_children, *products, *parent_category, *parent_category.parent_category",
|
|
19
|
+
limit,
|
|
20
|
+
...query,
|
|
21
|
+
},
|
|
22
|
+
next,
|
|
23
|
+
cache: "force-cache",
|
|
24
|
+
}
|
|
25
|
+
)
|
|
26
|
+
.then(({ product_categories }) => product_categories)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const getCategoryByHandle = async (categoryHandle: string[]) => {
|
|
30
|
+
const handle = `${categoryHandle.join("/")}`
|
|
31
|
+
|
|
32
|
+
const next = {
|
|
33
|
+
...(await getCacheOptions("categories")),
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return sdk.client
|
|
37
|
+
.fetch<HttpTypes.StoreProductCategoryListResponse>(
|
|
38
|
+
`/store/product-categories`,
|
|
39
|
+
{
|
|
40
|
+
query: {
|
|
41
|
+
fields: "*category_children, *products",
|
|
42
|
+
handle,
|
|
43
|
+
},
|
|
44
|
+
next,
|
|
45
|
+
cache: "force-cache",
|
|
46
|
+
}
|
|
47
|
+
)
|
|
48
|
+
.then(({ product_categories }) => product_categories[0])
|
|
49
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use server"
|
|
2
|
+
|
|
3
|
+
import { sdk } from "@lib/config"
|
|
4
|
+
import { HttpTypes } from "@medusajs/types"
|
|
5
|
+
import { getCacheOptions } from "./cookies"
|
|
6
|
+
|
|
7
|
+
export const retrieveCollection = async (id: string) => {
|
|
8
|
+
const next = {
|
|
9
|
+
...(await getCacheOptions("collections")),
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return sdk.client
|
|
13
|
+
.fetch<{ collection: HttpTypes.StoreCollection }>(
|
|
14
|
+
`/store/collections/${id}`,
|
|
15
|
+
{
|
|
16
|
+
next,
|
|
17
|
+
cache: "force-cache",
|
|
18
|
+
}
|
|
19
|
+
)
|
|
20
|
+
.then(({ collection }) => collection)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const listCollections = async (
|
|
24
|
+
queryParams: Record<string, string> = {}
|
|
25
|
+
): Promise<{ collections: HttpTypes.StoreCollection[]; count: number }> => {
|
|
26
|
+
const next = {
|
|
27
|
+
...(await getCacheOptions("collections")),
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
queryParams.limit = queryParams.limit || "100"
|
|
31
|
+
queryParams.offset = queryParams.offset || "0"
|
|
32
|
+
|
|
33
|
+
return sdk.client
|
|
34
|
+
.fetch<{ collections: HttpTypes.StoreCollection[]; count: number }>(
|
|
35
|
+
"/store/collections",
|
|
36
|
+
{
|
|
37
|
+
query: queryParams,
|
|
38
|
+
next,
|
|
39
|
+
cache: "force-cache",
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
.then(({ collections }) => ({ collections, count: collections.length }))
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export const getCollectionByHandle = async (
|
|
46
|
+
handle: string
|
|
47
|
+
): Promise<HttpTypes.StoreCollection> => {
|
|
48
|
+
const next = {
|
|
49
|
+
...(await getCacheOptions("collections")),
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return sdk.client
|
|
53
|
+
.fetch<HttpTypes.StoreCollectionListResponse>(`/store/collections`, {
|
|
54
|
+
query: { handle, fields: "*products" },
|
|
55
|
+
next,
|
|
56
|
+
cache: "force-cache",
|
|
57
|
+
})
|
|
58
|
+
.then(({ collections }) => collections[0])
|
|
59
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import "server-only"
|
|
2
|
+
import { getBoutique } from "@lib/boutique/config"
|
|
3
|
+
import { cookies as nextCookies } from "next/headers"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Les cookies ne dépendent pas du port : sur localhost (ou un même domaine),
|
|
7
|
+
* toutes les boutiques du projet les partagent. Chaque nom est donc suffixé
|
|
8
|
+
* par le slug, pour qu'un panier ou une session d'une boutique n'apparaisse
|
|
9
|
+
* jamais dans une autre.
|
|
10
|
+
*/
|
|
11
|
+
export const cookieName = (base: "jwt" | "cart_id" | "cache_id" | "onboarding") =>
|
|
12
|
+
`_medusa_${base}_${getBoutique().slug}`
|
|
13
|
+
|
|
14
|
+
export const getAuthHeaders = async (): Promise<
|
|
15
|
+
{ authorization: string } | {}
|
|
16
|
+
> => {
|
|
17
|
+
try {
|
|
18
|
+
const cookies = await nextCookies()
|
|
19
|
+
const token = cookies.get(cookieName("jwt"))?.value
|
|
20
|
+
|
|
21
|
+
if (!token) {
|
|
22
|
+
return {}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return { authorization: `Bearer ${token}` }
|
|
26
|
+
} catch {
|
|
27
|
+
return {}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const getCacheTag = async (tag: string): Promise<string> => {
|
|
32
|
+
try {
|
|
33
|
+
const cookies = await nextCookies()
|
|
34
|
+
const cacheId = cookies.get(cookieName("cache_id"))?.value
|
|
35
|
+
|
|
36
|
+
if (!cacheId) {
|
|
37
|
+
return ""
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return `${tag}-${cacheId}`
|
|
41
|
+
} catch (error) {
|
|
42
|
+
return ""
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Cache des requêtes Medusa. Les tags (par visiteur) permettent aux server actions
|
|
48
|
+
* d'expirer panier / compte immédiatement ; `revalidate` fait apparaître en 60 s
|
|
49
|
+
* les changements faits dans l'admin (produits, prix, catégories) pour tout le monde.
|
|
50
|
+
* Sans lui, le starter gardait le catalogue en cache jusqu'au redémarrage.
|
|
51
|
+
*/
|
|
52
|
+
export const getCacheOptions = async (
|
|
53
|
+
tag: string
|
|
54
|
+
): Promise<{ tags?: string[]; revalidate: number }> => {
|
|
55
|
+
if (typeof window !== "undefined") {
|
|
56
|
+
return { revalidate: 60 }
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const cacheTag = await getCacheTag(tag)
|
|
60
|
+
|
|
61
|
+
return cacheTag ? { tags: [cacheTag], revalidate: 60 } : { revalidate: 60 }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const secureCookie = {
|
|
65
|
+
httpOnly: true,
|
|
66
|
+
sameSite: "strict" as const,
|
|
67
|
+
secure: process.env.NODE_ENV === "production",
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export const setAuthToken = async (token: string) => {
|
|
71
|
+
const cookies = await nextCookies()
|
|
72
|
+
cookies.set(cookieName("jwt"), token, {
|
|
73
|
+
...secureCookie,
|
|
74
|
+
maxAge: 60 * 60 * 24 * 7,
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export const removeAuthToken = async () => {
|
|
79
|
+
const cookies = await nextCookies()
|
|
80
|
+
cookies.set(cookieName("jwt"), "", {
|
|
81
|
+
maxAge: -1,
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export const getCartId = async () => {
|
|
86
|
+
const cookies = await nextCookies()
|
|
87
|
+
return cookies.get(cookieName("cart_id"))?.value
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export const setCartId = async (cartId: string) => {
|
|
91
|
+
const cookies = await nextCookies()
|
|
92
|
+
cookies.set(cookieName("cart_id"), cartId, {
|
|
93
|
+
...secureCookie,
|
|
94
|
+
maxAge: 60 * 60 * 24 * 7,
|
|
95
|
+
})
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export const removeCartId = async () => {
|
|
99
|
+
const cookies = await nextCookies()
|
|
100
|
+
cookies.set(cookieName("cart_id"), "", {
|
|
101
|
+
maxAge: -1,
|
|
102
|
+
})
|
|
103
|
+
}
|