Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
3c23854
feat(spree): add checkout and customer types for commerce integration
willymwai Jan 14, 2025
04179df
fix(spree): update checkout imports and provider types
willymwai Jan 14, 2025
8555aa5
feat(spree): add checkout provider and update commerce integration
willymwai Jan 14, 2025
1776e2a
feat(spree): add checkout component registration
willymwai Jan 14, 2025
b4742e8
fix(spree): update checkout component registration and exports
willymwai Jan 14, 2025
679056a
fix(spree): update checkout component name and add type imports
willymwai Jan 14, 2025
8f779af
feat(spree): update commerce provider context and checkout types
willymwai Jan 15, 2025
8d0ef9f
chore: bump commerce-spree package version to 0.0.31 and update check…
willymwai Jan 15, 2025
d612fea
feat(spree): add checkout types and update provider integration
willymwai Jan 15, 2025
0d7e696
fix(spree): update commerce imports and provider types
willymwai Jan 16, 2025
3e00c6d
fix(spree): update imports and add patch-package dependency
willymwai Jan 16, 2025
19945aa
fix(spree): simplify checkout integration and update imports
willymwai Jan 16, 2025
b3ce66d
fix(spree): rename checkout registration to checkoutProvider
willymwai Jan 16, 2025
0084402
fix(spree): refactor cart handling and improve checkout integration
willymwai Jan 16, 2025
6bdd03c
feat(spree): implement checkout submission and enhance checkout hook
willymwai Jan 16, 2025
2ce9e64
feat(spree): implement checkout submission with address and payment h…
willymwai Jan 17, 2025
a59c392
fix(spree): remove submit mutation from checkout hook and types
willymwai Jan 17, 2025
fb6c9da
fix(spree): fix import typo and update checkout provider integration
willymwai Jan 17, 2025
e5e34fa
fix(spree): fix import typo in AddressFields path
willymwai Jan 17, 2025
0ae98d9
feat(spree): add global actions registration for checkout submission
willymwai Jan 17, 2025
6833fc7
refactor(spree): extract checkout submission logic to separate utility
willymwai Jan 17, 2025
a159b57
refactor(spree): optimize checkout submission with useCallback and da…
willymwai Jan 17, 2025
4effd31
feat(spree): add onSuccessAction support for checkout submission
willymwai Jan 17, 2025
f420042
feat(spree): add onSuccessAction parameter to checkout submission
willymwai Jan 18, 2025
f327811
fix(spree): improve checkout submission with include params and onSuc…
willymwai Jan 18, 2025
ba41661
feat(spree): enhance address fields validation in checkout submission
willymwai Jan 18, 2025
cb84143
fix(spree): update onSuccessAction value from 'next' to 'orderNext'
willymwai Jan 18, 2025
b9362c2
feat(spree): bump commerce-spree package version to 0.1.0
willymwai Jan 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,5 @@ bower_components/
node_modules/
storybook-static/
.nx/

