Skip to content

Commit fc789fe

Browse files
authored
Allow query hook parameters to be null. (#1046)
* Remove unused util. * Allow query hook parameters to be `null`.
1 parent 246d484 commit fc789fe

File tree

23 files changed

+508
-295
lines changed

23 files changed

+508
-295
lines changed

packages/commerce-sdk-react/src/hooks/ShopperBaskets/query.ts

+42-27
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,25 @@
55
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
66
*/
77
import {UseQueryResult} from '@tanstack/react-query'
8-
import {ApiClients, ApiQueryOptions, Argument, DataType} from '../types'
8+
import {ApiClients, ApiQueryOptions, Argument, DataType, NullableParameters} from '../types'
99
import useCommerceApi from '../useCommerceApi'
1010
import {useQuery} from '../useQuery'
11-
import {mergeOptions} from '../utils'
11+
import {mergeOptions, omitNullableParameters} from '../utils'
1212
import * as queryKeyHelpers from './queryKeyHelpers'
1313

1414
type Client = ApiClients['shopperBaskets']
1515

1616
/**
1717
* Gets a basket.
18+
* @parameter apiOptions - Options to pass through to `commerce-sdk-isomorphic`, with `null` accepted for unset API parameters.
19+
* @parameter queryOptions - TanStack Query query options, with `enabled` by default set to check that all required API parameters have been set.
1820
* @returns A TanStack Query query hook with data from the Shopper Baskets `getBasket` endpoint.
1921
* @see {@link https://developer.salesforce.com/docs/commerce/commerce-api/references/shopper-baskets?meta=getBasket| Salesforce Developer Center} for more information about the API endpoint.
2022
* @see {@link https://salesforcecommercecloud.github.io/commerce-sdk-isomorphic/classes/shopperbaskets.shopperbaskets-1.html#getbasket | `commerce-sdk-isomorphic` documentation} for more information on the parameters and returned data type.
2123
* @see {@link https://tanstack.com/query/latest/docs/react/reference/useQuery | TanStack Query `useQuery` reference} for more information about the return value.
2224
*/
2325
export const useBasket = (
24-
apiOptions: Argument<Client['getBasket']>,
26+
apiOptions: NullableParameters<Argument<Client['getBasket']>>,
2527
queryOptions: ApiQueryOptions<Client['getBasket']> = {}
2628
): UseQueryResult<DataType<Client['getBasket']>> => {
2729
type Options = Argument<Client['getBasket']>
@@ -30,29 +32,32 @@ export const useBasket = (
3032
const methodName = 'getBasket'
3133
const requiredParameters = ['organizationId', 'basketId', 'siteId'] as const
3234

33-
// Parameters can be set in `apiOptions` or `client.clientConfig`, we must merge them in order
34-
// to generate the correct query key.
35-
const netOptions = mergeOptions(client, apiOptions)
35+
// Parameters can be set in `apiOptions` or `client.clientConfig`;
36+
// we must merge them in order to generate the correct query key.
37+
const netOptions = omitNullableParameters(mergeOptions(client, apiOptions))
3638
const queryKey = queryKeyHelpers[methodName].queryKey(netOptions.parameters)
39+
// We don't use `netOptions` here because we manipulate the options in `useQuery`.
3740
const method = async (options: Options) => await client[methodName](options)
3841

3942
// For some reason, if we don't explicitly set these generic parameters, the inferred type for
4043
// `Data` sometimes, but not always, includes `Response`, which is incorrect. I don't know why.
41-
return useQuery<Options, Data>(netOptions, queryOptions, {
44+
return useQuery<Client, Options, Data>(netOptions, queryOptions, {
4245
method,
4346
queryKey,
4447
requiredParameters
4548
})
4649
}
4750
/**
4851
* Gets applicable payment methods for an existing basket considering the open payment amount only.
52+
* @parameter apiOptions - Options to pass through to `commerce-sdk-isomorphic`, with `null` accepted for unset API parameters.
53+
* @parameter queryOptions - TanStack Query query options, with `enabled` by default set to check that all required API parameters have been set.
4954
* @returns A TanStack Query query hook with data from the Shopper Baskets `getPaymentMethodsForBasket` endpoint.
5055
* @see {@link https://developer.salesforce.com/docs/commerce/commerce-api/references/shopper-baskets?meta=getPaymentMethodsForBasket| Salesforce Developer Center} for more information about the API endpoint.
5156
* @see {@link https://salesforcecommercecloud.github.io/commerce-sdk-isomorphic/classes/shopperbaskets.shopperbaskets-1.html#getpaymentmethodsforbasket | `commerce-sdk-isomorphic` documentation} for more information on the parameters and returned data type.
5257
* @see {@link https://tanstack.com/query/latest/docs/react/reference/useQuery | TanStack Query `useQuery` reference} for more information about the return value.
5358
*/
5459
export const usePaymentMethodsForBasket = (
55-
apiOptions: Argument<Client['getPaymentMethodsForBasket']>,
60+
apiOptions: NullableParameters<Argument<Client['getPaymentMethodsForBasket']>>,
5661
queryOptions: ApiQueryOptions<Client['getPaymentMethodsForBasket']> = {}
5762
): UseQueryResult<DataType<Client['getPaymentMethodsForBasket']>> => {
5863
type Options = Argument<Client['getPaymentMethodsForBasket']>
@@ -61,29 +66,32 @@ export const usePaymentMethodsForBasket = (
6166
const methodName = 'getPaymentMethodsForBasket'
6267
const requiredParameters = ['organizationId', 'basketId', 'siteId'] as const
6368

64-
// Parameters can be set in `apiOptions` or `client.clientConfig`, we must merge them in order
65-
// to generate the correct query key.
66-
const netOptions = mergeOptions(client, apiOptions)
69+
// Parameters can be set in `apiOptions` or `client.clientConfig`;
70+
// we must merge them in order to generate the correct query key.
71+
const netOptions = omitNullableParameters(mergeOptions(client, apiOptions))
6772
const queryKey = queryKeyHelpers[methodName].queryKey(netOptions.parameters)
73+
// We don't use `netOptions` here because we manipulate the options in `useQuery`.
6874
const method = async (options: Options) => await client[methodName](options)
6975

7076
// For some reason, if we don't explicitly set these generic parameters, the inferred type for
7177
// `Data` sometimes, but not always, includes `Response`, which is incorrect. I don't know why.
72-
return useQuery<Options, Data>(netOptions, queryOptions, {
78+
return useQuery<Client, Options, Data>(netOptions, queryOptions, {
7379
method,
7480
queryKey,
7581
requiredParameters
7682
})
7783
}
7884
/**
7985
* Gets applicable price books for an existing basket.
86+
* @parameter apiOptions - Options to pass through to `commerce-sdk-isomorphic`, with `null` accepted for unset API parameters.
87+
* @parameter queryOptions - TanStack Query query options, with `enabled` by default set to check that all required API parameters have been set.
8088
* @returns A TanStack Query query hook with data from the Shopper Baskets `getPriceBooksForBasket` endpoint.
8189
* @see {@link https://developer.salesforce.com/docs/commerce/commerce-api/references/shopper-baskets?meta=getPriceBooksForBasket| Salesforce Developer Center} for more information about the API endpoint.
8290
* @see {@link https://salesforcecommercecloud.github.io/commerce-sdk-isomorphic/classes/shopperbaskets.shopperbaskets-1.html#getpricebooksforbasket | `commerce-sdk-isomorphic` documentation} for more information on the parameters and returned data type.
8391
* @see {@link https://tanstack.com/query/latest/docs/react/reference/useQuery | TanStack Query `useQuery` reference} for more information about the return value.
8492
*/
8593
export const usePriceBooksForBasket = (
86-
apiOptions: Argument<Client['getPriceBooksForBasket']>,
94+
apiOptions: NullableParameters<Argument<Client['getPriceBooksForBasket']>>,
8795
queryOptions: ApiQueryOptions<Client['getPriceBooksForBasket']> = {}
8896
): UseQueryResult<DataType<Client['getPriceBooksForBasket']>> => {
8997
type Options = Argument<Client['getPriceBooksForBasket']>
@@ -92,29 +100,32 @@ export const usePriceBooksForBasket = (
92100
const methodName = 'getPriceBooksForBasket'
93101
const requiredParameters = ['organizationId', 'basketId', 'siteId'] as const
94102

95-
// Parameters can be set in `apiOptions` or `client.clientConfig`, we must merge them in order
96-
// to generate the correct query key.
97-
const netOptions = mergeOptions(client, apiOptions)
103+
// Parameters can be set in `apiOptions` or `client.clientConfig`;
104+
// we must merge them in order to generate the correct query key.
105+
const netOptions = omitNullableParameters(mergeOptions(client, apiOptions))
98106
const queryKey = queryKeyHelpers[methodName].queryKey(netOptions.parameters)
107+
// We don't use `netOptions` here because we manipulate the options in `useQuery`.
99108
const method = async (options: Options) => await client[methodName](options)
100109

101110
// For some reason, if we don't explicitly set these generic parameters, the inferred type for
102111
// `Data` sometimes, but not always, includes `Response`, which is incorrect. I don't know why.
103-
return useQuery<Options, Data>(netOptions, queryOptions, {
112+
return useQuery<Client, Options, Data>(netOptions, queryOptions, {
104113
method,
105114
queryKey,
106115
requiredParameters
107116
})
108117
}
109118
/**
110119
* Gets the applicable shipping methods for a certain shipment of a basket.
120+
* @parameter apiOptions - Options to pass through to `commerce-sdk-isomorphic`, with `null` accepted for unset API parameters.
121+
* @parameter queryOptions - TanStack Query query options, with `enabled` by default set to check that all required API parameters have been set.
111122
* @returns A TanStack Query query hook with data from the Shopper Baskets `getShippingMethodsForShipment` endpoint.
112123
* @see {@link https://developer.salesforce.com/docs/commerce/commerce-api/references/shopper-baskets?meta=getShippingMethodsForShipment| Salesforce Developer Center} for more information about the API endpoint.
113124
* @see {@link https://salesforcecommercecloud.github.io/commerce-sdk-isomorphic/classes/shopperbaskets.shopperbaskets-1.html#getshippingmethodsforshipment | `commerce-sdk-isomorphic` documentation} for more information on the parameters and returned data type.
114125
* @see {@link https://tanstack.com/query/latest/docs/react/reference/useQuery | TanStack Query `useQuery` reference} for more information about the return value.
115126
*/
116127
export const useShippingMethodsForShipment = (
117-
apiOptions: Argument<Client['getShippingMethodsForShipment']>,
128+
apiOptions: NullableParameters<Argument<Client['getShippingMethodsForShipment']>>,
118129
queryOptions: ApiQueryOptions<Client['getShippingMethodsForShipment']> = {}
119130
): UseQueryResult<DataType<Client['getShippingMethodsForShipment']>> => {
120131
type Options = Argument<Client['getShippingMethodsForShipment']>
@@ -123,29 +134,32 @@ export const useShippingMethodsForShipment = (
123134
const methodName = 'getShippingMethodsForShipment'
124135
const requiredParameters = ['organizationId', 'basketId', 'shipmentId', 'siteId'] as const
125136

126-
// Parameters can be set in `apiOptions` or `client.clientConfig`, we must merge them in order
127-
// to generate the correct query key.
128-
const netOptions = mergeOptions(client, apiOptions)
137+
// Parameters can be set in `apiOptions` or `client.clientConfig`;
138+
// we must merge them in order to generate the correct query key.
139+
const netOptions = omitNullableParameters(mergeOptions(client, apiOptions))
129140
const queryKey = queryKeyHelpers[methodName].queryKey(netOptions.parameters)
141+
// We don't use `netOptions` here because we manipulate the options in `useQuery`.
130142
const method = async (options: Options) => await client[methodName](options)
131143

132144
// For some reason, if we don't explicitly set these generic parameters, the inferred type for
133145
// `Data` sometimes, but not always, includes `Response`, which is incorrect. I don't know why.
134-
return useQuery<Options, Data>(netOptions, queryOptions, {
146+
return useQuery<Client, Options, Data>(netOptions, queryOptions, {
135147
method,
136148
queryKey,
137149
requiredParameters
138150
})
139151
}
140152
/**
141153
* This method gives you the external taxation data set by the PUT taxes API. This endpoint can be called only if external taxation mode was used for basket creation. See POST /baskets for more information.
154+
* @parameter apiOptions - Options to pass through to `commerce-sdk-isomorphic`, with `null` accepted for unset API parameters.
155+
* @parameter queryOptions - TanStack Query query options, with `enabled` by default set to check that all required API parameters have been set.
142156
* @returns A TanStack Query query hook with data from the Shopper Baskets `getTaxesFromBasket` endpoint.
143157
* @see {@link https://developer.salesforce.com/docs/commerce/commerce-api/references/shopper-baskets?meta=getTaxesFromBasket| Salesforce Developer Center} for more information about the API endpoint.
144158
* @see {@link https://salesforcecommercecloud.github.io/commerce-sdk-isomorphic/classes/shopperbaskets.shopperbaskets-1.html#gettaxesfrombasket | `commerce-sdk-isomorphic` documentation} for more information on the parameters and returned data type.
145159
* @see {@link https://tanstack.com/query/latest/docs/react/reference/useQuery | TanStack Query `useQuery` reference} for more information about the return value.
146160
*/
147161
export const useTaxesFromBasket = (
148-
apiOptions: Argument<Client['getTaxesFromBasket']>,
162+
apiOptions: NullableParameters<Argument<Client['getTaxesFromBasket']>>,
149163
queryOptions: ApiQueryOptions<Client['getTaxesFromBasket']> = {}
150164
): UseQueryResult<DataType<Client['getTaxesFromBasket']>> => {
151165
type Options = Argument<Client['getTaxesFromBasket']>
@@ -154,15 +168,16 @@ export const useTaxesFromBasket = (
154168
const methodName = 'getTaxesFromBasket'
155169
const requiredParameters = ['organizationId', 'basketId', 'siteId'] as const
156170

157-
// Parameters can be set in `apiOptions` or `client.clientConfig`, we must merge them in order
158-
// to generate the correct query key.
159-
const netOptions = mergeOptions(client, apiOptions)
171+
// Parameters can be set in `apiOptions` or `client.clientConfig`;
172+
// we must merge them in order to generate the correct query key.
173+
const netOptions = omitNullableParameters(mergeOptions(client, apiOptions))
160174
const queryKey = queryKeyHelpers[methodName].queryKey(netOptions.parameters)
175+
// We don't use `netOptions` here because we manipulate the options in `useQuery`.
161176
const method = async (options: Options) => await client[methodName](options)
162177

163178
// For some reason, if we don't explicitly set these generic parameters, the inferred type for
164179
// `Data` sometimes, but not always, includes `Response`, which is incorrect. I don't know why.
165-
return useQuery<Options, Data>(netOptions, queryOptions, {
180+
return useQuery<Client, Options, Data>(netOptions, queryOptions, {
166181
method,
167182
queryKey,
168183
requiredParameters

packages/commerce-sdk-react/src/hooks/ShopperBaskets/queryKeyHelpers.ts

+17-11
Original file line numberDiff line numberDiff line change
@@ -10,40 +10,46 @@ import {pick} from '../utils'
1010

1111
// We must use a client with no parameters in order to have required/optional match the API spec
1212
type Client = ShopperBaskets<{shortCode: string}>
13-
type Params<T extends keyof QueryKeys> = NonNullable<Argument<Client[T]>['parameters']>
13+
type Params<T extends keyof QueryKeys> = Partial<Argument<Client[T]>['parameters']>
1414
export type QueryKeys = {
15-
getBasket: ['/organizations/', string, '/baskets/', string, Params<'getBasket'>]
15+
getBasket: [
16+
'/organizations/',
17+
string | undefined,
18+
'/baskets/',
19+
string | undefined,
20+
Params<'getBasket'>
21+
]
1622
getPaymentMethodsForBasket: [
1723
'/organizations/',
18-
string,
24+
string | undefined,
1925
'/baskets/',
20-
string,
26+
string | undefined,
2127
'/payment-methods',
2228
Params<'getPaymentMethodsForBasket'>
2329
]
2430
getPriceBooksForBasket: [
2531
'/organizations/',
26-
string,
32+
string | undefined,
2733
'/baskets/',
28-
string,
34+
string | undefined,
2935
'/price-books',
3036
Params<'getPriceBooksForBasket'>
3137
]
3238
getShippingMethodsForShipment: [
3339
'/organizations/',
34-
string,
40+
string | undefined,
3541
'/baskets/',
36-
string,
42+
string | undefined,
3743
'/shipments/',
38-
string,
44+
string | undefined,
3945
'/shipping-methods',
4046
Params<'getShippingMethodsForShipment'>
4147
]
4248
getTaxesFromBasket: [
4349
'/organizations/',
44-
string,
50+
string | undefined,
4551
'/baskets/',
46-
string,
52+
string | undefined,
4753
'/taxes',
4854
Params<'getTaxesFromBasket'>
4955
]

packages/commerce-sdk-react/src/hooks/ShopperContexts/query.ts

+10-7
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,25 @@
55
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
66
*/
77
import {UseQueryResult} from '@tanstack/react-query'
8-
import {ApiClients, ApiQueryOptions, Argument, DataType} from '../types'
8+
import {ApiClients, ApiQueryOptions, Argument, DataType, NullableParameters} from '../types'
99
import useCommerceApi from '../useCommerceApi'
1010
import {useQuery} from '../useQuery'
11-
import {mergeOptions} from '../utils'
11+
import {mergeOptions, omitNullableParameters} from '../utils'
1212
import * as queryKeyHelpers from './queryKeyHelpers'
1313

1414
type Client = ApiClients['shopperContexts']
1515

1616
/**
1717
* Gets the shopper's context based on the shopperJWT. ******** This API is currently a work in progress, and not available to use yet. ********
18+
* @parameter apiOptions - Options to pass through to `commerce-sdk-isomorphic`, with `null` accepted for unset API parameters.
19+
* @parameter queryOptions - TanStack Query query options, with `enabled` by default set to check that all required API parameters have been set.
1820
* @returns A TanStack Query query hook with data from the Shopper Contexts `getShopperContext` endpoint.
1921
* @see {@link https://developer.salesforce.com/docs/commerce/commerce-api/references/shopper-contexts?meta=getShopperContext| Salesforce Developer Center} for more information about the API endpoint.
2022
* @see {@link https://salesforcecommercecloud.github.io/commerce-sdk-isomorphic/classes/shoppercontexts.shoppercontexts-1.html#getshoppercontext | `commerce-sdk-isomorphic` documentation} for more information on the parameters and returned data type.
2123
* @see {@link https://tanstack.com/query/latest/docs/react/reference/useQuery | TanStack Query `useQuery` reference} for more information about the return value.
2224
*/
2325
export const useShopperContext = (
24-
apiOptions: Argument<Client['getShopperContext']>,
26+
apiOptions: NullableParameters<Argument<Client['getShopperContext']>>,
2527
queryOptions: ApiQueryOptions<Client['getShopperContext']> = {}
2628
): UseQueryResult<DataType<Client['getShopperContext']>> => {
2729
type Options = Argument<Client['getShopperContext']>
@@ -30,15 +32,16 @@ export const useShopperContext = (
3032
const methodName = 'getShopperContext'
3133
const requiredParameters = ['organizationId', 'usid'] as const
3234

33-
// Parameters can be set in `apiOptions` or `client.clientConfig`, we must merge them in order
34-
// to generate the correct query key.
35-
const netOptions = mergeOptions(client, apiOptions)
35+
// Parameters can be set in `apiOptions` or `client.clientConfig`;
36+
// we must merge them in order to generate the correct query key.
37+
const netOptions = omitNullableParameters(mergeOptions(client, apiOptions))
3638
const queryKey = queryKeyHelpers[methodName].queryKey(netOptions.parameters)
39+
// We don't use `netOptions` here because we manipulate the options in `useQuery`.
3740
const method = async (options: Options) => await client[methodName](options)
3841

3942
// For some reason, if we don't explicitly set these generic parameters, the inferred type for
4043
// `Data` sometimes, but not always, includes `Response`, which is incorrect. I don't know why.
41-
return useQuery<Options, Data>(netOptions, queryOptions, {
44+
return useQuery<Client, Options, Data>(netOptions, queryOptions, {
4245
method,
4346
queryKey,
4447
requiredParameters

packages/commerce-sdk-react/src/hooks/ShopperContexts/queryKeyHelpers.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ import {pick} from '../utils'
1010

1111
// We must use a client with no parameters in order to have required/optional match the API spec
1212
type Client = ShopperContexts<{shortCode: string}>
13-
type Params<T extends keyof QueryKeys> = NonNullable<Argument<Client[T]>['parameters']>
13+
type Params<T extends keyof QueryKeys> = Partial<Argument<Client[T]>['parameters']>
1414
export type QueryKeys = {
1515
getShopperContext: [
1616
'/organizations/',
17-
string,
17+
string | undefined,
1818
'/shopper-context/',
19-
string,
19+
string | undefined,
2020
Params<'getShopperContext'>
2121
]
2222
}

0 commit comments

Comments
 (0)