diff --git a/.changeset/afraid-steaks-explode.md b/.changeset/afraid-steaks-explode.md new file mode 100644 index 000000000..7e98ba1b0 --- /dev/null +++ b/.changeset/afraid-steaks-explode.md @@ -0,0 +1,5 @@ +--- +"@bigcommerce/catalyst-client": minor +--- + +Remove the `fetchAvailableCountries` query as it is no longer needed in Catalyst. This helps us remove queries that are dependent on the access token. diff --git a/.changeset/silly-spies-behave.md b/.changeset/silly-spies-behave.md new file mode 100644 index 000000000..92dde848d --- /dev/null +++ b/.changeset/silly-spies-behave.md @@ -0,0 +1,5 @@ +--- +"@bigcommerce/catalyst-core": patch +--- + +Use the `geography` node to retrieve a list of countries. This removes one less dependency on the access token. diff --git a/core/app/[locale]/(default)/cart/_components/checkout-summary.tsx b/core/app/[locale]/(default)/cart/_components/checkout-summary.tsx index c32def948..c3d85234e 100644 --- a/core/app/[locale]/(default)/cart/_components/checkout-summary.tsx +++ b/core/app/[locale]/(default)/cart/_components/checkout-summary.tsx @@ -6,7 +6,7 @@ import { FragmentOf, graphql } from '~/client/graphql'; import { CouponCode } from './coupon-code'; import { CouponCodeFragment } from './coupon-code/fragment'; import { ShippingEstimator } from './shipping-estimator'; -import { ShippingEstimatorFragment } from './shipping-estimator/fragment'; +import { GeographyFragment, ShippingEstimatorFragment } from './shipping-estimator/fragment'; import { getShippingCountries } from './shipping-estimator/get-shipping-countries'; const MoneyFieldsFragment = graphql(` @@ -42,18 +42,19 @@ export const CheckoutSummaryFragment = graphql( ); interface Props { - data: FragmentOf; + checkout: FragmentOf; + geography: FragmentOf; } -export const CheckoutSummary = async ({ data }: Props) => { +export const CheckoutSummary = async ({ checkout, geography }: Props) => { const locale = await getLocale(); const t = await getTranslations({ locale, namespace: 'Cart.CheckoutSummary' }); const format = await getFormatter({ locale }); const messages = await getMessages({ locale }); - const shippingCountries = await getShippingCountries(); + const { cart, grandTotal, subtotal, taxTotal } = checkout; - const { cart, grandTotal, subtotal, taxTotal } = data; + const shippingCountries = await getShippingCountries({ geography }); return ( <> @@ -68,7 +69,7 @@ export const CheckoutSummary = async ({ data }: Props) => { - + {cart?.discountedAmount && ( @@ -85,7 +86,7 @@ export const CheckoutSummary = async ({ data }: Props) => { )} - + {taxTotal && ( diff --git a/core/app/[locale]/(default)/cart/_components/shipping-estimator/fragment.ts b/core/app/[locale]/(default)/cart/_components/shipping-estimator/fragment.ts index 53474742a..991d0325d 100644 --- a/core/app/[locale]/(default)/cart/_components/shipping-estimator/fragment.ts +++ b/core/app/[locale]/(default)/cart/_components/shipping-estimator/fragment.ts @@ -29,3 +29,16 @@ export const ShippingEstimatorFragment = graphql( `, [ShippingOptionsFragment, ShippingInfoFragment], ); + +export const GeographyFragment = graphql( + ` + fragment GeographyFragment on Geography { + countries { + entityId + name + code + } + } + `, + [], +); diff --git a/core/app/[locale]/(default)/cart/_components/shipping-estimator/get-shipping-countries.ts b/core/app/[locale]/(default)/cart/_components/shipping-estimator/get-shipping-countries.ts index f7a67a481..82c0add91 100644 --- a/core/app/[locale]/(default)/cart/_components/shipping-estimator/get-shipping-countries.ts +++ b/core/app/[locale]/(default)/cart/_components/shipping-estimator/get-shipping-countries.ts @@ -1,8 +1,15 @@ -import { getCountries } from '~/client/management/get-countries'; +import { FragmentOf } from 'gql.tada'; + import { getShippingZones } from '~/client/management/get-shipping-zones'; -export const getShippingCountries = async () => { - const [shippingZones, allCountries] = await Promise.all([getShippingZones(), getCountries()]); +import { GeographyFragment } from './fragment'; + +interface GetShippingCountries { + geography: FragmentOf; +} + +export const getShippingCountries = async ({ geography }: GetShippingCountries) => { + const shippingZones = await getShippingZones(); const uniqueCountryZones = shippingZones.reduce((zones, item) => { item.locations.forEach(({ country_iso2 }) => { @@ -24,11 +31,12 @@ export const getShippingCountries = async () => { return zones; }, []); - const shippingCountries = allCountries.flatMap((countryDetails) => { - const isCountryInTheList = uniqueCountryZones.includes(countryDetails.country_iso2); + const countries = geography.countries ?? []; + const shippingCountries = countries.flatMap((countryDetails) => { + const isCountryInTheList = uniqueCountryZones.includes(countryDetails.code); if (isCountryInTheList) { - const { id, country: name, country_iso2: countryCode } = countryDetails; + const { entityId: id, name, code: countryCode } = countryDetails; return { id, name, countryCode }; } diff --git a/core/app/[locale]/(default)/cart/page.tsx b/core/app/[locale]/(default)/cart/page.tsx index 818adcf4a..7640d7ea8 100644 --- a/core/app/[locale]/(default)/cart/page.tsx +++ b/core/app/[locale]/(default)/cart/page.tsx @@ -12,6 +12,7 @@ import { CartItem, CartItemFragment } from './_components/cart-item'; import { CheckoutButton } from './_components/checkout-button'; import { CheckoutSummary, CheckoutSummaryFragment } from './_components/checkout-summary'; import { EmptyCart } from './_components/empty-cart'; +import { GeographyFragment } from './_components/shipping-estimator/fragment'; export const metadata = { title: 'Cart', @@ -38,9 +39,12 @@ const CartPageQuery = graphql( ...CheckoutSummaryFragment } } + geography { + ...GeographyFragment + } } `, - [CartItemFragment, CheckoutSummaryFragment], + [CartItemFragment, CheckoutSummaryFragment, GeographyFragment], ); export default async function CartPage({ params: { locale } }: Props) { @@ -70,6 +74,7 @@ export default async function CartPage({ params: { locale } }: Props) { const cart = data.site.cart; const checkout = data.site.checkout; + const geography = data.geography; if (!cart) { return ; @@ -88,7 +93,7 @@ export default async function CartPage({ params: { locale } }: Props) {
- {checkout && } + {checkout && } diff --git a/core/client/management/get-countries.ts b/core/client/management/get-countries.ts deleted file mode 100644 index a770f875f..000000000 --- a/core/client/management/get-countries.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { z } from 'zod'; - -import { client } from '..'; - -const CountriesListSchema = z.array( - z.object({ - id: z.number().min(1), - country: z.string().min(1), - country_iso2: z.string(), - country_iso3: z.string(), - states: z.object({ - url: z.string(), - resource: z.string(), - }), - }), -); - -// List of available countries -export const getCountries = async () => { - const response = await client.fetchAvailableCountries(); - const parsedResponse = CountriesListSchema.safeParse(response); - - if (parsedResponse.success) { - return parsedResponse.data; - } - - throw new Error('Unable to get data on Countries: Invalid response'); -}; diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 6dd9f70de..d593c8a53 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -105,27 +105,6 @@ class Client { return response.json() as Promise>; } - async fetchAvailableCountries() { - const response = await fetch( - `https://${adminApiHostname}/stores/${this.config.storeHash}/v2/countries?limit=250`, - { - method: 'GET', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - 'X-Auth-Token': this.config.xAuthToken, - 'User-Agent': this.backendUserAgent, - }, - }, - ); - - if (!response.ok) { - throw new Error(`Unable to get available Countries List: ${response.statusText}`); - } - - return response.json() as Promise; - } - async fetchCountryStates(id: number) { const response = await fetch( `https://${adminApiHostname}/stores/${this.config.storeHash}/v2/countries/${id}/states?limit=60`,