From e10d50c55a98820d738d0c795cdd32f1015336ba Mon Sep 17 00:00:00 2001 From: Bel Curcio Date: Thu, 25 Feb 2021 06:27:56 -0300 Subject: [PATCH 1/2] shopify: changes --- framework/commerce/with-config.js | 2 +- framework/shopify/api/index.ts | 1 - .../shopify/api/utils/fetch-graphql-api.ts | 2 +- framework/shopify/cart/use-cart.tsx | 11 ++++-- framework/shopify/config.json | 5 +++ framework/shopify/next.config.js | 11 ++++++ framework/shopify/product/use-price.tsx | 4 +-- framework/shopify/provider.ts | 34 +++++++++++++++++++ 8 files changed, 62 insertions(+), 8 deletions(-) create mode 100644 framework/shopify/config.json create mode 100644 framework/shopify/next.config.js create mode 100644 framework/shopify/provider.ts diff --git a/framework/commerce/with-config.js b/framework/commerce/with-config.js index 6dcf08986..da6705cef 100644 --- a/framework/commerce/with-config.js +++ b/framework/commerce/with-config.js @@ -4,7 +4,7 @@ const merge = require('deepmerge') -const PROVIDERS = ['bigcommerce'] +const PROVIDERS = ['bigcommerce', 'shopify'] function getProviderName() { return process.env.BIGCOMMERCE_STOREFRONT_API_URL ? 'bigcommerce' : null diff --git a/framework/shopify/api/index.ts b/framework/shopify/api/index.ts index 0402cfccc..1da7f31c6 100644 --- a/framework/shopify/api/index.ts +++ b/framework/shopify/api/index.ts @@ -3,7 +3,6 @@ import fetchGraphqlApi from './utils/fetch-graphql-api' export interface ShopifyConfig extends CommerceAPIConfig {} -// TODO(bc) const API_URL = process.env.SHOPIFY_STORE_DOMAIN || process.env.NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN diff --git a/framework/shopify/api/utils/fetch-graphql-api.ts b/framework/shopify/api/utils/fetch-graphql-api.ts index 946242c93..f3f8b9a17 100644 --- a/framework/shopify/api/utils/fetch-graphql-api.ts +++ b/framework/shopify/api/utils/fetch-graphql-api.ts @@ -21,7 +21,7 @@ const fetchGraphqlApi: GraphQLFetcher = async ( fetchOptions ) => { const config = getConfig() - const url = `https://${config.commerceUrl}/api/2020-10/graphql.json` + const url = `https://${config.commerceUrl}/api/2021-01/graphql.json` const res = await fetch(url, { ...fetchOptions, diff --git a/framework/shopify/cart/use-cart.tsx b/framework/shopify/cart/use-cart.tsx index f067b520d..e69afda0c 100644 --- a/framework/shopify/cart/use-cart.tsx +++ b/framework/shopify/cart/use-cart.tsx @@ -1,9 +1,16 @@ import { useCommerce } from '../index' +import useCart, { UseCart, FetchCartInput } from '@commerce/cart/use-cart' +import type { Cart } from '../types' -export function emptyHook() { +// export default useCart as UseCart +export default useCart as UseCart + +export const handler = () => { const { checkout } = useCommerce() const { lineItems, totalPriceV2 } = checkout || {} + console.log(checkout) + return { data: { subTotal: totalPriceV2?.amount || 0, @@ -38,5 +45,3 @@ export function emptyHook() { isLoading: false, } } - -export default emptyHook diff --git a/framework/shopify/config.json b/framework/shopify/config.json new file mode 100644 index 000000000..17ef37e25 --- /dev/null +++ b/framework/shopify/config.json @@ -0,0 +1,5 @@ +{ + "features": { + "wishlist": false + } +} diff --git a/framework/shopify/next.config.js b/framework/shopify/next.config.js new file mode 100644 index 000000000..0f9bc31ff --- /dev/null +++ b/framework/shopify/next.config.js @@ -0,0 +1,11 @@ +const providerConfig = require('./config.json') + +module.exports = { + commerce: { + provider: 'shopify', + ...providerConfig, + }, + images: { + domains: ['cdn.shopify.com'], + }, +} diff --git a/framework/shopify/product/use-price.tsx b/framework/shopify/product/use-price.tsx index a79940a76..0174faf5e 100644 --- a/framework/shopify/product/use-price.tsx +++ b/framework/shopify/product/use-price.tsx @@ -1,2 +1,2 @@ -export * from '@commerce/use-price' -export { default } from '@commerce/use-price' +export * from '@commerce/product/use-price' +export { default } from '@commerce/product/use-price' diff --git a/framework/shopify/provider.ts b/framework/shopify/provider.ts new file mode 100644 index 000000000..31b958a21 --- /dev/null +++ b/framework/shopify/provider.ts @@ -0,0 +1,34 @@ +import { handler as useCart } from './cart/use-cart' +import { handler as useAddItem } from './cart/use-add-item' +import { handler as useUpdateItem } from './cart/use-update-item' +import { handler as useRemoveItem } from './cart/use-remove-item' + +import { handler as useWishlist } from './wishlist/use-wishlist' +import { handler as useWishlistAddItem } from './wishlist/use-add-item' +import { handler as useWishlistRemoveItem } from './wishlist/use-remove-item' + +import { handler as useCustomer } from './customer/use-customer' +import { handler as useSearch } from './product/use-search' + +import { handler as useLogin } from './auth/use-login' +import { handler as useLogout } from './auth/use-logout' +import { handler as useSignup } from './auth/use-signup' + +import fetcher from './fetcher' + +export const shopifyProvider = { + locale: 'en-us', + cartCookie: 'sp_cartId', + fetcher, + cart: { useCart, useAddItem, useUpdateItem, useRemoveItem }, + wishlist: { + useWishlist, + useAddItem: useWishlistAddItem, + useRemoveItem: useWishlistRemoveItem, + }, + customer: { useCustomer }, + products: { useSearch }, + auth: { useLogin, useLogout, useSignup }, +} + +export type ShopifyProvider = typeof shopifyProvider From 3b386e3d55dddcf94d62ca19e8411be49d6378f6 Mon Sep 17 00:00:00 2001 From: Bel Curcio Date: Thu, 25 Feb 2021 07:48:14 -0300 Subject: [PATCH 2/2] shopify: changes --- .../WishlistButton/WishlistButton.tsx | 6 +-- framework/shopify/api/index.ts | 9 ++-- framework/shopify/fetcher.ts | 51 ++++++++++++++++++ package.json | 3 +- yarn.lock | 53 ++++++++++--------- 5 files changed, 88 insertions(+), 34 deletions(-) create mode 100644 framework/shopify/fetcher.ts diff --git a/components/wishlist/WishlistButton/WishlistButton.tsx b/components/wishlist/WishlistButton/WishlistButton.tsx index 5a1f17e5c..57f769e3d 100644 --- a/components/wishlist/WishlistButton/WishlistButton.tsx +++ b/components/wishlist/WishlistButton/WishlistButton.tsx @@ -1,12 +1,12 @@ import React, { FC, useState } from 'react' import cn from 'classnames' - import { useUI } from '@components/ui' -import type { Product, ProductVariant } from '@commerce/types' +import { Heart } from '@components/icons' import useAddItem from '@framework/wishlist/use-add-item' import useCustomer from '@framework/customer/use-customer' -import useRemoveItem from '@framework/wishlist/use-remove-item' import useWishlist from '@framework/wishlist/use-wishlist' +import useRemoveItem from '@framework/wishlist/use-remove-item' +import type { Product, ProductVariant } from '@commerce/types' type Props = { productId: Product['id'] diff --git a/framework/shopify/api/index.ts b/framework/shopify/api/index.ts index 1da7f31c6..8646d0136 100644 --- a/framework/shopify/api/index.ts +++ b/framework/shopify/api/index.ts @@ -3,14 +3,11 @@ import fetchGraphqlApi from './utils/fetch-graphql-api' export interface ShopifyConfig extends CommerceAPIConfig {} -const API_URL = - process.env.SHOPIFY_STORE_DOMAIN || - process.env.NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN -const API_TOKEN = - process.env.SHOPIFY_STOREFRONT_ACCESS_TOKEN || - process.env.NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN +const API_URL = process.env.SHOPIFY_STORE_DOMAIN +const API_TOKEN = process.env.SHOPIFY_STOREFRONT_ACCESS_TOKEN if (!API_URL) { + console.log(process.env) throw new Error( `The environment variable SHOPIFY_STORE_DOMAIN is missing and it's required to access your store` ) diff --git a/framework/shopify/fetcher.ts b/framework/shopify/fetcher.ts new file mode 100644 index 000000000..73500ee93 --- /dev/null +++ b/framework/shopify/fetcher.ts @@ -0,0 +1,51 @@ +import { FetcherError } from '@commerce/utils/errors' +import type { Fetcher } from '@commerce/utils/types' + +async function getText(res: Response) { + try { + return (await res.text()) || res.statusText + } catch (error) { + return res.statusText + } +} + +async function getError(res: Response) { + if (res.headers.get('Content-Type')?.includes('application/json')) { + const data = await res.json() + return new FetcherError({ errors: data.errors, status: res.status }) + } + return new FetcherError({ message: await getText(res), status: res.status }) +} + +const fetcher: Fetcher = async ({ + url, + query, + method = 'POST', + variables, + body: bodyObj, +}) => { + // const config = getConfig() + // url = `https://${process.env.SHOPIFY_STORE_DOMAIN}/api/2021-01/graphql.json` + + const hasBody = Boolean(variables || bodyObj) + const body = hasBody + ? JSON.stringify(variables ? { query, variables } : bodyObj) + : undefined + const headers = hasBody + ? { + 'X-Shopify-Storefront-Access-Token': config.apiToken, + 'Content-Type': 'application/json', + } + : undefined + + const res = await fetch(url!, { method, body, headers }) + + if (res.ok) { + const { data } = await res.json() + return data + } + + throw await getError(res) +} + +export default fetcher diff --git a/package.json b/package.json index d2ed966c3..906d950dc 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "lodash.debounce": "^4.0.8", "lodash.random": "^3.2.0", "lodash.throttle": "^4.1.1", - "next": "^10.0.7-canary.3", + "next": "^10.0.7", "next-seo": "^4.11.0", "next-themes": "^0.0.4", "postcss": "^8.2.4", @@ -65,6 +65,7 @@ "@types/lodash.throttle": "^4.1.6", "@types/node": "^14.14.16", "@types/react": "^17.0.0", + "@types/shopify-buy": "^2.10.5", "deepmerge": "^4.2.2", "graphql": "^15.4.0", "husky": "^4.3.8", diff --git a/yarn.lock b/yarn.lock index c6114e0f5..9238b1f03 100644 --- a/yarn.lock +++ b/yarn.lock @@ -862,20 +862,20 @@ dependencies: webpack-bundle-analyzer "4.3.0" -"@next/env@10.0.7-canary.8": - version "10.0.7-canary.8" - resolved "https://registry.yarnpkg.com/@next/env/-/env-10.0.7-canary.8.tgz#b241d5a9f8824bd3f1c6ca066decc46ec78012da" - integrity sha512-4rNuMMj+eG+vP6hr61Fo6GAjhtyHV+4fgLYcvd3HAnsfulU2TX/1cufZH04N5qXgK1IzgO0t0ZUweIXTn6vj7A== +"@next/env@10.0.7": + version "10.0.7" + resolved "https://registry.yarnpkg.com/@next/env/-/env-10.0.7.tgz#7b3e87a9029ca37491e2ec25c27593f0906725f9" + integrity sha512-/vnz2SL/mk3Tei58WfRtVnvz5xHmAqcBmZL5sTBEy1CZG6OtZGNx0qAFCjtVkeJ5m1Bh4Ut+WFh/RF333wx8Sg== -"@next/polyfill-module@10.0.7-canary.8": - version "10.0.7-canary.8" - resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-10.0.7-canary.8.tgz#d2222f4f686953ae9983a3612b061199352584ff" - integrity sha512-3dX9HZ1N8KDI0kmS6SIS5z7a0V8QULwVLR2YH7a2q/JcpFMs4h6AadCOwgjb8G2P6eRKj0VN9tUS/pDdCsiqjw== +"@next/polyfill-module@10.0.7": + version "10.0.7" + resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-10.0.7.tgz#ec45ec1f28f47beed15ed67dffc907edd7143094" + integrity sha512-HxqzRpoSgmZP0kRIWwH+e0SgtAXqJ0VkYtwWcsQFED8+xF4Eqn+7Twyp4uE6hutC8gr8IFSFqH+DEYhRtg1ltQ== -"@next/react-dev-overlay@10.0.7-canary.8": - version "10.0.7-canary.8" - resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-10.0.7-canary.8.tgz#0ec70bb80debd770e66ef002144b43eefc36cff9" - integrity sha512-PUjmUH+mMA+uQMlPT30y7UJg92bZY//xujKchvZqj8AOngQhZCjr8cdd97MtwwWOFYBB5ALUXXN8zkjmgcvDtw== +"@next/react-dev-overlay@10.0.7": + version "10.0.7" + resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-10.0.7.tgz#5fe777011cab75ec09ad539ee61bb95ab5a2bdeb" + integrity sha512-yq71MDHVqN2N+IqOvZDiFsMpQrBcymrdpTx1ShhAADX7cWQvW4dhcIir4BbfrS10vS1LLz/3a8uKZkGdNoJj3w== dependencies: "@babel/code-frame" "7.12.11" anser "1.4.9" @@ -889,10 +889,10 @@ stacktrace-parser "0.1.10" strip-ansi "6.0.0" -"@next/react-refresh-utils@10.0.7-canary.8": - version "10.0.7-canary.8" - resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-10.0.7-canary.8.tgz#2dc4b584749fd961d77eb88d7cd7f7239671fdb9" - integrity sha512-1KkWSXIjaCg9mrj4sYl/mZfuP+tsJjvgsbpECt8tE6phPrablZgxlpJfMx/CtFxh+JYE2kHNxAeunQoIQi73zw== +"@next/react-refresh-utils@10.0.7": + version "10.0.7" + resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-10.0.7.tgz#866ce30fe2f321e011255e81ed5d55eeda05894b" + integrity sha512-d/71vtQglv6m7sh4W1O9drc2hYti7UnAdEXfBLZAS354g2S80lvCRGIhbDrMx4w0rpShoxBIZboE2++LihAESg== "@nodelib/fs.scandir@2.1.4": version "2.1.4" @@ -1129,6 +1129,11 @@ "@types/prop-types" "*" csstype "^3.0.2" +"@types/shopify-buy@^2.10.5": + version "2.10.5" + resolved "https://registry.yarnpkg.com/@types/shopify-buy/-/shopify-buy-2.10.5.tgz#c7184b792989a968af879224e8990cde4db45519" + integrity sha512-12Le/iXPynrONntux/OaXf9+yx0zbMBKhwywdej9mfR8YhXB82pPZYzU3o6j8cjK1uCQ/wWkqLTftpaXpeMKig== + "@types/warning@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/warning/-/warning-3.0.0.tgz#0d2501268ad8f9962b740d387c4654f5f8e23e52" @@ -4656,17 +4661,17 @@ next-unused@^0.0.3: madge "^3.8.0" ts-loader "^7.0.0" -next@^10.0.7-canary.3: - version "10.0.7-canary.8" - resolved "https://registry.yarnpkg.com/next/-/next-10.0.7-canary.8.tgz#7c37efb5c2c3d231b674e382b9bb0b30f533aaf9" - integrity sha512-F0AmkgDq9Eq43YzP1aclz0s8J8x/8TzOzeOaeGY6nzblnJ3EjdzdkVM5YAKYC738MAQ6zR7Wat9VCs96yWZ7WA== +next@^10.0.7: + version "10.0.7" + resolved "https://registry.yarnpkg.com/next/-/next-10.0.7.tgz#442f8e1da7454de33b0bbcc1ce5684b923597ee6" + integrity sha512-We0utmwwfkvO12eLyUZd3tX9VLDE3FPpOaHpH3kqKdUTxJzUKt8FLBXCTm0mwsTKW5XColWG8mJvz2OLu3+3QA== dependencies: "@babel/runtime" "7.12.5" "@hapi/accept" "5.0.1" - "@next/env" "10.0.7-canary.8" - "@next/polyfill-module" "10.0.7-canary.8" - "@next/react-dev-overlay" "10.0.7-canary.8" - "@next/react-refresh-utils" "10.0.7-canary.8" + "@next/env" "10.0.7" + "@next/polyfill-module" "10.0.7" + "@next/react-dev-overlay" "10.0.7" + "@next/react-refresh-utils" "10.0.7" "@opentelemetry/api" "0.14.0" ast-types "0.13.2" browserslist "4.16.1"