@mparticle/web-sdk 2.18.3 → 2.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mparticle.common.js +70 -20
- package/dist/mparticle.esm.js +70 -20
- package/dist/mparticle.js +202 -141
- package/package.json +1 -1
- package/src/apiClient.ts +1 -1
- package/src/batchUploader.ts +146 -109
- package/src/{consent.js → consent.ts} +228 -72
- package/src/cookieSyncManager.js +40 -0
- package/src/mockBatchCreator.ts +3 -0
- package/src/sdkRuntimeModels.ts +4 -3
- package/src/sdkToEventsApiConverter.ts +1 -1
- package/src/serverModel.ts +34 -32
- package/src/store.ts +5 -4
- package/src/vault.ts +141 -0
- package/src/consent.interfaces.ts +0 -89
package/src/serverModel.ts
CHANGED
|
@@ -17,17 +17,17 @@ import { parseNumber, parseStringOrNumber, Dictionary } from './utils';
|
|
|
17
17
|
import { ServerSettings } from './store';
|
|
18
18
|
import { MPID } from '@mparticle/web-sdk';
|
|
19
19
|
import {
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
IConsentStateV2DTO,
|
|
21
|
+
IGDPRConsentStateV2DTO,
|
|
22
22
|
IPrivacyV2DTO,
|
|
23
23
|
SDKConsentState,
|
|
24
|
-
} from './consent
|
|
24
|
+
} from './consent';
|
|
25
25
|
|
|
26
26
|
const MessageType = Types.MessageType;
|
|
27
27
|
const ApplicationTransitionType = Types.ApplicationTransitionType;
|
|
28
28
|
|
|
29
29
|
// TODO: Confirm which attributes are optional
|
|
30
|
-
export interface
|
|
30
|
+
export interface IServerV2DTO {
|
|
31
31
|
id: string | number;
|
|
32
32
|
nm: string | number;
|
|
33
33
|
pr: number;
|
|
@@ -61,7 +61,7 @@ export interface IServerDTO {
|
|
|
61
61
|
das?: string;
|
|
62
62
|
mpid?: MPID;
|
|
63
63
|
smpids?: MPID[];
|
|
64
|
-
con?:
|
|
64
|
+
con?: IConsentStateV2DTO;
|
|
65
65
|
fr?: boolean;
|
|
66
66
|
iu?: boolean; // isUpgrade
|
|
67
67
|
at?: number;
|
|
@@ -69,13 +69,13 @@ export interface IServerDTO {
|
|
|
69
69
|
flags?: Dictionary<string[]>;
|
|
70
70
|
cu?: string;
|
|
71
71
|
sc?: {
|
|
72
|
-
pl:
|
|
72
|
+
pl: IProductV2DTO[];
|
|
73
73
|
};
|
|
74
74
|
pd?: {
|
|
75
75
|
an: number;
|
|
76
76
|
cs: number;
|
|
77
77
|
co: string;
|
|
78
|
-
pl:
|
|
78
|
+
pl: IProductV2DTO[];
|
|
79
79
|
ta: string;
|
|
80
80
|
ti: string;
|
|
81
81
|
tcc: string;
|
|
@@ -85,13 +85,13 @@ export interface IServerDTO {
|
|
|
85
85
|
};
|
|
86
86
|
pm?: {
|
|
87
87
|
an: string;
|
|
88
|
-
pl:
|
|
88
|
+
pl: IPromotionV2DTO[];
|
|
89
89
|
};
|
|
90
|
-
pi?:
|
|
90
|
+
pi?: IProductImpressionV2DTO[];
|
|
91
91
|
pet?: number;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
export interface
|
|
94
|
+
export interface IProductV2DTO {
|
|
95
95
|
id: string | number;
|
|
96
96
|
nm: string | number;
|
|
97
97
|
pr: number;
|
|
@@ -105,16 +105,16 @@ export interface IProductDTO {
|
|
|
105
105
|
attrs: Record<string, string> | null;
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
export interface
|
|
108
|
+
export interface IPromotionV2DTO {
|
|
109
109
|
id: string | number;
|
|
110
110
|
nm: string | number;
|
|
111
111
|
ps: string | number;
|
|
112
112
|
cr: string;
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
export interface
|
|
115
|
+
export interface IProductImpressionV2DTO {
|
|
116
116
|
pil: string;
|
|
117
|
-
pl:
|
|
117
|
+
pl: IProductV2DTO[];
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
export interface IUploadObject extends SDKEvent {
|
|
@@ -129,14 +129,14 @@ export interface IUploadObject extends SDKEvent {
|
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
export interface IServerModel {
|
|
132
|
-
|
|
132
|
+
convertEventToV2DTO: (event: IUploadObject) => IServerV2DTO;
|
|
133
133
|
createEventObject: (event: BaseEvent, user?: MParticleUser) => SDKEvent;
|
|
134
|
-
|
|
134
|
+
convertToConsentStateV2DTO: (state: SDKConsentState) => IConsentStateV2DTO;
|
|
135
135
|
appendUserInfo: (user: MParticleUser, event: SDKEvent) => void;
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
// TODO: Make this a pure function that returns a new object
|
|
139
|
-
function convertCustomFlags(event: SDKEvent, dto:
|
|
139
|
+
function convertCustomFlags(event: SDKEvent, dto: IServerV2DTO) {
|
|
140
140
|
var valueArray: string[] = [];
|
|
141
141
|
dto.flags = {};
|
|
142
142
|
|
|
@@ -171,7 +171,7 @@ function convertCustomFlags(event: SDKEvent, dto: IServerDTO) {
|
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
function
|
|
174
|
+
function convertProductToV2DTO(product: SDKProduct): IProductV2DTO {
|
|
175
175
|
return {
|
|
176
176
|
id: parseStringOrNumber(product.Sku),
|
|
177
177
|
nm: parseStringOrNumber(product.Name),
|
|
@@ -187,13 +187,13 @@ function convertProductToDTO(product: SDKProduct): IProductDTO {
|
|
|
187
187
|
};
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
-
function
|
|
190
|
+
function convertProductListToV2DTO(productList: SDKProduct[]): IProductV2DTO[] {
|
|
191
191
|
if (!productList) {
|
|
192
192
|
return [];
|
|
193
193
|
}
|
|
194
194
|
|
|
195
195
|
return productList.map(function(product) {
|
|
196
|
-
return
|
|
196
|
+
return convertProductToV2DTO(product);
|
|
197
197
|
});
|
|
198
198
|
}
|
|
199
199
|
|
|
@@ -245,16 +245,16 @@ export default function ServerModel(
|
|
|
245
245
|
event.UserIdentities = validUserIdentities;
|
|
246
246
|
};
|
|
247
247
|
|
|
248
|
-
this.
|
|
248
|
+
this.convertToConsentStateV2DTO = function(
|
|
249
249
|
state: SDKConsentState
|
|
250
|
-
):
|
|
250
|
+
): IConsentStateV2DTO {
|
|
251
251
|
if (!state) {
|
|
252
252
|
return null;
|
|
253
253
|
}
|
|
254
|
-
var jsonObject:
|
|
254
|
+
var jsonObject: IConsentStateV2DTO = {};
|
|
255
255
|
var gdprConsentState = state.getGDPRConsentState();
|
|
256
256
|
if (gdprConsentState) {
|
|
257
|
-
var gdpr:
|
|
257
|
+
var gdpr: IGDPRConsentStateV2DTO = {};
|
|
258
258
|
jsonObject.gdpr = gdpr;
|
|
259
259
|
for (var purpose in gdprConsentState) {
|
|
260
260
|
if (gdprConsentState.hasOwnProperty(purpose)) {
|
|
@@ -292,7 +292,7 @@ export default function ServerModel(
|
|
|
292
292
|
};
|
|
293
293
|
}
|
|
294
294
|
|
|
295
|
-
return jsonObject as
|
|
295
|
+
return jsonObject as IConsentStateV2DTO;
|
|
296
296
|
};
|
|
297
297
|
|
|
298
298
|
this.createEventObject = function(
|
|
@@ -408,8 +408,8 @@ export default function ServerModel(
|
|
|
408
408
|
return null;
|
|
409
409
|
};
|
|
410
410
|
|
|
411
|
-
this.
|
|
412
|
-
var dto: Partial<
|
|
411
|
+
this.convertEventToV2DTO = function(event: IUploadObject): IServerV2DTO {
|
|
412
|
+
var dto: Partial<IServerV2DTO> = {
|
|
413
413
|
n: event.EventName,
|
|
414
414
|
et: event.EventCategory,
|
|
415
415
|
ua: event.UserAttributes,
|
|
@@ -441,7 +441,7 @@ export default function ServerModel(
|
|
|
441
441
|
}
|
|
442
442
|
}
|
|
443
443
|
|
|
444
|
-
var consent = self.
|
|
444
|
+
var consent = self.convertToConsentStateV2DTO(event.ConsentState);
|
|
445
445
|
if (consent) {
|
|
446
446
|
dto.con = consent;
|
|
447
447
|
}
|
|
@@ -458,7 +458,7 @@ export default function ServerModel(
|
|
|
458
458
|
}
|
|
459
459
|
|
|
460
460
|
if (event.CustomFlags) {
|
|
461
|
-
convertCustomFlags(event, dto as
|
|
461
|
+
convertCustomFlags(event, dto as IServerV2DTO);
|
|
462
462
|
}
|
|
463
463
|
|
|
464
464
|
if (event.EventDataType === MessageType.Commerce) {
|
|
@@ -467,7 +467,9 @@ export default function ServerModel(
|
|
|
467
467
|
// TODO: If Cart is deprecated, we should deprecate this too
|
|
468
468
|
if (event.ShoppingCart) {
|
|
469
469
|
dto.sc = {
|
|
470
|
-
pl:
|
|
470
|
+
pl: convertProductListToV2DTO(
|
|
471
|
+
event.ShoppingCart.ProductList
|
|
472
|
+
),
|
|
471
473
|
};
|
|
472
474
|
}
|
|
473
475
|
|
|
@@ -478,7 +480,7 @@ export default function ServerModel(
|
|
|
478
480
|
event.ProductAction.CheckoutStep
|
|
479
481
|
),
|
|
480
482
|
co: event.ProductAction.CheckoutOptions,
|
|
481
|
-
pl:
|
|
483
|
+
pl: convertProductListToV2DTO(
|
|
482
484
|
event.ProductAction.ProductList
|
|
483
485
|
),
|
|
484
486
|
ti: event.ProductAction.TransactionId,
|
|
@@ -512,7 +514,7 @@ export default function ServerModel(
|
|
|
512
514
|
dto.pi = event.ProductImpressions.map(function(impression) {
|
|
513
515
|
return {
|
|
514
516
|
pil: impression.ProductImpressionList,
|
|
515
|
-
pl:
|
|
517
|
+
pl: convertProductListToV2DTO(impression.ProductList),
|
|
516
518
|
};
|
|
517
519
|
});
|
|
518
520
|
}
|
|
@@ -520,6 +522,6 @@ export default function ServerModel(
|
|
|
520
522
|
dto.pet = event.ProfileMessageType;
|
|
521
523
|
}
|
|
522
524
|
|
|
523
|
-
return dto as
|
|
525
|
+
return dto as IServerV2DTO;
|
|
524
526
|
};
|
|
525
527
|
}
|
package/src/store.ts
CHANGED
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
SDKProduct,
|
|
24
24
|
} from './sdkRuntimeModels';
|
|
25
25
|
import { isNumber, isDataPlanSlug, Dictionary } from './utils';
|
|
26
|
-
import { SDKConsentState } from './consent
|
|
26
|
+
import { SDKConsentState } from './consent';
|
|
27
27
|
|
|
28
28
|
// This represents the runtime configuration of the SDK AFTER
|
|
29
29
|
// initialization has been complete and all settings and
|
|
@@ -219,9 +219,10 @@ export default function Store(
|
|
|
219
219
|
this.deviceId = config.deviceId;
|
|
220
220
|
}
|
|
221
221
|
if (config.hasOwnProperty('isDevelopmentMode')) {
|
|
222
|
-
this.SDKConfig.isDevelopmentMode =
|
|
223
|
-
|
|
224
|
-
|
|
222
|
+
this.SDKConfig.isDevelopmentMode =
|
|
223
|
+
mpInstance._Helpers.returnConvertedBoolean(
|
|
224
|
+
config.isDevelopmentMode
|
|
225
|
+
);
|
|
225
226
|
} else {
|
|
226
227
|
this.SDKConfig.isDevelopmentMode = false;
|
|
227
228
|
}
|
package/src/vault.ts
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { Logger } from '@mparticle/web-sdk';
|
|
2
|
+
import { Dictionary, isEmpty } from './utils';
|
|
3
|
+
|
|
4
|
+
interface IVaultOptions {
|
|
5
|
+
logger?: Logger;
|
|
6
|
+
offlineStorageEnabled?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export default class Vault<StorableItem extends Dictionary> {
|
|
10
|
+
public contents: Dictionary<StorableItem>;
|
|
11
|
+
private readonly _storageKey: string;
|
|
12
|
+
private readonly _itemKey: keyof StorableItem;
|
|
13
|
+
private logger?: Logger;
|
|
14
|
+
private offlineStorageEnabled: boolean = false;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
*
|
|
18
|
+
* @param {string} storageKey the local storage key string
|
|
19
|
+
* @param {string} itemKey an element within your StorableItem to use as a key
|
|
20
|
+
* @param {IVaultOptions} options A Dictionary of IVaultOptions
|
|
21
|
+
*/
|
|
22
|
+
constructor(
|
|
23
|
+
storageKey: string,
|
|
24
|
+
itemKey: keyof StorableItem,
|
|
25
|
+
options?: IVaultOptions
|
|
26
|
+
) {
|
|
27
|
+
this._storageKey = storageKey;
|
|
28
|
+
this._itemKey = itemKey;
|
|
29
|
+
this.contents = this.getItems() || {};
|
|
30
|
+
|
|
31
|
+
this.offlineStorageEnabled = options?.offlineStorageEnabled;
|
|
32
|
+
|
|
33
|
+
// Add a fake logger in case one is not provided or needed
|
|
34
|
+
this.logger = options?.logger || {
|
|
35
|
+
verbose: () => {},
|
|
36
|
+
warning: () => {},
|
|
37
|
+
error: () => {},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Stores a single Item using `itemId` as an index
|
|
43
|
+
* @method storeItem
|
|
44
|
+
* @param item {StorableItem} a Dictonary with key to store
|
|
45
|
+
*/
|
|
46
|
+
public storeItem(item: StorableItem): void {
|
|
47
|
+
this.contents = this.getItems();
|
|
48
|
+
|
|
49
|
+
if (item[this._itemKey]) {
|
|
50
|
+
this.contents[item[this._itemKey]] = item;
|
|
51
|
+
this.logger.verbose(
|
|
52
|
+
`Saved items to vault with key: ${item[this._itemKey]}`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
this.saveItems(this.contents);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Stores Items using `itemId` as an index
|
|
61
|
+
* @method storeItems
|
|
62
|
+
* @param {StorableItem[]} an Array of StorableItems
|
|
63
|
+
*/
|
|
64
|
+
public storeItems(items: StorableItem[]): void {
|
|
65
|
+
items.forEach((item) => this.storeItem(item));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Removes a single StorableItem based on `indexId`
|
|
70
|
+
* @method removeItem
|
|
71
|
+
* @param {String} indexId
|
|
72
|
+
*/
|
|
73
|
+
public removeItem(indexId: string): void {
|
|
74
|
+
this.logger.verbose(`Removing from vault: ${indexId}`);
|
|
75
|
+
this.contents = this.getItems() || {};
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
delete this.contents[indexId];
|
|
79
|
+
|
|
80
|
+
this.saveItems(this.contents);
|
|
81
|
+
} catch (error) {
|
|
82
|
+
this.logger.error(
|
|
83
|
+
`Unable to remove item without a matching ID ${indexId}`
|
|
84
|
+
);
|
|
85
|
+
this.logger.error(error as string);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Retrieves all StorableItems from local storage as an array
|
|
91
|
+
* @method retrieveItems
|
|
92
|
+
* @returns {StorableItem[]} an array of Items
|
|
93
|
+
*/
|
|
94
|
+
public retrieveItems(): StorableItem[] {
|
|
95
|
+
this.contents = this.getItems();
|
|
96
|
+
|
|
97
|
+
return Object.keys(this.contents).map((item) => this.contents[item]);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Removes all persisted data from local storage based on this vault's `key`
|
|
102
|
+
* @method purge
|
|
103
|
+
*/
|
|
104
|
+
public purge(): void {
|
|
105
|
+
this.contents = {};
|
|
106
|
+
this.removeItems();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private saveItems(items: Dictionary<StorableItem>): void {
|
|
110
|
+
if (!this.offlineStorageEnabled) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
window.localStorage.setItem(
|
|
115
|
+
this._storageKey,
|
|
116
|
+
!isEmpty(items) ? JSON.stringify(items) : ''
|
|
117
|
+
);
|
|
118
|
+
} catch (error) {
|
|
119
|
+
this.logger.error(`Cannot Save items to Local Storage: ${items}`);
|
|
120
|
+
this.logger.error(error as string);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private getItems(): Dictionary<StorableItem> {
|
|
125
|
+
if (!this.offlineStorageEnabled) {
|
|
126
|
+
return this.contents;
|
|
127
|
+
}
|
|
128
|
+
// TODO: Handle cases where Local Storage is unavailable
|
|
129
|
+
// https://go.mparticle.com/work/SQDSDKS-5022
|
|
130
|
+
const itemString = window.localStorage.getItem(this._storageKey);
|
|
131
|
+
|
|
132
|
+
return itemString ? JSON.parse(itemString) : {};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
private removeItems(): void {
|
|
136
|
+
if (!this.offlineStorageEnabled) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
window.localStorage.removeItem(this._storageKey);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
// TODO: Migrate this to Consent.ts when that is created
|
|
2
|
-
import { ConsentState, PrivacyConsentState } from '@mparticle/web-sdk';
|
|
3
|
-
|
|
4
|
-
export interface IGDPRConsentObject {
|
|
5
|
-
purpose: string;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export interface ICCPAConsentObject {
|
|
9
|
-
purpose: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface IConsentJSONObject {
|
|
13
|
-
gdpr?: Partial<IGDPRConsentObject>;
|
|
14
|
-
ccpa?: Partial<ICCPAConsentObject>;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
interface ICreatePrivacyConsentFunction {
|
|
18
|
-
(
|
|
19
|
-
consented: boolean,
|
|
20
|
-
timestamp?: number,
|
|
21
|
-
consentDocument?: string,
|
|
22
|
-
location?: string,
|
|
23
|
-
hardwareId?: string
|
|
24
|
-
): PrivacyConsentState | null;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// TODO: Refactor this with Consent Namespace in @types/mparticle-web-sdk
|
|
28
|
-
// https://go.mparticle.com/work/SQDSDKS-5009
|
|
29
|
-
export interface SDKConsentApi {
|
|
30
|
-
createGDPRConsent: ICreatePrivacyConsentFunction;
|
|
31
|
-
createCCPAConsent: ICreatePrivacyConsentFunction;
|
|
32
|
-
createConsentState: (consentState?: ConsentState) => ConsentState;
|
|
33
|
-
ConsentSerialization: IConsentSerialization;
|
|
34
|
-
createPrivacyConsent: ICreatePrivacyConsentFunction;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export interface IConsentSerialization {
|
|
38
|
-
toMinifiedJsonObject: (state: ConsentState) => IConsentJSONObject;
|
|
39
|
-
fromMinifiedJsonObject: (json: IConsentJSONObject) => ConsentState;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// TODO: Resolve discrepency between ConsentState and SDKConsentState
|
|
43
|
-
// https://go.mparticle.com/work/SQDSDKS-5009
|
|
44
|
-
export interface SDKConsentState
|
|
45
|
-
extends Omit<ConsentState, 'getGDPRConsentState' | 'getCCPAConsentState'> {
|
|
46
|
-
getGDPRConsentState(): SDKGDPRConsentState;
|
|
47
|
-
getCCPAConsentState(): SDKCCPAConsentState;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export interface SDKGDPRConsentState {
|
|
51
|
-
[key: string]: SDKConsentStateData;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// TODO: Resolve discrepency between ConsentState and SDKConsentState
|
|
55
|
-
// https://go.mparticle.com/work/SQDSDKS-5009
|
|
56
|
-
// Specifically PrivacyConsentState, GDPRConsentState and CCPAConsentState
|
|
57
|
-
// Treat all attributes as required, but we had to override this
|
|
58
|
-
// to be optional for a bugfix:
|
|
59
|
-
// https://github.com/mParticle/mparticle-web-sdk/commit/3b11ead79f25b417737442a4fabd6435750f46b8
|
|
60
|
-
export interface SDKConsentStateData {
|
|
61
|
-
Consented: boolean;
|
|
62
|
-
Timestamp?: number;
|
|
63
|
-
ConsentDocument?: string;
|
|
64
|
-
Location?: string;
|
|
65
|
-
HardwareId?: string;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export interface SDKCCPAConsentState extends SDKConsentStateData {}
|
|
69
|
-
|
|
70
|
-
export interface IPrivacyV2DTO {
|
|
71
|
-
c: boolean; // Consented
|
|
72
|
-
ts: number; // Timestamp
|
|
73
|
-
d: string; // Document
|
|
74
|
-
l: string; // Location
|
|
75
|
-
h: string; // HardwareID
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export interface IGDPRConsentStateDTO {
|
|
79
|
-
[key: string]: IPrivacyV2DTO;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export interface ICCPAConsentStateDTO {
|
|
83
|
-
data_sale_opt_out: IPrivacyV2DTO;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export interface IConsentStateDTO {
|
|
87
|
-
gdpr?: IGDPRConsentStateDTO;
|
|
88
|
-
ccpa?: ICCPAConsentStateDTO;
|
|
89
|
-
}
|