@mparticle/web-sdk 3.22.0 → 3.24.0

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.
Files changed (37) hide show
  1. package/dist/mparticle.common.js +1 -1669
  2. package/dist/mparticle.esm.js +1 -1669
  3. package/dist/mparticle.js +4827 -4184
  4. package/dist/types/src/buttonTracking/buttonClickEvent.d.ts +4 -0
  5. package/dist/types/src/buttonTracking/buttonDescription.d.ts +2 -2
  6. package/dist/types/src/buttonTracking/buttonTracker.d.ts +2 -0
  7. package/dist/types/src/buttonTracking/checkoutIntent.d.ts +2 -2
  8. package/dist/types/src/buttonTracking/controls.d.ts +6 -3
  9. package/dist/types/src/buttonTracking/labelMasking.d.ts +1 -0
  10. package/dist/types/src/configAPIClient.d.ts +1 -0
  11. package/dist/types/src/forwarder-utils.d.ts +3 -0
  12. package/dist/types/src/pageUrl.d.ts +10 -0
  13. package/dist/types/src/pageViewTracker.d.ts +21 -3
  14. package/dist/types/src/roktManager.d.ts +8 -2
  15. package/dist/types/src/sdkRuntimeModels.d.ts +3 -0
  16. package/dist/types/src/store.d.ts +2 -0
  17. package/package.json +21 -14
  18. package/src/batchUploader.ts +3 -2
  19. package/src/buttonTracking/buttonClickEvent.ts +76 -1
  20. package/src/buttonTracking/buttonDescription.ts +236 -46
  21. package/src/buttonTracking/buttonTracker.ts +122 -7
  22. package/src/buttonTracking/checkoutIntent.ts +51 -9
  23. package/src/buttonTracking/controls.ts +160 -50
  24. package/src/buttonTracking/labelMasking.ts +4 -1
  25. package/src/configAPIClient.ts +1 -0
  26. package/src/events.ts +9 -3
  27. package/src/forwarder-utils.ts +38 -0
  28. package/src/forwarders.ts +2 -28
  29. package/src/mp-instance.ts +23 -10
  30. package/src/mparticle-instance-manager.ts +3 -0
  31. package/src/pageUrl.ts +191 -0
  32. package/src/pageViewTracker.ts +206 -78
  33. package/src/roktManager.ts +53 -20
  34. package/src/sdkRuntimeModels.ts +3 -0
  35. package/src/serverModel.ts +3 -3
  36. package/src/store.ts +14 -0
  37. package/src/utils.ts +1 -1
@@ -1,5 +1,9 @@
1
+ import { IKitFilterSettings } from '../configAPIClient';
2
+ import type KitBlocker from '../kitBlocking';
1
3
  import { BaseEvent } from '../sdkRuntimeModels';
2
4
  import { IButtonClick } from './buttonDescription';
3
5
  export declare const AUTO_BUTTON_ATTRIBUTE = "is_auto_button_click";
4
6
  export declare const BUTTON_CLICK_EVENT_NAME = "Auto Button Click";
5
7
  export declare const buildButtonClickEvent: (click: IButtonClick, pathname: string) => BaseEvent;
8
+ export type ButtonClickBlocker = 'data plan' | 'forwarding rule' | 'event name filter' | 'event type filter';
9
+ export declare const getButtonClickBlocker: (forwarder: IKitFilterSettings, kitBlocker?: KitBlocker) => ButtonClickBlocker | undefined;
@@ -1,6 +1,6 @@
1
1
  export type ButtonElementKind = 'button' | 'input' | 'role' | 'wallet' | 'link';
2
2
  export type LinkType = 'same_page' | 'outbound' | 'download';
