Skip to content

Commit c9a2723

Browse files
refactor: Create Interfaces for eCommerce (#964)
1 parent 9691517 commit c9a2723

10 files changed

+238
-30
lines changed

src/ecommerce.interfaces.ts

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
import {
2+
ProductAction,
3+
Product,
4+
Promotion,
5+
CommerceEvent,
6+
} from '@mparticle/event-models';
7+
import {
8+
SDKEventAttrs,
9+
SDKEventOptions,
10+
TransactionAttributes,
11+
} from '@mparticle/web-sdk';
12+
import { valueof } from './utils';
13+
import {
14+
ProductActionType,
15+
PromotionActionType,
16+
CommerceEventType,
17+
EventType,
18+
} from './types';
19+
import {
20+
SDKEvent,
21+
SDKEventCustomFlags,
22+
SDKImpression,
23+
SDKProduct,
24+
SDKProductImpression,
25+
SDKPromotion,
26+
} from './sdkRuntimeModels';
27+
28+
interface IECommerceShared {
29+
createProduct(
30+
name: string,
31+
sku: string | number,
32+
price: string | number,
33+
quantity?: string | number,
34+
variant?: string,
35+
category?: string,
36+
brand?: string,
37+
position?: number,
38+
couponCode?: string,
39+
attributes?: SDKEventAttrs
40+
): SDKProduct | null;
41+
createImpression(name: string, product: Product): SDKImpression | null;
42+
createPromotion(
43+
id: string | number,
44+
creative?: string,
45+
name?: string,
46+
position?: number
47+
): SDKPromotion | null;
48+
createTransactionAttributes(
49+
id: string | number,
50+
affiliation?: string,
51+
couponCode?: string,
52+
revenue?: string | number,
53+
shipping?: string | number,
54+
tax?: number
55+
): TransactionAttributes | null;
56+
expandCommerceEvent(event: CommerceEvent): SDKEvent[] | null;
57+
}
58+
59+
export interface SDKCart {
60+
add(product: SDKProduct | SDKProduct[], logEvent?: boolean): void;
61+
remove(product: SDKProduct | SDKProduct[], logEvent?: boolean): void;
62+
clear(): void;
63+
}
64+
65+
// Used for the public `eCommerce` namespace
66+
export interface SDKECommerceAPI extends IECommerceShared {
67+
logCheckout(
68+
step: number,
69+
option?: string,
70+
attrs?: SDKEventAttrs,
71+
customFlags?: SDKEventCustomFlags
72+
): void;
73+
logImpression(
74+
impression: SDKProductImpression,
75+
attrs?: SDKEventAttrs,
76+
customFlags?: SDKEventCustomFlags,
77+
eventOptions?: SDKEventOptions
78+
): void;
79+
logProductAction(
80+
productActionType: valueof<typeof ProductActionType>,
81+
product: SDKProduct | SDKProduct[],
82+
attrs?: SDKEventAttrs,
83+
customFlags?: SDKEventCustomFlags,
84+
transactionAttributes?: TransactionAttributes,
85+
eventOptions?: SDKEventOptions
86+
): void;
87+
logPromotion(
88+
type: valueof<typeof PromotionActionType>,
89+
promotion: SDKPromotion,
90+
attrs?: SDKEventAttrs,
91+
customFlags?: SDKEventCustomFlags,
92+
eventOptions?: SDKEventOptions
93+
): void;
94+
setCurrencyCode(code: string): void;
95+
96+
/*
97+
* @deprecated
98+
*/
99+
Cart: SDKCart;
100+
101+
/*
102+
* @deprecated
103+
*/
104+
logPurchase(
105+
transactionAttributes: TransactionAttributes,
106+
product: SDKProduct | SDKProduct[],
107+
clearCart?: boolean,
108+
attrs?: SDKEventAttrs,
109+
customFlags?: SDKEventCustomFlags
110+
): void;
111+
112+
/*
113+
* @deprecated
114+
*/
115+
logRefund(
116+
transactionAttributes: TransactionAttributes,
117+
product: SDKProduct | SDKProduct[],
118+
clearCart?: boolean,
119+
attrs?: SDKEventAttrs,
120+
customFlags?: SDKEventCustomFlags
121+
): void;
122+
}
123+
124+
interface ExtractedActionAttributes {
125+
Affiliation?: string;
126+
'Coupon Code'?: string;
127+
'Total Amount'?: number;
128+
'Shipping Amount'?: number;
129+
'Tax Amount'?: number;
130+
'Checkout Option'?: string;
131+
'Checkout Step'?: number;
132+
'Transaction ID'?: string;
133+
}
134+
interface ExtractedProductAttributes {
135+
'Coupon Code'?: string;
136+
Brand?: string;
137+
Category?: string;
138+
Name?: string;
139+
Id?: string;
140+
'Item Price'?: number;
141+
Quantity?: number;
142+
Position?: number;
143+
Variant?: string;
144+
'Total Product Amount': number;
145+
}
146+
interface ExtractedPromotionAttributes {
147+
Id?: string;
148+
Creative?: string;
149+
Name?: string;
150+
Position?: number;
151+
}
152+
interface ExtractedTransactionId {
153+
'Transaction ID'?: string;
154+
}
155+
156+
// Used for the private `_Ecommerce` namespace
157+
export interface IECommerce extends IECommerceShared {
158+
buildProductList(event: SDKEvent, product: Product | Product[]): Product[];
159+
convertProductActionToEventType(
160+
productActionType: valueof<typeof ProductActionType>
161+
): // https://go.mparticle.com/work/SQDSDKS-4801
162+
typeof CommerceEventType | typeof EventType | null;
163+
convertPromotionActionToEventType(
164+
promotionActionType: valueof<typeof PromotionActionType>
165+
): typeof CommerceEventType | null;
166+
convertTransactionAttributesToProductAction(
167+
transactionAttributes: TransactionAttributes,
168+
productAction: ProductAction
169+
): void;
170+
createCommerceEventObject(
171+
customFlags: SDKEventCustomFlags,
172+
options?: SDKEventOptions
173+
): SDKEvent | null;
174+
expandProductAction(commerceEvent: CommerceEvent): SDKEvent[];
175+
expandProductImpression(commerceEvent: CommerceEvent): SDKEvent[];
176+
expandPromotionAction(commerceEvent: CommerceEvent): SDKEvent[];
177+
extractActionAttributes(
178+
attributes: ExtractedActionAttributes,
179+
productAction: ProductAction
180+
): void;
181+
extractProductAttributes(
182+
attributes: ExtractedProductAttributes,
183+
product: Product
184+
): void;
185+
extractPromotionAttributes(
186+
attributes: ExtractedPromotionAttributes,
187+
promotion: Promotion
188+
): void;
189+
extractTransactionId(
190+
attributes: ExtractedTransactionId,
191+
productAction: ProductAction
192+
): void;
193+
generateExpandedEcommerceName(eventName: string, plusOne: boolean): string;
194+
getProductActionEventName(
195+
productActionType: valueof<typeof ProductActionType>
196+
): string;
197+
getPromotionActionEventName(
198+
promotionActionType: valueof<typeof PromotionActionType>
199+
): string;
200+
sanitizeAmount(amount: string | number, category: string): number;
201+
}

src/ecommerce.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ var Messages = Constants.Messages;
55

66
export default function Ecommerce(mpInstance) {
77
var self = this;
8+
9+
// https://go.mparticle.com/work/SQDSDKS-4801
810
this.convertTransactionAttributesToProductAction = function(
911
transactionAttributes,
1012
productAction
@@ -103,8 +105,11 @@ export default function Ecommerce(mpInstance) {
103105
return Types.CommerceEventType.ProductRemoveFromCart;
104106
case Types.ProductActionType.RemoveFromWishlist:
105107
return Types.CommerceEventType.ProductRemoveFromWishlist;
108+
109+
// https://go.mparticle.com/work/SQDSDKS-4801
106110
case Types.ProductActionType.Unknown:
107111
return Types.EventType.Unknown;
112+
108113
case Types.ProductActionType.ViewDetail:
109114
return Types.CommerceEventType.ProductViewDetail;
110115
default:
@@ -139,6 +144,7 @@ export default function Ecommerce(mpInstance) {
139144
);
140145
};
141146

147+
// https://go.mparticle.com/work/SQDSDKS-4801
142148
this.extractProductAttributes = function(attributes, product) {
143149
if (product.CouponCode) {
144150
attributes['Coupon Code'] = product.CouponCode;
@@ -170,12 +176,14 @@ export default function Ecommerce(mpInstance) {
170176
attributes['Total Product Amount'] = product.TotalAmount || 0;
171177
};
172178

179+
// https://go.mparticle.com/work/SQDSDKS-4801
173180
this.extractTransactionId = function(attributes, productAction) {
174181
if (productAction.TransactionId) {
175182
attributes['Transaction Id'] = productAction.TransactionId;
176183
}
177184
};
178185

186+
// https://go.mparticle.com/work/SQDSDKS-4801
179187
this.extractActionAttributes = function(attributes, productAction) {
180188
self.extractTransactionId(attributes, productAction);
181189

@@ -208,6 +216,7 @@ export default function Ecommerce(mpInstance) {
208216
}
209217
};
210218

219+
// https://go.mparticle.com/work/SQDSDKS-4801
211220
this.extractPromotionAttributes = function(attributes, promotion) {
212221
if (promotion.Id) {
213222
attributes['Id'] = promotion.Id;

src/identity-user-interfaces.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
11
import { AllUserAttributes, MPID, Product, User } from '@mparticle/web-sdk';
22
import { SDKIdentityTypeEnum } from './identity.interfaces';
33
import { MessageType } from './types';
4-
import { BaseEvent } from './sdkRuntimeModels';
4+
import { BaseEvent, SDKProduct } from './sdkRuntimeModels';
55
import Constants from './constants';
66
const { HTTPCodes } = Constants;
77

88
// Cart is Deprecated and private to mParticle user in @mparticle/web-sdk
99
// but we need to expose it here for type safety in some of our tests
10-
interface Cart {
10+
interface ICart {
1111
/**
1212
* @deprecated Cart persistence in mParticle has been deprecated. Please use mParticle.eCommerce.logProductAction(mParticle.ProductActionType.AddToCart, [products])
1313
*/
14-
add: (product: Product, logEventBoolean?: boolean) => void;
14+
add: (product: SDKProduct, logEventBoolean?: boolean) => void;
1515
/**
1616
* @deprecated Cart persistence in mParticle has been deprecated. Please use mParticle.eCommerce.logProductAction(mParticle.ProductActionType.RemoveFromCart, [products])
1717
*/
18-
remove: (product: Product, logEventBoolean?: boolean) => void;
18+
remove: (product: SDKProduct, logEventBoolean?: boolean) => void;
1919
/**
2020
* @deprecated Cart persistence in mParticle has been deprecated.
2121
*/
2222
clear: () => void;
2323
/**
2424
* @deprecated Cart Products have been deprecated
2525
*/
26-
getCartProducts: () => Product[];
26+
getCartProducts: () => SDKProduct[];
2727
}
2828

2929
// https://go.mparticle.com/work/SQDSDKS-5033
@@ -36,7 +36,7 @@ export interface IMParticleUser extends User {
3636
/*
3737
* @deprecated
3838
*/
39-
getCart(): Cart;
39+
getCart(): ICart;
4040
}
4141

4242
export interface ISDKUserIdentity {

src/sdkRuntimeModels.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import IntegrationCapture from './integrationCapture';
4040
import { INativeSdkHelpers } from './nativeSdkHelpers.interfaces';
4141
import { ICookieSyncManager, IPixelConfiguration } from './cookieSyncManager';
4242
import { IEvents } from './events.interfaces';
43+
import { IECommerce, SDKECommerceAPI } from './ecommerce.interfaces';
4344

4445
// TODO: Resolve this with version in @mparticle/web-sdk
4546
export type SDKEventCustomFlags = Dictionary<any>;
@@ -107,6 +108,11 @@ export interface SDKPromotion {
107108
Position?: string;
108109
}
109110

111+
export interface SDKImpression {
112+
Name: string;
113+
Product: SDKProduct;
114+
}
115+
110116
export interface SDKProductImpression {
111117
ProductImpressionList?: string;
112118
ProductList?: SDKProduct[];
@@ -150,7 +156,9 @@ export interface SDKProduct {
150156
Position?: number;
151157
CouponCode?: string;
152158
TotalAmount?: number;
153-
Attributes?: { [key: string]: string };
159+
160+
// https://go.mparticle.com/work/SQDSDKS-4801
161+
Attributes?: Record<string, unknown> | null;
154162
}
155163

156164
export interface MParticleWebSDK {
@@ -170,6 +178,7 @@ export interface MParticleWebSDK {
170178
_Forwarders: any;
171179
_Helpers: SDKHelpersApi;
172180
_Events: IEvents;
181+
_Ecommerce: IECommerce;
173182
config: SDKInitConfig;
174183
_ServerModel: IServerModel;
175184
_SessionManager: ISessionManager;
@@ -208,7 +217,7 @@ export interface MParticleWebSDK {
208217
eventOptions?: SDKEventOptions
209218
): void;
210219
logBaseEvent(event: BaseEvent, eventOptions?: SDKEventOptions): void;
211-
eCommerce: any;
220+
eCommerce: SDKECommerceAPI;
212221
logLevel: string;
213222
ProductActionType: SDKProductActionType;
214223
generateHash(value: string): string;

src/sdkToEventsApiConverter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ export function convertProducts(
373373
price: sdkProduct.Price,
374374
quantity: sdkProduct.Quantity,
375375
coupon_code: sdkProduct.CouponCode,
376-
custom_attributes: sdkProduct.Attributes,
376+
custom_attributes: sdkProduct.Attributes as Record<string, string>,
377377
};
378378
products.push(product);
379379
}

src/serverModel.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ export interface IProductV2DTO {
110110
ps: number;
111111
cc: string | number;
112112
tpa: number;
113-
attrs: Record<string, string> | null;
113+
attrs: Record<string, unknown> | undefined;
114114
}
115115

116116
export interface IPromotionV2DTO {

test/src/tests-batchUploader_3.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
11
import sinon from 'sinon';
22
import { urls, apiKey, MPConfig, testMPID } from './config/constants';
33
import {
4-
BaseEvent,
54
MParticleWebSDK,
6-
SDKEvent,
7-
SDKProductActionType,
85
} from '../../src/sdkRuntimeModels';
9-
import { Batch, CustomEventData } from '@mparticle/event-models';
106
import Utils from './config/utils';
11-
import { BatchUploader } from '../../src/batchUploader';
127
import { expect } from 'chai';
138
import _BatchValidator from '../../src/mockBatchCreator';
14-
import Logger from '../../src/logger.js';
15-
import { event0, event1, event2, event3 } from '../fixtures/events';
169
import fetchMock from 'fetch-mock/esm/client';
10+
import { ProductActionType } from '../../src/types';
1711
const { fetchMockSuccess, waitForCondition, hasIdentifyReturned } = Utils;
1812

1913
declare global {
@@ -137,7 +131,7 @@ describe('batch uploader', () => {
137131
window.mParticle.logEvent('Test Event');
138132

139133
var product1 = window.mParticle.eCommerce.createProduct('iphone', 'iphoneSKU', 999);
140-
window.mParticle.eCommerce.logProductAction(SDKProductActionType.AddToCart, product1);
134+
window.mParticle.eCommerce.logProductAction(ProductActionType.AddToCart, product1);
141135

142136
const lastCall = fetchMock.lastCall();
143137
const endpoint = lastCall[0];

0 commit comments

Comments
 (0)