forked from vercel/commerce
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Spree Commerce Provider (vercel#484)
* Include @spree/storefront-api-v2-sdk * Add basic Spree framework structure * Add Spree as allowed Framework * Fetch product images, standardize API fetch using Spree SDK * Include slug and path in products * Fetch single product during build time * PLP with searching by category * Fetch Spree Categories and Brands * Sort PLP * Search products by name * Fix option values collection * Fix hasNonMasterVariants * Sort Categories and Brands * Add configuration to show product options when there's one variant available * Enable text search for the Spree Framework * Allow removing line items * Allow updating line item quantity * Add __typename to variant options to allow adding the selected variant to the cart * Use fetch and Request from node-fetch in Spree SDK * Update Spree SDK fetcher * Show placeholder message for /chechout and adjust api fetcher type * Use kebab case instead of camel case * Remove outdated comments * Remove outdated comment * Resolve isColorProductOption duplication * Type Spree variants and line items and temporarily remove height, width and depth * Remove outdated comment * Update comments about cart discounts * Remove 'spree' prefix from isomorphicConfig and add lastUpdatedProductsPrerenderCount * Implement getAllProductPaths to prerender some products during build time * Adjust fetchers to the latest Spree SDK interface * Add types to Spree taxons mapping * Revert port change in package.json scripts * Add basic README describing Spree installation * Expand README's installation section * Upgrade Spree SDK to 4.7.0 and add node-fetch to dependencies * Order providers alphanumerically Co-authored-by: Damian Legawiec <[email protected]> * Sort products by available_on when using the Trending sorting in useSearch * Change the default Spree port to 4000 and update README in sync with Spree Starter changes * Save primary variant's SKU when normalizing a product from Spree * Create a new cart if Spree can't find the current using a token * Add separator to README * Add missing Error subclass * Allow placeholder images for products and line items without images * Add image * Reset tsconfig.json paths to originla values * Search taxonomies by permalinks instead of IDs * Upgrade Spree SDK to version 4.7.1 * Remove references to @framework and use relative paths instead * Generalize TypeScript and add typings to getPage * Update fetcher to avoid parsing non-JSON responses * Use original product image by default instead of resized * Link to an online demo of the Spree integration in the README * Flatten fetcher responses * Include Spree in the list of supported ecommerce backends in README * Update README.md * Format Spree's README * Add link to the Spree demo site in the main README * Update README.md * Update README.md * Allow setting a taxon id for getAllProducts * Use Spree SDK's JSON:API helpers * Sort getAllProducts by -updated_at when using a taxonomy * Remove slash '/' from line item's paths * Allow filtering variant images by option type * Upgrade checkout behavior in line with core NextJS Commerce changes * Remove dummy submitCheckout function * [NX-24] Display PDP option types sorted by position from Spree * Supply Spree primary variant if a product has no option variants * Do not throw an error if a product doesn't have NEXT_PUBLIC_SPREE_IMAGES_OPTION_FILTER * [NX-43] Uses image transformations when fetching products images * Use bind to properly call Spree SDK methods and update SDK fetcher in line with SDK 4.12.0 * Fix ESLint issues in useHook * Support account sign up, login and logout Also - Converts the guest cart to a persisted cart tied to the logged in user after log in. - Fixes issues with use-remove-item. The cart will now properly refresh after an item is removed. - Uses the logged in user's token to adjust the cart and make other authenticated requests. - Transparently refreshed the access token of the logged in user with a refresh token. Replays requests to Spree which fail with a 401 error after refreshing the access token. * Fetch logged in user's cart after login or signup but associate guest cart only after signup * Support Spree default wishlist show, add and remove wished items operations * Fetch Spree CMS Pages * Fix login, handle critical token errors and fix WishlistCard Fix to WishlistCard changes its props to be consistent with WishlistButton when calling useRemoveItem * Fix variable name (vercel#574) Variable name should be `ChevronRight` * Update get-cart.ts (vercel#474) include digital items Co-authored-by: Gonzalo Pozzo <[email protected]> * Update normalize.ts (vercel#475) add missing options property to `normalizeLineItem` Co-authored-by: Gonzalo Pozzo <[email protected]> * Update add-item.ts (vercel#473) * Update add-item.ts include digital items * Update add-item.ts include digital items Co-authored-by: Gonzalo Pozzo <[email protected]> * fix typo (vercel#572) Co-authored-by: Gonzalo Pozzo <[email protected]> * Fix authentication.refreshToken arguments * Remove redundant comments and logs * Fix createEmptyCart request to Spree and add option to disable auto login * Fix formatting issues * Apply image transformation when fetching images for products in cart * Replace call to qs with Spree SDK built-in helper * Upgrade Spree SDK to 5.0.1 * Rename zeitFetch import to vercelFetch * Abstract fetcher JSON Content-Type checking into separate function * Rename imageUrl to url getMediaGallery already provides context for the constant * Remove return type for getProductPath The return type can be trivially determined from the returned value. * Change URL to Spree demo store in root README Co-authored-by: Gonzalo Pozzo <[email protected]> * Change label for link to Spree demo store in Spree's README Co-authored-by: Gonzalo Pozzo <[email protected]> * Change URL to Spree demo store in Spree's README Co-authored-by: Gonzalo Pozzo <[email protected]> * Use only relative paths to /framework/spree from itself Co-authored-by: tniezg <[email protected]> Co-authored-by: Damian Legawiec <[email protected]> Co-authored-by: Robert Nowakowski <[email protected]> Co-authored-by: Grey <[email protected]> Co-authored-by: pfcodes <[email protected]> Co-authored-by: Gonzalo Pozzo <[email protected]> Co-authored-by: Konrad Kruk <[email protected]>
- Loading branch information
1 parent
541009f
commit d77d000
Showing
107 changed files
with
4,142 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ const PROVIDERS = [ | |
'swell', | ||
'vendure', | ||
'ordercloud', | ||
'spree', | ||
] | ||
|
||
function getProviderName() { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Template to be used for creating .env* files (.env, .env.local etc.) in the project's root directory. | ||
|
||
COMMERCE_PROVIDER=spree | ||
|
||
{# - NEXT_PUBLIC_* are exposed to the web browser and the server #} | ||
NEXT_PUBLIC_SPREE_API_HOST=http://localhost:4000 | ||
NEXT_PUBLIC_SPREE_DEFAULT_LOCALE=en-us | ||
NEXT_PUBLIC_SPREE_CART_COOKIE_NAME=spree_cart_token | ||
{# -- cookie expire in days #} | ||
NEXT_PUBLIC_SPREE_CART_COOKIE_EXPIRE=7 | ||
NEXT_PUBLIC_SPREE_USER_COOKIE_NAME=spree_user_token | ||
NEXT_PUBLIC_SPREE_USER_COOKIE_EXPIRE=7 | ||
NEXT_PUBLIC_SPREE_IMAGE_HOST=http://localhost:4000 | ||
NEXT_PUBLIC_SPREE_ALLOWED_IMAGE_DOMAIN=localhost | ||
NEXT_PUBLIC_SPREE_CATEGORIES_TAXONOMY_PERMALINK=categories | ||
NEXT_PUBLIC_SPREE_BRANDS_TAXONOMY_PERMALINK=brands | ||
NEXT_PUBLIC_SPREE_ALL_PRODUCTS_TAXONOMY_ID=false | ||
NEXT_PUBLIC_SPREE_SHOW_SINGLE_VARIANT_OPTIONS=false | ||
NEXT_PUBLIC_SPREE_LAST_UPDATED_PRODUCTS_PRERENDER_COUNT=10 | ||
NEXT_PUBLIC_SPREE_PRODUCT_PLACEHOLDER_IMAGE_URL=/product-img-placeholder.svg | ||
NEXT_PUBLIC_SPREE_LINE_ITEM_PLACEHOLDER_IMAGE_URL=/product-img-placeholder.svg | ||
NEXT_PUBLIC_SPREE_IMAGES_OPTION_FILTER=false | ||
NEXT_PUBLIC_SPREE_IMAGES_SIZE=1000x1000 | ||
NEXT_PUBLIC_SPREE_IMAGES_QUALITY=100 | ||
NEXT_PUBLIC_SPREE_LOGIN_AFTER_SIGNUP=true |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# [Spree Commerce][1] Provider | ||
|
||
![Screenshots of Spree Commerce and NextJS Commerce][5] | ||
|
||
An integration of [Spree Commerce](https://spreecommerce.org/) within NextJS Commerce. It supports browsing and searching Spree products and adding products to the cart. | ||
|
||
**Demo**: [https://spree.vercel.store/][6] | ||
|
||
## Installation | ||
|
||
1. Setup Spree - [follow the Getting Started guide](https://dev-docs.spreecommerce.org/getting-started/installation). | ||
|
||
1. Setup Nextjs Commerce - [instructions for setting up NextJS Commerce][2]. | ||
|
||
1. Copy the `.env.template` file in this directory (`/framework/spree`) to `.env.local` in the main directory | ||
|
||
```bash | ||
cp framework/spree/.env.template .env.local | ||
``` | ||
|
||
1. Set `NEXT_PUBLIC_SPREE_CATEGORIES_TAXONOMY_PERMALINK` and `NEXT_PUBLIC_SPREE_BRANDS_TAXONOMY_PERMALINK` environment variables: | ||
|
||
- They rely on [taxonomies'](https://dev-docs.spreecommerce.org/internals/products#taxons-and-taxonomies) permalinks in Spree. | ||
- Go to the Spree admin panel and create `Categories` and `Brands` taxonomies if they don't exist and copy their permalinks into `.env.local` in NextJS Commerce. | ||
|
||
1. Finally, run `yarn dev` :tada: | ||
|
||
[1]: https://spreecommerce.org/ | ||
[2]: https://github.com/vercel/commerce | ||
[3]: https://github.com/spree/spree_starter | ||
[4]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS | ||
[5]: ./README-assets/screenshots.png | ||
[6]: https://spree.vercel.store/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export default function noopApi(...args: any[]): void {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export default function noopApi(...args: any[]): void {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export default function noopApi(...args: any[]): void {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import type { CheckoutEndpoint } from '.' | ||
|
||
const getCheckout: CheckoutEndpoint['handlers']['getCheckout'] = async ({ | ||
req: _request, | ||
res: response, | ||
config: _config, | ||
}) => { | ||
try { | ||
const html = ` | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Checkout</title> | ||
</head> | ||
<body> | ||
<div style='margin: 10rem auto; text-align: center; font-family: SansSerif, "Segoe UI", Helvetica; color: #888;'> | ||
<svg xmlns="http://www.w3.org/2000/svg" style='height: 60px; width: 60px;' fill="none" viewBox="0 0 24 24" stroke="currentColor"> | ||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" /> | ||
</svg> | ||
<h1>Checkout not yet implemented :(</h1> | ||
<p> | ||
See <a href='https://github.com/vercel/commerce/issues/64' target='_blank'>#64</a> | ||
</p> | ||
</div> | ||
</body> | ||
</html> | ||
` | ||
|
||
response.status(200) | ||
response.setHeader('Content-Type', 'text/html') | ||
response.write(html) | ||
response.end() | ||
} catch (error) { | ||
console.error(error) | ||
|
||
const message = 'An unexpected error ocurred' | ||
|
||
response.status(500).json({ data: null, errors: [{ message }] }) | ||
} | ||
} | ||
|
||
export default getCheckout |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { createEndpoint } from '@commerce/api' | ||
import type { GetAPISchema, CommerceAPI } from '@commerce/api' | ||
import checkoutEndpoint from '@commerce/api/endpoints/checkout' | ||
import type { CheckoutSchema } from '@commerce/types/checkout' | ||
import getCheckout from './get-checkout' | ||
import type { SpreeApiProvider } from '../..' | ||
|
||
export type CheckoutAPI = GetAPISchema< | ||
CommerceAPI<SpreeApiProvider>, | ||
CheckoutSchema | ||
> | ||
|
||
export type CheckoutEndpoint = CheckoutAPI['endpoint'] | ||
|
||
export const handlers: CheckoutEndpoint['handlers'] = { getCheckout } | ||
|
||
const checkoutApi = createEndpoint<CheckoutAPI>({ | ||
handler: checkoutEndpoint, | ||
handlers, | ||
}) | ||
|
||
export default checkoutApi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export default function noopApi(...args: any[]): void {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export default function noopApi(...args: any[]): void {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export default function noopApi(...args: any[]): void {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export default function noopApi(...args: any[]): void {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export default function noopApi(...args: any[]): void {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export default function noopApi(...args: any[]): void {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export default function noopApi(...args: any[]): void {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import type { CommerceAPI, CommerceAPIConfig } from '@commerce/api' | ||
import { getCommerceApi as commerceApi } from '@commerce/api' | ||
import createApiFetch from './utils/create-api-fetch' | ||
|
||
import getAllPages from './operations/get-all-pages' | ||
import getPage from './operations/get-page' | ||
import getSiteInfo from './operations/get-site-info' | ||
import getCustomerWishlist from './operations/get-customer-wishlist' | ||
import getAllProductPaths from './operations/get-all-product-paths' | ||
import getAllProducts from './operations/get-all-products' | ||
import getProduct from './operations/get-product' | ||
|
||
export interface SpreeApiConfig extends CommerceAPIConfig {} | ||
|
||
const config: SpreeApiConfig = { | ||
commerceUrl: '', | ||
apiToken: '', | ||
cartCookie: '', | ||
customerCookie: '', | ||
cartCookieMaxAge: 2592000, | ||
fetch: createApiFetch(() => getCommerceApi().getConfig()), | ||
} | ||
|
||
const operations = { | ||
getAllPages, | ||
getPage, | ||
getSiteInfo, | ||
getCustomerWishlist, | ||
getAllProductPaths, | ||
getAllProducts, | ||
getProduct, | ||
} | ||
|
||
export const provider = { config, operations } | ||
|
||
export type SpreeApiProvider = typeof provider | ||
|
||
export type SpreeApi<P extends SpreeApiProvider = SpreeApiProvider> = | ||
CommerceAPI<P> | ||
|
||
export function getCommerceApi<P extends SpreeApiProvider>( | ||
customProvider: P = provider as any | ||
): SpreeApi<P> { | ||
return commerceApi(customProvider) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import type { | ||
OperationContext, | ||
OperationOptions, | ||
} from '@commerce/api/operations' | ||
import type { GetAllPagesOperation, Page } from '@commerce/types/page' | ||
import { requireConfigValue } from '../../isomorphic-config' | ||
import normalizePage from '../../utils/normalizations/normalize-page' | ||
import type { IPages } from '@spree/storefront-api-v2-sdk/types/interfaces/Page' | ||
import type { SpreeSdkVariables } from '../../types' | ||
import type { SpreeApiConfig, SpreeApiProvider } from '../index' | ||
|
||
export default function getAllPagesOperation({ | ||
commerce, | ||
}: OperationContext<SpreeApiProvider>) { | ||
async function getAllPages<T extends GetAllPagesOperation>(options?: { | ||
config?: Partial<SpreeApiConfig> | ||
preview?: boolean | ||
}): Promise<T['data']> | ||
|
||
async function getAllPages<T extends GetAllPagesOperation>( | ||
opts: { | ||
config?: Partial<SpreeApiConfig> | ||
preview?: boolean | ||
} & OperationOptions | ||
): Promise<T['data']> | ||
|
||
async function getAllPages<T extends GetAllPagesOperation>({ | ||
config: userConfig, | ||
preview, | ||
query, | ||
url, | ||
}: { | ||
url?: string | ||
config?: Partial<SpreeApiConfig> | ||
preview?: boolean | ||
query?: string | ||
} = {}): Promise<T['data']> { | ||
console.info( | ||
'getAllPages called. Configuration: ', | ||
'query: ', | ||
query, | ||
'userConfig: ', | ||
userConfig, | ||
'preview: ', | ||
preview, | ||
'url: ', | ||
url | ||
) | ||
|
||
const config = commerce.getConfig(userConfig) | ||
const { fetch: apiFetch } = config | ||
|
||
const variables: SpreeSdkVariables = { | ||
methodPath: 'pages.list', | ||
arguments: [ | ||
{ | ||
per_page: 500, | ||
filter: { | ||
locale_eq: | ||
config.locale || (requireConfigValue('defaultLocale') as string), | ||
}, | ||
}, | ||
], | ||
} | ||
|
||
const { data: spreeSuccessResponse } = await apiFetch< | ||
IPages, | ||
SpreeSdkVariables | ||
>('__UNUSED__', { | ||
variables, | ||
}) | ||
|
||
const normalizedPages: Page[] = spreeSuccessResponse.data.map<Page>( | ||
(spreePage) => | ||
normalizePage(spreeSuccessResponse, spreePage, config.locales || []) | ||
) | ||
|
||
return { pages: normalizedPages } | ||
} | ||
|
||
return getAllPages | ||
} |
Oops, something went wrong.