Skip to content

Commit 4b6529f

Browse files
authored
fix(plugin-ecommerce): issue with slug map ignoring variants and threading through cart data (#15234)
Fixes an issue with slug map ignoring that variants can be disabled which leads to an error when generating types. Fixes a bug where we're not threading through the remaining cart data to transactions so any custom fields are lost.
1 parent 6827978 commit 4b6529f

5 files changed

Lines changed: 159 additions & 46 deletions

File tree

packages/plugin-ecommerce/src/index.ts

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,6 @@ export const ecommercePlugin =
2929
}
3030

3131
const sanitizedPluginConfig = sanitizePluginConfig({ pluginConfig })
32-
/**
33-
* Used to keep track of the slugs of collections in case they are overridden by the user.
34-
*/
35-
const collectionSlugMap = getCollectionSlugMap({ sanitizedPluginConfig })
3632

3733
const accessConfig = sanitizedPluginConfig.access
3834

@@ -41,8 +37,21 @@ export const ecommercePlugin =
4137
incomingConfig.collections = []
4238
}
4339

44-
// Controls whether variants are enabled in the plugin. This is toggled to true under products config
45-
let enableVariants = false
40+
// Determine if variants are enabled based on products config
41+
const productsConfig =
42+
typeof sanitizedPluginConfig.products === 'boolean'
43+
? sanitizedPluginConfig.products
44+
? { variants: true }
45+
: undefined
46+
: sanitizedPluginConfig.products
47+
48+
const enableVariants = Boolean(productsConfig?.variants)
49+
50+
/**
51+
* Used to keep track of the slugs of collections in case they are overridden by the user.
52+
* Variant-related slugs are only included when variants are enabled.
53+
*/
54+
const collectionSlugMap = getCollectionSlugMap({ enableVariants, sanitizedPluginConfig })
4655

4756
const currenciesConfig: Required<SanitizedEcommercePluginConfig['currencies']> =
4857
sanitizedPluginConfig.currencies
@@ -74,16 +83,7 @@ export const ecommercePlugin =
7483
incomingConfig.collections.push(addressesCollection)
7584
}
7685

77-
if (sanitizedPluginConfig.products) {
78-
const productsConfig =
79-
typeof sanitizedPluginConfig.products === 'boolean'
80-
? {
81-
variants: true,
82-
}
83-
: sanitizedPluginConfig.products
84-
85-
enableVariants = Boolean(productsConfig.variants)
86-
86+
if (productsConfig) {
8787
if (productsConfig.variants) {
8888
const variantsConfig =
8989
typeof productsConfig.variants === 'boolean' ? undefined : productsConfig.variants
@@ -93,8 +93,8 @@ export const ecommercePlugin =
9393
currenciesConfig,
9494
inventory: sanitizedPluginConfig.inventory,
9595
productsSlug: collectionSlugMap.products,
96-
variantOptionsSlug: collectionSlugMap.variantOptions,
97-
variantTypesSlug: collectionSlugMap.variantTypes,
96+
variantOptionsSlug: collectionSlugMap.variantOptions ?? 'variantOptions',
97+
variantTypesSlug: collectionSlugMap.variantTypes ?? 'variantTypes',
9898
})
9999

100100
const variants =
@@ -109,7 +109,7 @@ export const ecommercePlugin =
109109

110110
const defaultVariantTypesCollection = createVariantTypesCollection({
111111
access: accessConfig,
112-
variantOptionsSlug: collectionSlugMap.variantOptions,
112+
variantOptionsSlug: collectionSlugMap.variantOptions ?? 'variantOptions',
113113
})
114114

115115
const variantTypes =
@@ -124,7 +124,7 @@ export const ecommercePlugin =
124124

125125
const defaultVariantOptionsCollection = createVariantOptionsCollection({
126126
access: accessConfig,
127-
variantTypesSlug: collectionSlugMap.variantTypes,
127+
variantTypesSlug: collectionSlugMap.variantTypes ?? 'variantTypes',
128128
})
129129

130130
const variantOptions =
@@ -145,8 +145,8 @@ export const ecommercePlugin =
145145
currenciesConfig,
146146
enableVariants,
147147
inventory: sanitizedPluginConfig.inventory,
148-
variantsSlug: collectionSlugMap.variants,
149-
variantTypesSlug: collectionSlugMap.variantTypes,
148+
variantsSlug: collectionSlugMap.variants ?? 'variants',
149+
variantTypesSlug: collectionSlugMap.variantTypes ?? 'variantTypes',
150150
})
151151

