-
Notifications
You must be signed in to change notification settings - Fork 214
Expand file tree
/
Copy pathwith-optional-commerce-sdk-react-provider.tsx
More file actions
77 lines (69 loc) · 2.96 KB
/
with-optional-commerce-sdk-react-provider.tsx
File metadata and controls
77 lines (69 loc) · 2.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/*
* Copyright (c) 2025, salesforce.com, inc.
* All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import React from 'react'
import {getAppOrigin} from '@salesforce/pwa-kit-react-sdk/utils/url'
import {CommerceApiProvider, useCommerceApi} from '@salesforce/commerce-sdk-react'
import {UserConfig} from '../types/config'
import {logger} from '../logger'
/**
* Checks if the CommerceApiProvider is already installed in the component tree.
* @returns boolean, true if the CommerceApiProvider is installed, false otherwise.
*/
const useHasCommerceApiProvider = () => {
let hasProvider = false
try {
const api = useCommerceApi()
// the api object is an object with a bunch of api clients like ShopperProduct, ShopperOrder, etc.
// if the object is empty, then the CommerceApiProvider is not installed
if (Object.keys(api).length > 0) {
hasProvider = true
}
} catch (_) {
hasProvider = false
}
return hasProvider
}
type WithOptionalCommerceSdkReactProvider = React.ComponentPropsWithoutRef<any>
/**
* Higher-order component that conditionally installs the CommerceApiProvider if the config is provided.
*
* @param WrappedComponent - The component to be optionally wrapped with CommerceApiProvider.
* @param config - The configuration object for the CommerceApiProvider.
* @returns A component that wraps the given component with CommerceApiProvider if it is not already present in the component tree.
*/
export const withOptionalCommerceSdkReactProvider = <P extends object>(
WrappedComponent: React.ComponentType<P>,
config: UserConfig
) => {
const HOC: React.FC<P> = (props: WithOptionalCommerceSdkReactProvider) => {
if (useHasCommerceApiProvider()) {
return <WrappedComponent {...(props as P)} />
}
if (!config.commerceApi || !config.commerceApi?.parameters) {
logger.error(
'CommerceApiProvider is not installed and no commerceApi config is provided, this extension may not work as expected.'
)
return <WrappedComponent {...(props as P)} />
}
const appOrigin = getAppOrigin()
return (
<CommerceApiProvider
shortCode={config.commerceApi.parameters.shortCode}
clientId={config.commerceApi.parameters.clientId}
organizationId={config.commerceApi.parameters.organizationId}
siteId={config.commerceApi.parameters.siteId}
locale={config.commerceApi.parameters.locale}
currency={config.commerceApi.parameters.currency}
redirectURI={`${appOrigin}/callback`}
proxy={`${appOrigin}${config.commerceApi.proxyPath}`}
>
<WrappedComponent {...(props as P)} />
</CommerceApiProvider>
)
}
return HOC
}