.qodo
3 changes: 2 additions & 1 deletion platform/canvas-packages/internal_pkgs/spree/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "commerce-spree",
"version": "0.0.30",
"version": "0.1.0",
"description": "Plasmic registration calls for spree commerce provider",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down Expand Up @@ -38,6 +38,7 @@
"@types/node": "^17.0.8",
"@types/react": "^18.0.27",
"next": "^12.0.8",
"patch-package": "^8.0.0",
"prettier": "^2.5.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
diff --git a/node_modules/@plasmicpkgs/commerce/dist/commerce.d.ts b/node_modules/@plasmicpkgs/commerce/dist/commerce.d.ts
index a23a631..e4075b1 100644
--- a/node_modules/@plasmicpkgs/commerce/dist/commerce.d.ts
+++ b/node_modules/@plasmicpkgs/commerce/dist/commerce.d.ts
@@ -18,6 +18,35 @@ export declare type Provider = CommerceConfig & {
useBrands?: SWRHook<Site.GetBrandsHook>;
};
extraFeatures?: CommerceExtraFeatures;
+ checkout?: {
+ useCheckout?: SWRHook<any>
+ useSubmitCheckout?: MutationHook<any>
+ }
+ wishlist?: {
+ useWishlist?: SWRHook<any>
+ useAddItem?: MutationHook<any>
+ useRemoveItem?: MutationHook<any>
+ }
+ customer?: {
+ useCustomer?: SWRHook<any>
+ card?: {
+ useCards?: SWRHook<any>
+ useAddItem?: MutationHook<any>
+ useUpdateItem?: MutationHook<any>
+ useRemoveItem?: MutationHook<any>
+ }
+ address?: {
+ useAddresses?: SWRHook<any>
+ useAddItem?: MutationHook<any>
+ useUpdateItem?: MutationHook<any>
+ useRemoveItem?: MutationHook<any>
+ }
+ }
+ auth?: {
+ useSignup?: MutationHook<any>
+ useLogin?: MutationHook<any>
+ useLogout?: MutationHook<any>
+ }
};
export declare type CommerceConfig = {
locale: string;
74 changes: 3 additions & 71 deletions platform/canvas-packages/internal_pkgs/spree/src/cart/use-cart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,9 @@ import type { SWRHook } from '@plasmicpkgs/commerce'
import { useCart as useCommerceCart, UseCart } from '@plasmicpkgs/commerce'
import type { GetCartHook } from '../types/cart'
import normalizeCart from '../utils/normalizations/normalize-cart'
import type { GraphQLFetcherResult } from '../types'
import type { IOrder } from '@spree/storefront-api-v2-sdk/types/interfaces/Order'
import type { IToken } from '@spree/storefront-api-v2-sdk/types/interfaces/Token'
import { FetcherError } from '@plasmicpkgs/commerce'
import { setCartToken } from '../utils/tokens/cart-token'
import ensureIToken from '../utils/tokens/ensure-itoken'
import isLoggedIn from '../utils/tokens/is-logged-in'
import createEmptyCart from '../utils/create-empty-cart'
import { requireConfigValue } from '../isomorphic-config'
import getCart from '../utils/get-cart'

const imagesSize = requireConfigValue('imagesSize') as string
const imagesQuality = requireConfigValue('imagesQuality') as number

export default useCommerceCart as UseCart<typeof handler>;
export default useCommerceCart as UseCart<typeof handler>

// This handler avoids calling /api/cart.
// There doesn't seem to be a good reason to call it.
Expand All @@ -36,64 +25,7 @@ export const handler: SWRHook<GetCartHook> = {
options
)

let spreeCartResponse: IOrder | null

const token: IToken | undefined = ensureIToken()

if (!token) {
spreeCartResponse = null
} else {
try {
const { data: spreeCartShowSuccessResponse } = await fetch<
GraphQLFetcherResult<IOrder>
>({
variables: {
methodPath: 'cart.show',
arguments: [
token,
{
include: [
'line_items',
'line_items.variant',
'line_items.variant.product',
'line_items.variant.product.images',
'line_items.variant.images',
'line_items.variant.option_values',
'line_items.variant.product.option_types',
].join(','),
image_transformation: {
quality: imagesQuality,
size: imagesSize,
},
},
],
},
})

spreeCartResponse = spreeCartShowSuccessResponse
} catch (fetchCartError) {
if (
!(fetchCartError instanceof FetcherError) ||
fetchCartError.status !== 404
) {
throw fetchCartError
}

spreeCartResponse = null
}
}

if (!spreeCartResponse || spreeCartResponse?.data.attributes.completed_at) {
const { data: spreeCartCreateSuccessResponse } = await createEmptyCart(
fetch
)

spreeCartResponse = spreeCartCreateSuccessResponse

if (!isLoggedIn()) {
setCartToken(spreeCartResponse.data.attributes.token)
}
}
const spreeCartResponse = await getCart(fetch)

return normalizeCart(spreeCartResponse, spreeCartResponse.data)
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { SWRHook } from '@plasmicpkgs/commerce'
import useCheckout, { UseCheckout } from '../commerce/checkout/use-checkout'
import getCart from '../utils/get-cart'
import normalizeCart from '../utils/normalizations/normalize-cart'
import { useMemo } from 'react'
import { GetCheckoutHook } from '../commerce/types/checkout'

export default useCheckout as UseCheckout<typeof handler>

export const handler: SWRHook<any> = {
// Provide fetchOptions for SWR cache key
fetchOptions: {
// TODO: Revise url and query
url: 'checkout',
query: 'show',
},
async fetcher({ input, options, fetch }) {
console.info(
'useCheckout fetcher called. Configuration: ',
'input: ',
input,
'options: ',
options
)
const spreeCartResponse = await getCart(fetch)
const cart = normalizeCart(spreeCartResponse, spreeCartResponse.data)
return {
hasPayment: false,
hasShipping: false,
addressId: null,
payments: [],
cardId: null,
lineItems: cart.lineItems,
}
},
useHook: ({ useData }) => {
const useWrappedHook: ReturnType<SWRHook<GetCheckoutHook>['useHook']> = (
input
) => {
const response = useData({
swrOptions: { revalidateOnFocus: false, ...input?.swrOptions },
})

return useMemo(
() =>
Object.create(response, {
isEmpty: {
get() {
return response.data?.lineItems?.length ?? 0
},
enumerable: true,
},
}),
[response]
)
}

return useWrappedHook
},
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import type { SubmitCheckoutHook } from '../commerce/types/checkout'
import type { MutationHook } from '../commerce/utils/types'

import { useCallback } from 'react'
import useSubmitCheckout, {
UseSubmitCheckout,
} from '../commerce/checkout/use-submit-checkout'
import { ValidationError } from '@plasmicpkgs/commerce'
import submitCheckout from '../utils/submit-checkout'
import useCheckout from './use-checkout'

export default useSubmitCheckout as UseSubmitCheckout<typeof handler>

export const handler: MutationHook<SubmitCheckoutHook> = {
// Provide fetchOptions for SWR cache key
fetchOptions: {
url: 'checkout',
query: 'orderUpdate',
},
async fetcher({ input, options, fetch }) {
console.info(
'useSubmitCheckout fetcher called. Configuration: ',
'input: ',
input,
'options: ',
options
)
return await submitCheckout(fetch, input)
},

useHook: ({ fetch }) => {
const useWrappedHook: ReturnType<
MutationHook<SubmitCheckoutHook>['useHook']
> = () => {
const { mutate } = useCheckout()

return useCallback(
async (input) => {
const {
email,
special_instructions,
billing_address,
shipping_address,
payments,
onSuccessAction,
} = input

if (
!email &&
!special_instructions &&
!billing_address &&
!shipping_address &&
!payments
) {
throw new ValidationError({
message:
'email or special_instructions or billing_address or shipping_address or payments needs to be provided.',
})
}
const data = await fetch({
input: {
email,
special_instructions,
billing_address,
shipping_address,
payments,
onSuccessAction,
},
})

await mutate(data, false)

return data
},
[mutate]
)
}
return useWrappedHook
},
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { SWRHook, HookFetcherFn } from '@plasmicpkgs/commerce'
import type { GetCheckoutHook } from '../types/checkout'

import Cookies from 'js-cookie'

import { useHook, useSWRHook } from '../utils/use-hook'
import { Provider, useCommerce } from '@plasmicpkgs/commerce'

export type UseCheckout<
H extends SWRHook<GetCheckoutHook> = SWRHook<GetCheckoutHook>
> = ReturnType<H['useHook']>

export const fetcher: HookFetcherFn<GetCheckoutHook> = async ({
options,
input: { cartId },
fetch,
}) => {
return cartId ? await fetch(options) : null
}

const fn = (provider: Provider) => provider.checkout?.useCheckout!

const useCheckout: UseCheckout = (input) => {
const hook = useHook(fn)
const { cartCookie } = useCommerce()
const fetcherFn = hook.fetcher ?? fetcher
const wrapper: typeof fetcher = (context) => {
context.input.cartId = Cookies.get(cartCookie)
return fetcherFn(context)
}
return useSWRHook({ ...hook, fetcher: wrapper })(input)
}

export default useCheckout
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { HookFetcherFn, MutationHook } from '../utils/types'
import type { SubmitCheckoutHook } from '../types/checkout'
import type { Provider } from '@plasmicpkgs/commerce'

import { useHook, useMutationHook } from '../utils/use-hook'
import { mutationFetcher } from '../utils/default-fetcher'

export type UseSubmitCheckout<
H extends MutationHook<
SubmitCheckoutHook<any>
> = MutationHook<SubmitCheckoutHook>
> = ReturnType<H['useHook']>

export const fetcher: HookFetcherFn<SubmitCheckoutHook> = mutationFetcher

const fn = (provider: Provider) => provider.checkout?.useSubmitCheckout!

const useSubmitCheckout: UseSubmitCheckout = (...args) => {
const hook = useHook(fn)
return useMutationHook({ fetcher, ...hook })(...args)
}

export default useSubmitCheckout
Loading