152152
const productsCollection =
@@ -172,7 +172,7 @@ export const ecommercePlugin =
172172
customersSlug: collectionSlugMap.customers,
173173
enableVariants: Boolean(productsConfig.variants),
174174
productsSlug: collectionSlugMap.products,
175-
variantsSlug: collectionSlugMap.variants,
175+
variantsSlug: collectionSlugMap.variants ?? 'variants',
176176
})
177177

178178
const cartsCollection =
@@ -197,7 +197,7 @@ export const ecommercePlugin =
197197
customersSlug: collectionSlugMap.customers,
198198
enableVariants,
199199
productsSlug: collectionSlugMap.products,
200-
variantsSlug: collectionSlugMap.variants,
200+
variantsSlug: collectionSlugMap.variants ?? 'variants',
201201
})
202202

203203
const ordersCollection =
@@ -238,7 +238,7 @@ export const ecommercePlugin =
238238
productsSlug: collectionSlugMap.products,
239239
productsValidation,
240240
transactionsSlug: collectionSlugMap.transactions,
241-
variantsSlug: collectionSlugMap.variants,
241+
variantsSlug: collectionSlugMap.variants ?? 'variants',
242242
}),
243243
method: 'post',
244244
path: `${methodPath}/initiate`,
@@ -250,8 +250,10 @@ export const ecommercePlugin =
250250
currenciesConfig,
251251
ordersSlug: collectionSlugMap.orders,
252252
paymentMethod,
253+
productsSlug: collectionSlugMap.products,
253254
productsValidation,
254255
transactionsSlug: collectionSlugMap.transactions,
256+
variantsSlug: collectionSlugMap.variants ?? 'variants',
255257
}),
256258
method: 'post',
257259
path: `${methodPath}/confirm-order`,
@@ -289,7 +291,7 @@ export const ecommercePlugin =
289291
ordersSlug: collectionSlugMap.orders,
290292
paymentMethods,
291293
productsSlug: collectionSlugMap.products,
292-
variantsSlug: collectionSlugMap.variants,
294+
variantsSlug: collectionSlugMap.variants ?? 'variants',
293295
})
294296

295297
const transactionsCollection =

packages/plugin-ecommerce/src/payments/adapters/stripe/initiatePayment.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,15 @@ export const initiatePayment: (props: Props) => NonNullable<PaymentAdapter>['ini
7474
: item.variant
7575
: undefined
7676

77+
// Preserve any additional custom properties (e.g., deliveryOption, customizations)
78+
// that may have been added via cartItemMatcher
79+
const { product: _product, variant: _variant, ...customProperties } = item
80+
7781
return {
82+
...customProperties,
7883
product: productID,
7984
quantity: item.quantity,
80-
variant: variantID,
85+
...(variantID ? { variant: variantID } : {}),
8186
}
8287
})
8388