3
- export type ButtonLabelSource = 'labelledby' | 'aria' | 'text' | 'label' | 'alt' | 'title' | 'value' | 'none';
3
+ export type ButtonLabelSource = 'labelledby' | 'aria' | 'text' | 'alt' | 'title' | 'value' | 'none';
4
4
  export interface IButtonClick {
5
5
  label?: string;
6
6
  labelSource: ButtonLabelSource;
@@ -18,4 +18,4 @@ export interface IButtonClick {
18
18
  fileExtension?: string;
19
19
  checked?: boolean;
20
20
  }
21
- export declare function describeButtonClick(control: Element): IButtonClick | undefined;
21
+ export declare function describeButtonClick(control: Element, path?: Array<EventTarget | null>): IButtonClick | undefined;
@@ -11,6 +11,7 @@ export declare class ButtonTracker {
11
11
  private hasRoktKit;
12
12
  private generation;
13
13
  private lastCommitClick;
14
+ private lastClick;
14
15
  private lastSent;
15
16
  private pagePath;
16
17
  private pageEvents;
@@ -21,6 +22,7 @@ export declare class ButtonTracker {
21
22
  constructor(mpInstance: IMParticleWebSDKInstance);
22
23
  get isActive(): boolean;
23
24
  init(options: IButtonTrackerOptions): void;
25
+ onApplePayBegin(): void;
24
26
  teardown(): void;
25
27
  clearPending(): void;
26
28
  private reset;
@@ -1,5 +1,5 @@
1
- export type CheckoutIntentKind = 'commit' | 'wallet' | 'checkout_step' | 'frame';
2
- export type CheckoutIntentSource = 'vendor' | 'label' | 'brand' | 'frame' | 'submit';
1
+ export type CheckoutIntentKind = 'commit' | 'wallet' | 'checkout_step' | 'frame' | 'cart';
2
+ export type CheckoutIntentSource = 'vendor' | 'label' | 'brand' | 'frame' | 'submit' | 'name' | 'api';
3
3
  export interface ICheckoutIntent {
4
4
  kind: Exclude<CheckoutIntentKind, 'frame'>;
5
5
  source: CheckoutIntentSource;
@@ -1,9 +1,12 @@
1
1
  export declare const CONTROL_SELECTOR = "button, input[type=\"submit\"], input[type=\"button\"], input[type=\"image\"], [role=\"button\"]";
2
+ export declare function someComposedAncestor(element: Element, test: (node: Element) => boolean, until?: Element): boolean;
2
3
  export declare function hasComposedAncestor(element: Element, selector: string): boolean;
3
4
  export declare function isRoktElement(element: Element): boolean;
4
5
  export declare function vendorButtonKind(control: Element): 'wallet' | 'checkout_step' | 'none' | undefined;
6
+ export declare function isWalletNamed(element: Element): boolean;
5
7
  export declare function isWalletElement(element: Element): boolean;
6
- export declare function isQuietIntentControl(control: Element, isVendorWallet: boolean): boolean;
7
- export declare function findControl(path: Array<EventTarget | null>): Element | undefined;
8
+ export declare function isQuietIntentControl(control: Element, isVendorWallet: boolean, isCart?: boolean): boolean;
9
+ export declare function isWalletNamedControl(element: Element): boolean;
10
+ export declare function isExcludedPath(path: Array<EventTarget | null>): boolean;
11
+ export declare function findControl(path: Array<EventTarget | null>, included?: boolean): Element | undefined;
8
12
  export declare function isUnsafeTextSource(element: Element): boolean;
9
- export declare function isUnsafeLabelSource(label: Element): boolean;
@@ -1 +1,2 @@
1
+ export declare const MAX_RAW_LABEL_LENGTH = 128;
1
2
  export declare function maskLabel(raw: string | null | undefined): string | undefined;
@@ -59,6 +59,7 @@ export interface IConfigResponse {
59
59
  workspaceToken: string;
60
60
  pixelConfigs: IPixelConfiguration[];
61
61
  flags: SDKEventCustomFlags;
62
+ autoLogPageViewQueryParams?: string;
62
63
  }
63
64
  export interface IConfigAPIClient {
64
65
  apiKey: string;
@@ -1,8 +1,11 @@
1
1
  import * as EventsApi from '@mparticle/event-models';
2
2
  import { IKitFilterSettings } from './configAPIClient';
3
+ import type { SDKEvent } from './sdkRuntimeModels';
4
+ import type KitBlocker from './kitBlocking';
3
5
  type ForwarderFilterConfig = Pick<IKitFilterSettings, 'eventNameFilters' | 'eventTypeFilters' | 'screenNameFilters' | 'screenAttributeFilters' | 'attributeFilters' | 'userIdentityFilters' | 'filteringEventAttributeValue'>;
4
6
  export declare function isBlockedByForwardingRule(messageType: number, attributes: Record<string, unknown> | null, forwarder: ForwarderFilterConfig): boolean;
5
7
  export declare function isBlockedByEventFilter(messageType: number, hashedEventName: number, hashedEventType: number, forwarder: ForwarderFilterConfig): boolean;
8
+ export declare function isEventForwarded(event: SDKEvent, forwarder: ForwarderFilterConfig, kitBlocker?: KitBlocker): boolean;
6
9
  export declare function filterEventAttributes(messageType: number, eventCategory: number, eventName: string, attributes: Record<string, unknown> | null, forwarder: ForwarderFilterConfig): Record<string, unknown> | null;
7
10
  export declare function filterUserIdentities(userIdentities: Array<{
8
11
  Type: number;
@@ -0,0 +1,10 @@
1
+ import { valueof } from './utils';
2
+ export declare const UrlMode: {
3
+ readonly Path: "path";
4
+ readonly Full: "full";
5
+ };
6
+ export type UrlMode = valueof<typeof UrlMode>;
7
+ export declare const EXCLUDED_URL_QUERY_PARAMS: string[];
8
+ export declare const EXCLUDED_URL_FRAGMENT_PARAMS: string[];
9
+ export declare const cleanUrl: (href: string, mode: UrlMode) => string;
10
+ export declare const cleanPageHref: () => string;
@@ -3,9 +3,23 @@ import { BaseEvent } from './sdkRuntimeModels';
3
3
  import { Dictionary } from './utils';
4
4
  export declare const WIN_APV_KEY = "__mpApv__";
5
5
  export declare const ALLOWED_QUERY_PARAMS: string[];
6
+ export declare const AUTO_PAGE_VIEW_ATTRIBUTE = "is_auto_page_view";
7
+ export declare const MAX_CUSTOM_QUERY_PARAMS = 25;
8
+ export interface IQueryParamAllowlist {
9
+ allowed: string[];
10
+ rejectedPositions: number[];
11
+ overLimit: number;
12
+ }
13
+ export declare const MAX_CUSTOM_QUERY_PARAM_VALUE_LENGTH = 512;
14
+ export interface ICapturedParam {
15
+ name: string;
16
+ value: string;
17
+ }
18
+ export declare const ALLOWED_QUERY_PARAM_PREFIXES: string[];
19
+ export declare const isAllowedQueryParam: (name: string) => boolean;
6
20
  interface IPageSnapshot {
7
21
  path: string;
8
- params: Dictionary<string>;
22
+ params: ICapturedParam[];
9
23
  }
10
24
  interface IPageViewData extends IPageSnapshot {
11
25
  hostname: string;
@@ -15,8 +29,10 @@ interface IPageViewData extends IPageSnapshot {
15
29
  export interface IPageViewOptions {
16
30
  isAutoPageView?: boolean;
17
31
  }
18
- export declare const allowedQueryParams: (href: string) => Dictionary<string>;
19
- export declare const AUTO_PAGE_VIEW_ATTRIBUTE = "is_auto_page_view";
32
+ export declare const parseQueryParamAllowlist: (configured: unknown) => IQueryParamAllowlist;
33
+ export declare const effectiveAllowlist: (extras?: string[]) => string[];
34
+ export declare const allowedQueryParams: (href: string, extras?: string[]) => ICapturedParam[];
35
+ export declare const paramsToAttributes: (params: ICapturedParam[]) => Dictionary<string>;
20
36
  export declare const autoPageViewAttribute: (isAutoPageView?: boolean) => Dictionary<boolean>;
21
37
  export declare const pageKey: (page: IPageSnapshot) => string;
22
38
  export declare const isNewPage: (lastKey: string | null, candidateKey: string) => boolean;
@@ -29,6 +45,7 @@ export declare class PageViewTracker {
29
45
  private readonly mpInstance;
30
46
  private lastPage;
31
47
  private active;
48
+ private customQueryParams;
32
49
  private pendingNavigations;
33
50
  private undoHistoryPatch;
34
51
  private readonly isAutoPageView;
@@ -36,6 +53,7 @@ export declare class PageViewTracker {
36
53
  get isActive(): boolean;
37
54
  init(): void;
38
55
  teardown(): void;
56
+ private readCustomQueryParams;
39
57
  private retire;
40
58
  private takePendingNavigations;
41
59
  private safeHandleNavigation;
@@ -5,6 +5,7 @@ import { Dictionary, AttributeValue } from "./utils";
5
5
  import { SDKIdentityApi } from "./identity.interfaces";
6
6
  import { SDKLoggerApi } from "./sdkRuntimeModels";
7
7
  import { IStore, LocalSessionAttributes } from "./store";
8
+ import { MPID } from "@mparticle/web-sdk";
8
9
  import { IErrorReportingService, ILoggingService } from "./reporting/types";
9
10
  import { IRoktLauncherOptions } from "./roktLauncherOptions";
10
11
  import IntegrationCapture from "./integrationCapture";
@@ -82,6 +83,7 @@ export default class RoktManager {
82
83
  kit: IRoktKit;
83
84
  filters: RoktKitFilterSettings;
84
85
  private currentUser;
86
+ private createFilteredUser?;
85
87
  private messageQueue;
86
88
  private sandbox;
87
89
  private placementAttributesMapping;
@@ -100,6 +102,7 @@ export default class RoktManager {
100
102
  private isShoppableAdsLoaded;
101
103
  private stopRouteChangeWatch;
102
104
  private pendingCheckoutIntents;
105
+ private autoButtonClicksForwarded;
103
106
  constructor(instanceName?: string);
104
107
  /**
105
108
  * Sets a callback to be invoked when RoktManager becomes ready
@@ -116,20 +119,22 @@ export default class RoktManager {
116
119
  * @param {Function} captureTiming - Function to capture performance timing marks
117
120
  * @param {IErrorReportingService} errorReporter - Dispatcher for error/warning reporting
118
121
  * @param {ILoggingService} loggingService - Dispatcher for informational logging
122
+ * @param {Function} createFilteredUser - Builds a user as the Rokt connection's filters and the data plan allow
119
123
  *
120
124
  * @throws Logs error to console if placementAttributesMapping parsing fails
121
125
  */
122
- init(roktConfig: IKitConfigs, filteredUser: IMParticleUser, identityService: SDKIdentityApi, store: IStore, logger?: SDKLoggerApi, options?: IRoktOptions, captureTiming?: (metricsName: string) => void, errorReporter?: IErrorReportingService, loggingService?: ILoggingService, integrationCapture?: IntegrationCapture): void;
126
+ init(roktConfig: IKitConfigs, filteredUser: IMParticleUser, identityService: SDKIdentityApi, store: IStore, logger?: SDKLoggerApi, options?: IRoktOptions, captureTiming?: (metricsName: string) => void, errorReporter?: IErrorReportingService, loggingService?: ILoggingService, integrationCapture?: IntegrationCapture, createFilteredUser?: (mpid: MPID) => IMParticleUser): void;
123
127
  get isInitialized(): boolean;
124
128
  attachKit(kit: IRoktKit): void;
125
129
  private watchRouteChanges;
126
130
  private notifyRouteChange;
131
+ setAutoButtonClicksForwarded(forwarded: boolean): void;
127
132
  isCheckoutIntentSuppressed(): boolean;
128
133
  isCheckoutIntentLive(): boolean;
129
134
  notifyCheckoutIntent(signal: ICheckoutIntentSignal, pathname?: string): void;
130
135
  discardCheckoutIntents(): void;
131
136
  private flushCheckoutIntents;
132
- private isAutoLogPageViewEnabled;
137
+ isAutoLogPageViewEnabled(): boolean;
133
138
  /**
134
139
  * Renders ads based on the options provided
135
140
  *
@@ -146,6 +151,7 @@ export default class RoktManager {
146
151
  * });
147
152
  */
148
153
  selectPlacements(options: IRoktSelectPlacementsOptions): Promise<IRoktSelection>;
154
+ private logFilteredIdentity;
149
155
  /**
150
156
  * Hashes attributes and returns both original and hashed versions
151
157
  * with Rokt-compatible key names (like emailsha256, mobilesha256)
@@ -19,6 +19,7 @@ import { IErrorLogMessage, IMParticleWebSDKInstance, IntegrationDelays } from '.
19
19
  import Constants from './constants';
20
20
  import RoktManager, { IRoktLauncherOptions } from './roktManager';
21
21
  import { IConsoleLogger } from './logger';
22
+ import { UrlMode } from './pageUrl';
22
23
  import { ErrorCodes, IErrorReportingService, ILoggingService } from './reporting/types';
23
24
  export type SDKEventCustomFlags = Dictionary<any>;
24
25
  export interface SDKEvent {
@@ -194,6 +195,7 @@ export interface IMParticleInstanceManager extends MParticleWebSDK {
194
195
  _instances: Dictionary<IMParticleWebSDKInstance>;
195
196
  _isTestEnv?: boolean;
196
197
  _forceNoLocalStorage?: boolean;
198
+ _cleanUrl(href: string, mode: UrlMode): string;
197
199
  config: SDKInitConfig;
198
200
  isIOS?: boolean;
199
201
  MPSideloadedKit: typeof MPSideloadedKit;
@@ -221,6 +223,7 @@ export interface SDKInitConfig extends Omit<MPConfiguration, 'dataPlan' | 'logLe
221
223
  dataPlanOptions?: KitBlockerOptions;
222
224
  flags?: Dictionary;
223
225
  pixelConfigs?: IPixelConfiguration[];
226
+ autoLogPageViewQueryParams?: string;
224
227
  aliasMaxWindow?: number;
225
228
  deviceId?: string;
226
229
  forceHttps?: boolean;
@@ -1,6 +1,7 @@
1
1
  import { Batch } from '@mparticle/event-models';
2
2
  import { MPID, IdentifyRequest, SDKEventCustomFlags, ConsentState, UserIdentities } from '@mparticle/web-sdk';
3
3
  import { IKitConfigs } from './configAPIClient';
4
+ import { IQueryParamAllowlist } from './pageViewTracker';
4
5
  import { DataPlanResult, KitBlockerOptions, LogLevelType, SDKDataPlan, SDKEvent, SDKGeoLocation, SDKInitConfig, SDKProduct } from './sdkRuntimeModels';
5
6
  import { Dictionary, AttributeValue } from './utils';
6
7
  import { SDKConsentState } from './consent';
@@ -25,6 +26,7 @@ export interface SDKConfig {
25
26
  appVersion?: string;
26
27
  package?: string;
27
28
  flags?: IFeatureFlags;
29
+ autoLogPageViewQueryParams?: IQueryParamAllowlist;
28
30
  kitConfigs: IKitConfigs[];
29
31
  kits: Dictionary<UnregisteredKit>;
30
32
  logLevel?: LogLevelType;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mparticle/web-sdk",
3
- "version": "3.22.0",
3
+ "version": "3.24.0",
4
4
  "description": "mParticle core SDK for web applications",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
@@ -101,20 +101,18 @@
101
101
  "lint"
102
102
  ],
103
103
  "devDependencies": {
104
- "@babel/core": "^7.18.6",
105
- "@babel/eslint-parser": "^7.18.2",
106
- "@babel/eslint-plugin": "^7.17.7",
107
- "@babel/plugin-proposal-class-properties": "^7.5.5",
108
- "@babel/plugin-proposal-object-rest-spread": "^7.5.5",
109
- "@babel/plugin-transform-runtime": "^7.6.0",
110
- "@babel/preset-env": "^7.6.0",
111
- "@babel/preset-typescript": "^7.6.0",
104
+ "@babel/core": "^8.0.7",
105
+ "@babel/plugin-transform-runtime": "^8.0.6",
106
+ "@babel/preset-env": "^8.0.7",
107
+ "@babel/preset-typescript": "^8.0.7",
108
+ "@babel/runtime": "^8.0.7",
112
109
  "@mparticle/data-planning-models": "^0.1.0",
113
110
  "@mparticle/event-models": "^1.3.1",
114
- "@rollup/plugin-babel": "6.0.3",
111
+ "@rollup/plugin-babel": "^7.1.0",
115
112
  "@rollup/plugin-commonjs": "25.0.4",
116
113
  "@rollup/plugin-json": "^5.0.2",
117
114
  "@rollup/plugin-node-resolve": "15.2.1",
115
+ "@rollup/plugin-terser": "^1.0.1",
118
116
  "@rollup/plugin-typescript": "^11.1.0",
119
117
  "@semantic-release/changelog": "^6.0.3",
120
118
  "@semantic-release/exec": "^6.0.3",
@@ -126,7 +124,7 @@
126
124
  "@types/mocha": "^9.0.0",
127
125
  "@types/mparticle__web-sdk": "^2.66.0",
128
126
  "@types/node": "^20.1.0",
129
- "babel-preset-minify": "^0.5.1",
127
+ "babel-plugin-polyfill-corejs3": "^1.0.0",
130
128
  "browser-sync": "^2.26.3",
131
129
  "browserify": "^17.0.0",
132
130
  "chai": "^4.2.0",
@@ -159,7 +157,7 @@
159
157
  "shelljs": "^0.8.4",
160
158
  "should": "^7.1.0",
161
159
  "sinon": "^16.1.3",
162
- "ts-jest": "^29.1.0",
160
+ "ts-jest": "^29.4.15",
163
161
  "tslib": "^2.1.0",
164
162
  "typescript": "^5.0.2",
165
163
  "uglify-js": "^3.4.9",
@@ -169,7 +167,16 @@
169
167
  "peerDependencies": {
170
168
  "@mparticle/event-models": "^1.3.1"
171
169
  },
172
- "dependencies": {
173
- "@babel/runtime": "^7.23.2"
170
+ "overrides": {
171
+ "@rollup/plugin-babel": {
172
+ "@babel/core": "$@babel/core"
173
+ }
174
+ },
175
+ "devEngines": {
176
+ "runtime": {
177
+ "name": "node",
178
+ "version": "^22.18.0 || >=24.11.0",
179
+ "onFail": "warn"
180
+ }
174
181
  }
175
182
  }
@@ -3,7 +3,8 @@ import Constants from './constants';
3
3
  import { SDKEvent, SDKEventCustomFlags } from './sdkRuntimeModels';
4
4
  import { convertEvents } from './sdkToEventsApiConverter';
5
5
  import { MessageType, EventType } from './types';
6
- import { getRampNumber, getHref, isEmpty, obfuscateDevData } from './utils';
6
+ import { getRampNumber, isEmpty, obfuscateDevData } from './utils';
7
+ import { cleanPageHref } from './pageUrl';
7
8
  import { SessionStorageVault, LocalStorageVault, StorageResult } from './vault';
8
9
  import {
9
10
  AsyncUploader,
@@ -204,7 +205,7 @@ export class BatchUploader {
204
205
  Debug: SDKConfig.isDevelopmentMode,
205
206
  ActiveTimeOnSite: _timeOnSiteTimer?.getTimeInForeground() || 0,
206
207
  TotalTimeOnSite: _Store.getTotalTimeOnSite?.() || 0,
207
- PageUrl: getHref() || null,
208
+ PageUrl: cleanPageHref() || null,
208
209
  IsBackgroundAST: true
209
210
  } as SDKEvent;
210
211
 
@@ -1,4 +1,8 @@
1
- import { BaseEvent } from '../sdkRuntimeModels';
1
+ import { IKitFilterSettings } from '../configAPIClient';
2
+ import { isEventForwarded } from '../forwarder-utils';
3
+ import type KitBlocker from '../kitBlocking';
4
+ import KitFilterHelper from '../kitFilterHelper';
5
+ import { BaseEvent, SDKEvent } from '../sdkRuntimeModels';
2
6
  import { EventType, MessageType } from '../types';
3
7
  import { IButtonClick } from './buttonDescription';
4
8
 
@@ -52,3 +56,74 @@ export const buildButtonClickEvent = (
52
56
  eventType: EventType.Other,
53
57
  };
54
58
  };
59
+
60
+ // Every attribute buildButtonClickEvent can set apart from the marker and the
61
+ // hostname, which is the same on every click on this page. A spec checks the
62
+ // two stay in step.
63
+ const CLICK_ATTRIBUTES = [
64
+ 'label_source',
65
+ 'element',
66
+ 'type',
67
+ 'path',
68
+ 'label',
69
+ 'aria_label',
70
+ 'icon',
71
+ 'element_id',
72
+ 'element_name',
73
+ 'test_id',
74
+ 'controls',
75
+ 'form',
76
+ 'link_type',
77
+ 'link_domain',
78
+ 'file_extension',
79
+ 'checked',
80
+ ];
81
+
82
+ export type ButtonClickBlocker =
83
+ | 'data plan'
84
+ | 'forwarding rule'
85
+ | 'event name filter'
86
+ | 'event type filter';
87
+
88
+ // Which check keeps some or all auto button clicks from a kit, or undefined
89
+ // when the kit receives every one. A forwarding rule on an attribute whose
90
+ // value differs between clicks lets some through and not others. Each other
91
+ // check goes through isEventForwarded on its own, so together they decide as
92
+ // it does for each click.
93
+ export const getButtonClickBlocker = (
94
+ forwarder: IKitFilterSettings,
95
+ kitBlocker?: KitBlocker
96
+ ): ButtonClickBlocker | undefined => {
97
+ const rule = forwarder.filteringEventAttributeValue;
98
+ if (
99
+ rule &&
100
+ rule.eventAttributeValue &&
101
+ CLICK_ATTRIBUTES.some(
102
+ name =>
103
+ KitFilterHelper.hashAttributeConditionalForwarding(name) ===
104
+ rule.eventAttributeName
105
+ )
106
+ ) {
107
+ return 'forwarding rule';
108
+ }
109
+ const click = ({
110
+ EventName: BUTTON_CLICK_EVENT_NAME,
111
+ EventCategory: EventType.Other,
112
+ EventDataType: MessageType.PageEvent,
113
+ EventAttributes: {
114
+ [AUTO_BUTTON_ATTRIBUTE]: true,
115
+ hostname: window.location.hostname,
116
+ },
117
+ } as unknown) as SDKEvent;
118
+ const checks: Array<[ButtonClickBlocker, Partial<IKitFilterSettings>]> = [
119
+ ['data plan', {}],
120
+ ['forwarding rule', { filteringEventAttributeValue: rule }],
121
+ ['event name filter', { eventNameFilters: forwarder.eventNameFilters }],
122
+ ['event type filter', { eventTypeFilters: forwarder.eventTypeFilters }],
123
+ ];
124
+ const failed = checks.find(
125
+ ([, filters]) =>
126
+ !isEventForwarded(click, filters as IKitFilterSettings, kitBlocker)
127
+ );
128
+ return failed ? failed[0] : undefined;
129
+ };