packages/plugin-ecommerce/src/types/index.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,7 @@ export type ProductsValidation = (args: {
617617
/**
618618
* A map of collection slugs used by the Ecommerce plugin.
619619
* Provides an easy way to track the slugs of collections even when they are overridden.
620+
* Variant-related slugs are only present when variants are enabled.
620621
*/
621622
export type CollectionSlugMap = {
622623
addresses: string
@@ -625,9 +626,9 @@ export type CollectionSlugMap = {
625626
orders: string
626627
products: string
627628
transactions: string
628-
variantOptions: string
629-
variants: string
630-
variantTypes: string
629+
variantOptions?: string
630+
variants?: string
631+
variantTypes?: string
631632
}
632633

633634
/**

packages/plugin-ecommerce/src/utilities/getCollectionSlugMap.spec.ts

Lines changed: 98 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,22 @@ describe('getCollectionSlugMap', () => {
3636
transactions: true,
3737
}
3838

39-
it('should return default slug map when no overrides are provided', () => {
39+
it('should return default slug map without variant slugs when enableVariants is false', () => {
4040
const result = getCollectionSlugMap({ sanitizedPluginConfig: baseConfig })
4141

42+
expect(result).toEqual({
43+
addresses: 'addresses',
44+
carts: 'carts',
45+
customers: 'users',
46+
orders: 'orders',
47+
products: 'products',
48+
transactions: 'transactions',
49+
})
50+
})
51+
52+
it('should return default slug map with variant slugs when enableVariants is true', () => {
53+
const result = getCollectionSlugMap({ enableVariants: true, sanitizedPluginConfig: baseConfig })
54+
4255
expect(result).toEqual({
4356
addresses: 'addresses',
4457
carts: 'carts',
@@ -60,12 +73,12 @@ describe('getCollectionSlugMap', () => {
6073
},
6174
}
6275

63-
const result = getCollectionSlugMap({ sanitizedPluginConfig: config })
76+
const result = getCollectionSlugMap({ enableVariants: true, sanitizedPluginConfig: config })
6477

6578
expect(result.customers).toBe('custom-users')
6679
})
6780

68-
it('should apply slugMap overrides', () => {
81+
it('should apply slugMap overrides when variants enabled', () => {
6982
const config: SanitizedEcommercePluginConfig = {
7083
...baseConfig,
7184
slugMap: {
@@ -75,7 +88,7 @@ describe('getCollectionSlugMap', () => {
7588
},
7689
}
7790

78-
const result = getCollectionSlugMap({ sanitizedPluginConfig: config })
91+
const result = getCollectionSlugMap({ enableVariants: true, sanitizedPluginConfig: config })
7992

8093
expect(result.products).toBe('custom-products')
8194
expect(result.variants).toBe('custom-variants')
@@ -85,6 +98,23 @@ describe('getCollectionSlugMap', () => {
8598
expect(result.carts).toBe('carts')
8699
})
87100

101+
it('should not apply variant slugMap overrides when variants disabled', () => {
102+
const config: SanitizedEcommercePluginConfig = {
103+
...baseConfig,
104+
slugMap: {
105+
products: 'custom-products',
106+
variants: 'custom-variants',
107+
orders: 'custom-orders',
108+
},
109+
}
110+
111+
const result = getCollectionSlugMap({ enableVariants: false, sanitizedPluginConfig: config })
112+
113+
expect(result.products).toBe('custom-products')
114+
expect(result.variants).toBeUndefined()
115+
expect(result.orders).toBe('custom-orders')
116+
})
117+
88118
it('should prioritize slugMap overrides over customers slug', () => {
89119
const config: SanitizedEcommercePluginConfig = {
90120
...baseConfig,
@@ -96,20 +126,20 @@ describe('getCollectionSlugMap', () => {
96126
},
97127
}
98128

99-
const result = getCollectionSlugMap({ sanitizedPluginConfig: config })
129+
const result = getCollectionSlugMap({ enableVariants: true, sanitizedPluginConfig: config })
100130

101131
expect(result.customers).toBe('overridden-users')
102132
})
103133

104-
it('should handle partial slugMap overrides', () => {
134+
it('should handle partial slugMap overrides with variants enabled', () => {
105135
const config: SanitizedEcommercePluginConfig = {
106136
...baseConfig,
107137
slugMap: {
108138
products: 'items',
109139
},
110140
}
111141

112-
const result = getCollectionSlugMap({ sanitizedPluginConfig: config })
142+
const result = getCollectionSlugMap({ enableVariants: true, sanitizedPluginConfig: config })
113143

114144
expect(result.products).toBe('items')
115145
expect(result.addresses).toBe('addresses')
@@ -122,13 +152,34 @@ describe('getCollectionSlugMap', () => {
122152
expect(result.variantTypes).toBe('variantTypes')
123153
})
124154

125-
it('should handle empty slugMap', () => {
155+
it('should handle partial slugMap overrides with variants disabled', () => {
156+
const config: SanitizedEcommercePluginConfig = {
157+
...baseConfig,
158+
slugMap: {
159+
products: 'items',
160+
},
161+
}
162+
163+
const result = getCollectionSlugMap({ enableVariants: false, sanitizedPluginConfig: config })
164+
165+
expect(result.products).toBe('items')
166+
expect(result.addresses).toBe('addresses')
167+
expect(result.carts).toBe('carts')
168+
expect(result.customers).toBe('users')
169+
expect(result.orders).toBe('orders')
170+
expect(result.transactions).toBe('transactions')
171+
expect(result.variants).toBeUndefined()
172+
expect(result.variantOptions).toBeUndefined()
173+
expect(result.variantTypes).toBeUndefined()
174+
})
175+
176+
it('should handle empty slugMap with variants enabled', () => {
126177
const config: SanitizedEcommercePluginConfig = {
127178
...baseConfig,
128179
slugMap: {},
129180
}
130181

131-
const result = getCollectionSlugMap({ sanitizedPluginConfig: config })
182+
const result = getCollectionSlugMap({ enableVariants: true, sanitizedPluginConfig: config })
132183

133184
expect(result).toEqual({
134185
addresses: 'addresses',
@@ -143,13 +194,31 @@ describe('getCollectionSlugMap', () => {
143194
})
144195
})
145196

146-
it('should handle undefined slugMap', () => {
197+
it('should handle empty slugMap with variants disabled', () => {
198+
const config: SanitizedEcommercePluginConfig = {
199+
...baseConfig,
200+
slugMap: {},
201+
}
202+
203+
const result = getCollectionSlugMap({ enableVariants: false, sanitizedPluginConfig: config })
204+
205+
expect(result).toEqual({
206+
addresses: 'addresses',
207+
carts: 'carts',
208+
customers: 'users',
209+
orders: 'orders',
210+
products: 'products',
211+
transactions: 'transactions',
212+
})
213+
})
214+
215+
it('should handle undefined slugMap with variants enabled', () => {
147216
const config: SanitizedEcommercePluginConfig = {
148217
...baseConfig,
149218
slugMap: undefined,
150219
}
151220

152-
const result = getCollectionSlugMap({ sanitizedPluginConfig: config })
221+
const result = getCollectionSlugMap({ enableVariants: true, sanitizedPluginConfig: config })
153222

154223
expect(result).toEqual({
155224
addresses: 'addresses',
@@ -163,4 +232,22 @@ describe('getCollectionSlugMap', () => {
163232
variantTypes: 'variantTypes',
164233
})
165234
})
235+
236+
it('should handle undefined slugMap with variants disabled', () => {
237+
const config: SanitizedEcommercePluginConfig = {
238+
...baseConfig,
239+
slugMap: undefined,
240+
}
241+
242+
const result = getCollectionSlugMap({ enableVariants: false, sanitizedPluginConfig: config })
243+
244+
expect(result).toEqual({
245+
addresses: 'addresses',
246+
carts: 'carts',
247+
customers: 'users',
248+
orders: 'orders',
249+
products: 'products',
250+
transactions: 'transactions',
251+
})
252+
})
166253
})

0 commit comments

Comments
 (0)