@amplitude/plugin-autocapture-browser 1.28.0-element-path-v1.0 → 1.28.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.
- package/lib/cjs/data-extractor.d.ts.map +1 -1
- package/lib/cjs/data-extractor.js +2 -27
- package/lib/cjs/data-extractor.js.map +1 -1
- package/lib/cjs/element-selector-config.d.ts +4 -5
- package/lib/cjs/element-selector-config.d.ts.map +1 -1
- package/lib/cjs/element-selector-config.js +5 -14
- package/lib/cjs/element-selector-config.js.map +1 -1
- package/lib/cjs/version.d.ts +1 -1
- package/lib/cjs/version.d.ts.map +1 -1
- package/lib/cjs/version.js +1 -1
- package/lib/cjs/version.js.map +1 -1
- package/lib/esm/data-extractor.d.ts.map +1 -1
- package/lib/esm/data-extractor.js +2 -27
- package/lib/esm/data-extractor.js.map +1 -1
- package/lib/esm/element-selector-config.d.ts +4 -5
- package/lib/esm/element-selector-config.d.ts.map +1 -1
- package/lib/esm/element-selector-config.js +5 -14
- package/lib/esm/element-selector-config.js.map +1 -1
- package/lib/esm/version.d.ts +1 -1
- package/lib/esm/version.d.ts.map +1 -1
- package/lib/esm/version.js +1 -1
- package/lib/esm/version.js.map +1 -1
- package/lib/scripts/amplitude-min.js +1 -1
- package/lib/scripts/amplitude-min.js.gz +0 -0
- package/lib/scripts/amplitude-min.js.map +1 -1
- package/lib/scripts/amplitude-min.umd.js +1 -1
- package/lib/scripts/amplitude-min.umd.js.gz +0 -0
- package/lib/scripts/data-extractor.d.ts.map +1 -1
- package/lib/scripts/element-selector-config.d.ts +4 -5
- package/lib/scripts/element-selector-config.d.ts.map +1 -1
- package/lib/scripts/version.d.ts +1 -1
- package/lib/scripts/version.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-extractor.d.ts","sourceRoot":"","sources":["../../src/data-extractor.ts"],"names":[],"mappings":"AACA,OAAO,EACL,0BAA0B,EAC1B,UAAU,EAEV,kBAAkB,EAKnB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8DAA8D,CAAC;AAW/F,OAAO,KAAK,EAAE,oBAAoB,EAAE,4BAA4B,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGjH,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAIL,KAAK,2BAA2B,EAChC,KAAK,qBAAqB,EAC3B,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"data-extractor.d.ts","sourceRoot":"","sources":["../../src/data-extractor.ts"],"names":[],"mappings":"AACA,OAAO,EACL,0BAA0B,EAC1B,UAAU,EAEV,kBAAkB,EAKnB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8DAA8D,CAAC;AAW/F,OAAO,KAAK,EAAE,oBAAoB,EAAE,4BAA4B,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGjH,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAIL,KAAK,2BAA2B,EAChC,KAAK,qBAAqB,EAC3B,MAAM,6BAA6B,CAAC;AAmBrC,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAAW;IACtD,iBAAiB,CAAC,EAAE,kBAAkB,CAAC;IAEvC;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;gBAEpC,OAAO,EAAE,0BAA0B,EAAE,OAAO,CAAC,EAAE;QAAE,iBAAiB,EAAE,kBAAkB,CAAA;KAAE;IAwBpG;;;;OAIG;IACH,sBAAsB,SAAU,MAAM,GAAG,IAAI,KAAG,MAAM,CAEpD;IAGF,YAAY,YAAa,OAAO,GAAG,IAAI,eA4CrC;IAEF,eAAe,YAAa,OAAO,KAAG,MAAM,CAiB1C;IAEF,cAAc,YAAa,OAAO,GAAG,IAAI,KAAG,MAAM,CAYhD;IAEF;;;;;;OAMG;IACH,oBAAoB,YAAa,2BAA2B,GAAG,IAAI,WAAW,qBAAqB,KAAG,IAAI,CAExG;IAGF,kBAAkB,eAAgB,UAAU,WAAW,OAAO,uBAAuB,MAAM;;MAmDzF;IAEF,mBAAmB,oJASjB;IAEF,4BAA4B,0GAGP,MAAM,EAAE,uBACN,MAAM,6DAmC3B;IAEF,yBAAyB,eAAgB,UAAU,kBAAkB,WAAW,+BAkB9E;IAIF,OAAO,CAAC,4BAA4B,CA2BlC;IAEF,OAAO,YAAa,OAAO,KAAG,MAAM,CAalC;IAGF,gBAAgB,YAAa,OAAO,KAAG,OAAO,MAAM,EAAE,SAAS,CAAC,CAa9D;CACH"}
|
|
@@ -18,10 +18,9 @@ var element_selector_1 = require("@amplitude/element-selector");
|
|
|
18
18
|
* while the other still uses defaults.
|
|
19
19
|
*/
|
|
20
20
|
var sharedSelectorEngine;
|
|
21
|
-
var sharedSelectorLogger;
|
|
22
21
|
function getSharedSelectorEngine() {
|
|
23
22
|
if (!sharedSelectorEngine) {
|
|
24
|
-
sharedSelectorEngine = (0, element_selector_1.createSelectorEngine)((0, element_selector_1.resolveSelectorConfig)()
|
|
23
|
+
sharedSelectorEngine = (0, element_selector_1.createSelectorEngine)((0, element_selector_1.resolveSelectorConfig)());
|
|
25
24
|
}
|
|
26
25
|
return sharedSelectorEngine;
|
|
27
26
|
}
|
|
@@ -114,16 +113,7 @@ var DataExtractor = /** @class */ (function () {
|
|
|
114
113
|
return '';
|
|
115
114
|
}
|
|
116
115
|
var startTime = performance.now();
|
|
117
|
-
var config = _this.selectorEngine.getConfig();
|
|
118
116
|
var elementPath = _this.selectorEngine.generate(element);
|
|
119
|
-
if (config.enabled && sharedSelectorLogger) {
|
|
120
|
-
var id = element.getAttribute('id');
|
|
121
|
-
sharedSelectorLogger.debug('@amplitude/plugin-autocapture-browser: element-selector engine enabled', {
|
|
122
|
-
elementPath: elementPath,
|
|
123
|
-
tag: element.tagName.toLowerCase(),
|
|
124
|
-
id: id || undefined,
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
117
|
var endTime = performance.now();
|
|
128
118
|
(_a = _this.diagnosticsClient) === null || _a === void 0 ? void 0 : _a.recordHistogram('autocapturePlugin.getElementPath', endTime - startTime);
|
|
129
119
|
return elementPath;
|
|
@@ -136,22 +126,7 @@ var DataExtractor = /** @class */ (function () {
|
|
|
136
126
|
* the new strategy-based selector output.
|
|
137
127
|
*/
|
|
138
128
|
this.updateSelectorConfig = function (remote, logger) {
|
|
139
|
-
|
|
140
|
-
sharedSelectorLogger = logger;
|
|
141
|
-
}
|
|
142
|
-
var resolved = (0, element_selector_1.resolveSelectorConfig)(remote !== null && remote !== void 0 ? remote : undefined, logger);
|
|
143
|
-
var engine = getSharedSelectorEngine();
|
|
144
|
-
var previousEnabled = engine.getConfig().enabled;
|
|
145
|
-
engine.updateConfig(resolved);
|
|
146
|
-
logger === null || logger === void 0 ? void 0 : logger.debug('@amplitude/plugin-autocapture-browser: element-selector config updated', {
|
|
147
|
-
enabled: resolved.enabled,
|
|
148
|
-
wasEnabled: previousEnabled,
|
|
149
|
-
toggled: previousEnabled !== resolved.enabled,
|
|
150
|
-
explicitTrackingAttribute: resolved.explicitTrackingAttribute,
|
|
151
|
-
autogeneratedIdPatternCount: resolved.autogeneratedIdPatterns.length,
|
|
152
|
-
unstableClassPatternCount: resolved.unstableClassPatterns.length,
|
|
153
|
-
maxAncestorWalkDepth: resolved.maxAncestorWalkDepth,
|
|
154
|
-
});
|
|
129
|
+
_this.selectorEngine.updateConfig((0, element_selector_1.resolveSelectorConfig)(remote !== null && remote !== void 0 ? remote : undefined, logger));
|
|
155
130
|
};
|
|
156
131
|
// Returns the Amplitude event properties for the given element.
|
|
157
132
|
this.getEventProperties = function (actionType, element, dataAttributePrefix) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-extractor.js","sourceRoot":"","sources":["../../src/data-extractor.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-restricted-globals */\nimport {\n ElementInteractionsOptions,\n ActionType,\n getDecodeURI,\n IDiagnosticsClient,\n MASKED_TEXT_VALUE,\n TEXT_MASK_ATTRIBUTE,\n getPageTitle,\n replaceSensitiveString,\n} from '@amplitude/analytics-core';\nimport type { DataSource } from '@amplitude/analytics-core/lib/esm/types/element-interactions';\nimport * as constants from './constants';\nimport {\n removeEmptyProperties,\n extractPrefixedAttributes,\n isElementPointerCursor,\n getClosestElement,\n isElementBasedEvent,\n parseAttributesToMask,\n getCurrentPageViewId,\n} from './helpers';\nimport type { BaseTimestampedEvent, ElementBasedTimestampedEvent, TimestampedEvent, JSONValue } from './helpers';\nimport { getAncestors, getElementProperties } from './hierarchy';\nimport { getDataSource } from './pageActions/actions';\nimport { Hierarchy } from './typings/autocapture';\nimport {\n createSelectorEngine,\n resolveSelectorConfig,\n type SelectorEngine,\n type ElementSelectorRemoteConfig,\n type ElementSelectorLogger,\n} from '@amplitude/element-selector';\n\n/**\n * Module-level shared selector engine singleton. Both autocapture-plugin and\n * frustration-plugin create separate DataExtractor instances, and each\n * subscribes to remote config independently. By sharing a single engine across\n * all extractors, whichever subscription fires first updates the engine for\n * everyone, eliminating the window where one plugin could see updated config\n * while the other still uses defaults.\n */\nlet sharedSelectorEngine: SelectorEngine | undefined;\nlet sharedSelectorLogger: ElementSelectorLogger | undefined;\n\nfunction getSharedSelectorEngine(): SelectorEngine {\n if (!sharedSelectorEngine) {\n sharedSelectorEngine = createSelectorEngine(resolveSelectorConfig(), { logger: sharedSelectorLogger });\n }\n return sharedSelectorEngine;\n}\n\nexport class DataExtractor {\n private readonly additionalMaskTextPatterns: RegExp[];\n diagnosticsClient?: IDiagnosticsClient;\n\n /**\n * Shared element-selector engine. This is the single place autocapture turns\n * an element into a selector string ({@link getElementPath}), so it's the\n * seam where the legacy `cssPath` walker is swapped for the configurable\n * engine. It ships dormant: with the default config (`enabled: false`) the\n * engine routes through the byte-identical legacy walker, so behavior is\n * unchanged until remote config flips an org onto the new algorithm via\n * {@link updateSelectorConfig}.\n *\n * The engine is shared across all DataExtractor instances to ensure\n * consistent selector output when both autocapture-plugin and\n * frustration-plugin are active.\n */\n private readonly selectorEngine: SelectorEngine;\n\n constructor(options: ElementInteractionsOptions, context?: { diagnosticsClient: IDiagnosticsClient }) {\n this.diagnosticsClient = context?.diagnosticsClient;\n this.selectorEngine = getSharedSelectorEngine();\n\n const rawPatterns = options.maskTextRegex ?? [];\n\n const compiled: RegExp[] = [];\n for (const entry of rawPatterns) {\n if (compiled.length >= constants.MAX_MASK_TEXT_PATTERNS) {\n break;\n }\n if (entry instanceof RegExp) {\n compiled.push(entry);\n } else if ('pattern' in entry && typeof entry.pattern === 'string') {\n try {\n compiled.push(new RegExp(entry.pattern, 'i'));\n } catch {\n // ignore invalid pattern strings\n }\n }\n }\n this.additionalMaskTextPatterns = compiled;\n }\n\n /**\n * Wrapper method to replace sensitive strings using the helper function\n * @param text - The text to search for sensitive data\n * @returns The text with sensitive data replaced by masked text\n */\n replaceSensitiveString = (text: string | null): string => {\n return replaceSensitiveString(text, this.additionalMaskTextPatterns);\n };\n\n // Get the DOM hierarchy of the element, starting from the target element to the root element.\n getHierarchy = (element: Element | null): Hierarchy => {\n const startTime = performance.now();\n\n let hierarchy: Hierarchy = [];\n if (!element) {\n return [];\n }\n\n // Get list of ancestors including itself and get properties at each level in the hierarchy\n const ancestors = getAncestors(element);\n\n // Build attributes to mask map\n const elementToAttributesToMaskMap = new Map<Element, Set<string>>();\n\n for (let i = ancestors.length - 1; i >= 0; i--) {\n const node = ancestors[i];\n if (node) {\n const attributesToMask = parseAttributesToMask(node.getAttribute(constants.DATA_AMP_MASK_ATTRIBUTES));\n const ancestorAttributesToMask =\n i === ancestors.length - 1 ? [] : elementToAttributesToMaskMap.get(ancestors[i + 1]) ?? new Set<string>();\n const combinedAttributesToMask = new Set([...ancestorAttributesToMask, ...attributesToMask]);\n elementToAttributesToMaskMap.set(node, combinedAttributesToMask);\n }\n }\n\n hierarchy = ancestors.map((el) =>\n getElementProperties(el, elementToAttributesToMaskMap.get(el) ?? new Set<string>()),\n );\n\n // Search for and mask any sensitive attribute values\n for (const hierarchyNode of hierarchy) {\n if (hierarchyNode?.attrs) {\n Object.entries(hierarchyNode.attrs).forEach(([key, value]) => {\n if (hierarchyNode.attrs) {\n hierarchyNode.attrs[key] = this.replaceSensitiveString(value);\n }\n });\n }\n }\n\n const endTime = performance.now();\n this.diagnosticsClient?.recordHistogram('autocapturePlugin.getHierarchy', endTime - startTime);\n\n return hierarchy;\n };\n\n getNearestLabel = (element: Element): string => {\n const parent = element.parentElement;\n if (!parent) {\n return '';\n }\n let labelElement: Element | null;\n try {\n labelElement = parent.querySelector(':scope>span,h1,h2,h3,h4,h5,h6');\n } catch {\n /* istanbul ignore next */\n labelElement = null;\n }\n if (labelElement) {\n /* istanbul ignore next */\n return this.getText(labelElement);\n }\n return this.getNearestLabel(parent);\n };\n\n getElementPath = (element: Element | null): string => {\n if (!element) {\n return '';\n }\n const startTime = performance.now();\n\n const config = this.selectorEngine.getConfig();\n const elementPath = this.selectorEngine.generate(element);\n\n if (config.enabled && sharedSelectorLogger) {\n const id = element.getAttribute('id');\n sharedSelectorLogger.debug('@amplitude/plugin-autocapture-browser: element-selector engine enabled', {\n elementPath,\n tag: element.tagName.toLowerCase(),\n id: id || undefined,\n });\n }\n\n const endTime = performance.now();\n this.diagnosticsClient?.recordHistogram('autocapturePlugin.getElementPath', endTime - startTime);\n\n return elementPath;\n };\n\n /**\n * Apply an element-selector remote-config payload to the engine. Called from\n * plugin setup when remote config is delivered. Resolving an absent/empty\n * payload yields the documented defaults (engine stays dormant on legacy\n * `cssPath`); flipping `enabled: true` switches {@link getElementPath} onto\n * the new strategy-based selector output.\n */\n updateSelectorConfig = (remote?: ElementSelectorRemoteConfig | null, logger?: ElementSelectorLogger): void => {\n if (logger) {\n sharedSelectorLogger = logger;\n }\n\n const resolved = resolveSelectorConfig(remote ?? undefined, logger);\n const engine = getSharedSelectorEngine();\n const previousEnabled = engine.getConfig().enabled;\n\n engine.updateConfig(resolved);\n\n logger?.debug('@amplitude/plugin-autocapture-browser: element-selector config updated', {\n enabled: resolved.enabled,\n wasEnabled: previousEnabled,\n toggled: previousEnabled !== resolved.enabled,\n explicitTrackingAttribute: resolved.explicitTrackingAttribute,\n autogeneratedIdPatternCount: resolved.autogeneratedIdPatterns.length,\n unstableClassPatternCount: resolved.unstableClassPatterns.length,\n maxAncestorWalkDepth: resolved.maxAncestorWalkDepth,\n });\n };\n\n // Returns the Amplitude event properties for the given element.\n getEventProperties = (actionType: ActionType, element: Element, dataAttributePrefix: string) => {\n /* istanbul ignore next */\n const tag = element?.tagName?.toLowerCase?.();\n /* istanbul ignore next */\n const rect =\n typeof element.getBoundingClientRect === 'function' ? element.getBoundingClientRect() : { left: null, top: null };\n\n const hierarchy = this.getHierarchy(element);\n const currentElementAttributes = hierarchy[0]?.attrs;\n const nearestLabel = this.getNearestLabel(element);\n const attributes = extractPrefixedAttributes(currentElementAttributes ?? {}, dataAttributePrefix);\n\n /* istanbul ignore next */\n const properties: Record<string, any> = {\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_HIERARCHY]: hierarchy,\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_TAG]: tag,\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_TEXT]: this.getText(element),\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_POSITION_LEFT]: rect.left == null ? null : Math.round(rect.left),\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_POSITION_TOP]: rect.top == null ? null : Math.round(rect.top),\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_ATTRIBUTES]: attributes,\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_PATH]: this.getElementPath(element),\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_PARENT_LABEL]: nearestLabel,\n [constants.AMPLITUDE_EVENT_PROP_PAGE_URL]: getDecodeURI(window.location.href.split('?')[0]),\n [constants.AMPLITUDE_EVENT_PROP_PAGE_TITLE]: (\n getPageTitle as (parseTitleFunction: (title: string) => string) => string\n )(this.replaceSensitiveString),\n [constants.AMPLITUDE_EVENT_PROP_VIEWPORT_HEIGHT]: window.innerHeight,\n [constants.AMPLITUDE_EVENT_PROP_VIEWPORT_WIDTH]: window.innerWidth,\n };\n\n const pageViewId = getCurrentPageViewId();\n /* istanbul ignore next */\n if (pageViewId) {\n /* istanbul ignore next */\n properties[constants.AMPLITUDE_EVENT_PROP_PAGE_VIEW_ID] = pageViewId;\n }\n\n // id is never masked, so always include it\n properties[constants.AMPLITUDE_EVENT_PROP_ELEMENT_ID] = element.getAttribute('id') || '';\n\n // class is never masked, so always include it\n properties[constants.AMPLITUDE_EVENT_PROP_ELEMENT_CLASS] = element.getAttribute('class');\n\n properties[constants.AMPLITUDE_EVENT_PROP_ELEMENT_ARIA_LABEL] = currentElementAttributes?.['aria-label'];\n\n if (tag === 'a' && actionType === 'click' && element instanceof HTMLAnchorElement) {\n const href = element.href.substring(0, constants.MAX_ATTRIBUTE_LENGTH);\n properties[constants.AMPLITUDE_EVENT_PROP_ELEMENT_HREF] = this.replaceSensitiveString(href); // we don't use hierarchy here because we don't want href value to be changed\n }\n\n return removeEmptyProperties(properties);\n };\n\n addTypeAndTimestamp = <T>(\n event: T,\n type: BaseTimestampedEvent<T>['type'] | ElementBasedTimestampedEvent<T>['type'],\n ): BaseTimestampedEvent<T> | ElementBasedTimestampedEvent<T> => {\n return {\n event,\n timestamp: Date.now(),\n type,\n };\n };\n\n addAdditionalEventProperties = <T>(\n event: T,\n type: TimestampedEvent<T>['type'],\n selectorAllowlist: string[],\n dataAttributePrefix: string,\n // capture the event if the cursor is a \"pointer\" when this element is clicked on\n // reason: a \"pointer\" cursor indicates that an element should be interactable\n // regardless of the element's tag name\n isCapturingCursorPointer = false,\n ): TimestampedEvent<T> | ElementBasedTimestampedEvent<T> => {\n const baseEvent = this.addTypeAndTimestamp(event, type);\n\n if (isElementBasedEvent(baseEvent) && baseEvent.event.target !== null) {\n if (isCapturingCursorPointer) {\n const isCursorPointer = isElementPointerCursor(baseEvent.event.target as Element, baseEvent.type);\n if (isCursorPointer) {\n baseEvent.closestTrackedAncestor = baseEvent.event.target as HTMLElement;\n baseEvent.targetElementProperties = this.getEventProperties(\n baseEvent.type,\n baseEvent.closestTrackedAncestor,\n dataAttributePrefix,\n );\n return baseEvent;\n }\n }\n // Retrieve additional event properties from the target element\n const closestTrackedAncestor = getClosestElement(baseEvent.event.target as HTMLElement, selectorAllowlist);\n if (closestTrackedAncestor) {\n baseEvent.closestTrackedAncestor = closestTrackedAncestor;\n baseEvent.targetElementProperties = this.getEventProperties(\n baseEvent.type,\n closestTrackedAncestor,\n dataAttributePrefix,\n );\n }\n return baseEvent;\n }\n\n return baseEvent;\n };\n\n extractDataFromDataSource = (dataSource: DataSource, contextElement: HTMLElement) => {\n // Extract from DOM Element\n if (dataSource.sourceType === 'DOM_ELEMENT') {\n const sourceElement = getDataSource(dataSource, contextElement);\n if (!sourceElement) {\n return undefined;\n }\n\n if (dataSource.elementExtractType === 'TEXT') {\n return this.getText(sourceElement);\n } else if (dataSource.elementExtractType === 'ATTRIBUTE' && dataSource.attribute) {\n return sourceElement.getAttribute(dataSource.attribute);\n }\n return undefined;\n }\n\n // TODO: Extract from other source types\n return undefined;\n };\n\n // Traverse text content without cloning DOM nodes, which avoids media/network side effects\n // from recreating nested elements such as <video>, <audio>, or <img>.\n private getTextWithMaskedDescendants = (element: Element): string => {\n const maskedSelector = `[${TEXT_MASK_ATTRIBUTE}], [contenteditable]`;\n // Fast path: if no masked descendants exist, rely on native text extraction.\n if (!element.querySelector(maskedSelector)) {\n return (element as HTMLElement).innerText;\n }\n\n let output = '';\n const childNodes = Array.from(element.childNodes);\n for (const childNode of childNodes) {\n if (childNode.nodeType === Node.TEXT_NODE) {\n output += childNode.textContent || '';\n continue;\n }\n\n if (!(childNode instanceof Element)) {\n continue;\n }\n\n // Replace entire masked/contenteditable subtrees with the mask token.\n if (childNode.hasAttribute(TEXT_MASK_ATTRIBUTE) || childNode.hasAttribute('contenteditable')) {\n output += MASKED_TEXT_VALUE;\n continue;\n }\n output += this.getTextWithMaskedDescendants(childNode);\n }\n return output;\n };\n\n getText = (element: Element): string => {\n // Check if element or any parent has data-amp-mask attribute\n const hasMaskAttribute = element.closest(`[${TEXT_MASK_ATTRIBUTE}]`) !== null;\n if (hasMaskAttribute) {\n return MASKED_TEXT_VALUE;\n }\n let output = '';\n if (!element.querySelector(`[${TEXT_MASK_ATTRIBUTE}], [contenteditable]`)) {\n output = (element as HTMLElement).innerText || '';\n } else {\n output = this.getTextWithMaskedDescendants(element);\n }\n return this.replaceSensitiveString(output.substring(0, 255)).replace(/\\s+/g, ' ').trim();\n };\n\n // Returns the element properties for the given element in Visual Labeling.\n getEventTagProps = (element: Element): Record<string, JSONValue> => {\n if (!element) {\n return {};\n }\n /* istanbul ignore next */\n const tag = element?.tagName?.toLowerCase?.();\n\n const properties = {\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_TAG]: tag,\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_TEXT]: this.getText(element),\n [constants.AMPLITUDE_EVENT_PROP_PAGE_URL]: window.location.href.split('?')[0],\n };\n return removeEmptyProperties(properties) as Record<string, JSONValue>;\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"data-extractor.js","sourceRoot":"","sources":["../../src/data-extractor.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-restricted-globals */\nimport {\n ElementInteractionsOptions,\n ActionType,\n getDecodeURI,\n IDiagnosticsClient,\n MASKED_TEXT_VALUE,\n TEXT_MASK_ATTRIBUTE,\n getPageTitle,\n replaceSensitiveString,\n} from '@amplitude/analytics-core';\nimport type { DataSource } from '@amplitude/analytics-core/lib/esm/types/element-interactions';\nimport * as constants from './constants';\nimport {\n removeEmptyProperties,\n extractPrefixedAttributes,\n isElementPointerCursor,\n getClosestElement,\n isElementBasedEvent,\n parseAttributesToMask,\n getCurrentPageViewId,\n} from './helpers';\nimport type { BaseTimestampedEvent, ElementBasedTimestampedEvent, TimestampedEvent, JSONValue } from './helpers';\nimport { getAncestors, getElementProperties } from './hierarchy';\nimport { getDataSource } from './pageActions/actions';\nimport { Hierarchy } from './typings/autocapture';\nimport {\n createSelectorEngine,\n resolveSelectorConfig,\n type SelectorEngine,\n type ElementSelectorRemoteConfig,\n type ElementSelectorLogger,\n} from '@amplitude/element-selector';\n\n/**\n * Module-level shared selector engine singleton. Both autocapture-plugin and\n * frustration-plugin create separate DataExtractor instances, and each\n * subscribes to remote config independently. By sharing a single engine across\n * all extractors, whichever subscription fires first updates the engine for\n * everyone, eliminating the window where one plugin could see updated config\n * while the other still uses defaults.\n */\nlet sharedSelectorEngine: SelectorEngine | undefined;\n\nfunction getSharedSelectorEngine(): SelectorEngine {\n if (!sharedSelectorEngine) {\n sharedSelectorEngine = createSelectorEngine(resolveSelectorConfig());\n }\n return sharedSelectorEngine;\n}\n\nexport class DataExtractor {\n private readonly additionalMaskTextPatterns: RegExp[];\n diagnosticsClient?: IDiagnosticsClient;\n\n /**\n * Shared element-selector engine. This is the single place autocapture turns\n * an element into a selector string ({@link getElementPath}), so it's the\n * seam where the legacy `cssPath` walker is swapped for the configurable\n * engine. It ships dormant: with the default config (`enabled: false`) the\n * engine routes through the byte-identical legacy walker, so behavior is\n * unchanged until remote config flips an org onto the new algorithm via\n * {@link updateSelectorConfig}.\n *\n * The engine is shared across all DataExtractor instances to ensure\n * consistent selector output when both autocapture-plugin and\n * frustration-plugin are active.\n */\n private readonly selectorEngine: SelectorEngine;\n\n constructor(options: ElementInteractionsOptions, context?: { diagnosticsClient: IDiagnosticsClient }) {\n this.diagnosticsClient = context?.diagnosticsClient;\n this.selectorEngine = getSharedSelectorEngine();\n\n const rawPatterns = options.maskTextRegex ?? [];\n\n const compiled: RegExp[] = [];\n for (const entry of rawPatterns) {\n if (compiled.length >= constants.MAX_MASK_TEXT_PATTERNS) {\n break;\n }\n if (entry instanceof RegExp) {\n compiled.push(entry);\n } else if ('pattern' in entry && typeof entry.pattern === 'string') {\n try {\n compiled.push(new RegExp(entry.pattern, 'i'));\n } catch {\n // ignore invalid pattern strings\n }\n }\n }\n this.additionalMaskTextPatterns = compiled;\n }\n\n /**\n * Wrapper method to replace sensitive strings using the helper function\n * @param text - The text to search for sensitive data\n * @returns The text with sensitive data replaced by masked text\n */\n replaceSensitiveString = (text: string | null): string => {\n return replaceSensitiveString(text, this.additionalMaskTextPatterns);\n };\n\n // Get the DOM hierarchy of the element, starting from the target element to the root element.\n getHierarchy = (element: Element | null): Hierarchy => {\n const startTime = performance.now();\n\n let hierarchy: Hierarchy = [];\n if (!element) {\n return [];\n }\n\n // Get list of ancestors including itself and get properties at each level in the hierarchy\n const ancestors = getAncestors(element);\n\n // Build attributes to mask map\n const elementToAttributesToMaskMap = new Map<Element, Set<string>>();\n\n for (let i = ancestors.length - 1; i >= 0; i--) {\n const node = ancestors[i];\n if (node) {\n const attributesToMask = parseAttributesToMask(node.getAttribute(constants.DATA_AMP_MASK_ATTRIBUTES));\n const ancestorAttributesToMask =\n i === ancestors.length - 1 ? [] : elementToAttributesToMaskMap.get(ancestors[i + 1]) ?? new Set<string>();\n const combinedAttributesToMask = new Set([...ancestorAttributesToMask, ...attributesToMask]);\n elementToAttributesToMaskMap.set(node, combinedAttributesToMask);\n }\n }\n\n hierarchy = ancestors.map((el) =>\n getElementProperties(el, elementToAttributesToMaskMap.get(el) ?? new Set<string>()),\n );\n\n // Search for and mask any sensitive attribute values\n for (const hierarchyNode of hierarchy) {\n if (hierarchyNode?.attrs) {\n Object.entries(hierarchyNode.attrs).forEach(([key, value]) => {\n if (hierarchyNode.attrs) {\n hierarchyNode.attrs[key] = this.replaceSensitiveString(value);\n }\n });\n }\n }\n\n const endTime = performance.now();\n this.diagnosticsClient?.recordHistogram('autocapturePlugin.getHierarchy', endTime - startTime);\n\n return hierarchy;\n };\n\n getNearestLabel = (element: Element): string => {\n const parent = element.parentElement;\n if (!parent) {\n return '';\n }\n let labelElement: Element | null;\n try {\n labelElement = parent.querySelector(':scope>span,h1,h2,h3,h4,h5,h6');\n } catch {\n /* istanbul ignore next */\n labelElement = null;\n }\n if (labelElement) {\n /* istanbul ignore next */\n return this.getText(labelElement);\n }\n return this.getNearestLabel(parent);\n };\n\n getElementPath = (element: Element | null): string => {\n if (!element) {\n return '';\n }\n const startTime = performance.now();\n\n const elementPath = this.selectorEngine.generate(element);\n\n const endTime = performance.now();\n this.diagnosticsClient?.recordHistogram('autocapturePlugin.getElementPath', endTime - startTime);\n\n return elementPath;\n };\n\n /**\n * Apply an element-selector remote-config payload to the engine. Called from\n * plugin setup when remote config is delivered. Resolving an absent/empty\n * payload yields the documented defaults (engine stays dormant on legacy\n * `cssPath`); flipping `enabled: true` switches {@link getElementPath} onto\n * the new strategy-based selector output.\n */\n updateSelectorConfig = (remote?: ElementSelectorRemoteConfig | null, logger?: ElementSelectorLogger): void => {\n this.selectorEngine.updateConfig(resolveSelectorConfig(remote ?? undefined, logger));\n };\n\n // Returns the Amplitude event properties for the given element.\n getEventProperties = (actionType: ActionType, element: Element, dataAttributePrefix: string) => {\n /* istanbul ignore next */\n const tag = element?.tagName?.toLowerCase?.();\n /* istanbul ignore next */\n const rect =\n typeof element.getBoundingClientRect === 'function' ? element.getBoundingClientRect() : { left: null, top: null };\n\n const hierarchy = this.getHierarchy(element);\n const currentElementAttributes = hierarchy[0]?.attrs;\n const nearestLabel = this.getNearestLabel(element);\n const attributes = extractPrefixedAttributes(currentElementAttributes ?? {}, dataAttributePrefix);\n\n /* istanbul ignore next */\n const properties: Record<string, any> = {\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_HIERARCHY]: hierarchy,\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_TAG]: tag,\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_TEXT]: this.getText(element),\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_POSITION_LEFT]: rect.left == null ? null : Math.round(rect.left),\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_POSITION_TOP]: rect.top == null ? null : Math.round(rect.top),\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_ATTRIBUTES]: attributes,\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_PATH]: this.getElementPath(element),\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_PARENT_LABEL]: nearestLabel,\n [constants.AMPLITUDE_EVENT_PROP_PAGE_URL]: getDecodeURI(window.location.href.split('?')[0]),\n [constants.AMPLITUDE_EVENT_PROP_PAGE_TITLE]: (\n getPageTitle as (parseTitleFunction: (title: string) => string) => string\n )(this.replaceSensitiveString),\n [constants.AMPLITUDE_EVENT_PROP_VIEWPORT_HEIGHT]: window.innerHeight,\n [constants.AMPLITUDE_EVENT_PROP_VIEWPORT_WIDTH]: window.innerWidth,\n };\n\n const pageViewId = getCurrentPageViewId();\n /* istanbul ignore next */\n if (pageViewId) {\n /* istanbul ignore next */\n properties[constants.AMPLITUDE_EVENT_PROP_PAGE_VIEW_ID] = pageViewId;\n }\n\n // id is never masked, so always include it\n properties[constants.AMPLITUDE_EVENT_PROP_ELEMENT_ID] = element.getAttribute('id') || '';\n\n // class is never masked, so always include it\n properties[constants.AMPLITUDE_EVENT_PROP_ELEMENT_CLASS] = element.getAttribute('class');\n\n properties[constants.AMPLITUDE_EVENT_PROP_ELEMENT_ARIA_LABEL] = currentElementAttributes?.['aria-label'];\n\n if (tag === 'a' && actionType === 'click' && element instanceof HTMLAnchorElement) {\n const href = element.href.substring(0, constants.MAX_ATTRIBUTE_LENGTH);\n properties[constants.AMPLITUDE_EVENT_PROP_ELEMENT_HREF] = this.replaceSensitiveString(href); // we don't use hierarchy here because we don't want href value to be changed\n }\n\n return removeEmptyProperties(properties);\n };\n\n addTypeAndTimestamp = <T>(\n event: T,\n type: BaseTimestampedEvent<T>['type'] | ElementBasedTimestampedEvent<T>['type'],\n ): BaseTimestampedEvent<T> | ElementBasedTimestampedEvent<T> => {\n return {\n event,\n timestamp: Date.now(),\n type,\n };\n };\n\n addAdditionalEventProperties = <T>(\n event: T,\n type: TimestampedEvent<T>['type'],\n selectorAllowlist: string[],\n dataAttributePrefix: string,\n // capture the event if the cursor is a \"pointer\" when this element is clicked on\n // reason: a \"pointer\" cursor indicates that an element should be interactable\n // regardless of the element's tag name\n isCapturingCursorPointer = false,\n ): TimestampedEvent<T> | ElementBasedTimestampedEvent<T> => {\n const baseEvent = this.addTypeAndTimestamp(event, type);\n\n if (isElementBasedEvent(baseEvent) && baseEvent.event.target !== null) {\n if (isCapturingCursorPointer) {\n const isCursorPointer = isElementPointerCursor(baseEvent.event.target as Element, baseEvent.type);\n if (isCursorPointer) {\n baseEvent.closestTrackedAncestor = baseEvent.event.target as HTMLElement;\n baseEvent.targetElementProperties = this.getEventProperties(\n baseEvent.type,\n baseEvent.closestTrackedAncestor,\n dataAttributePrefix,\n );\n return baseEvent;\n }\n }\n // Retrieve additional event properties from the target element\n const closestTrackedAncestor = getClosestElement(baseEvent.event.target as HTMLElement, selectorAllowlist);\n if (closestTrackedAncestor) {\n baseEvent.closestTrackedAncestor = closestTrackedAncestor;\n baseEvent.targetElementProperties = this.getEventProperties(\n baseEvent.type,\n closestTrackedAncestor,\n dataAttributePrefix,\n );\n }\n return baseEvent;\n }\n\n return baseEvent;\n };\n\n extractDataFromDataSource = (dataSource: DataSource, contextElement: HTMLElement) => {\n // Extract from DOM Element\n if (dataSource.sourceType === 'DOM_ELEMENT') {\n const sourceElement = getDataSource(dataSource, contextElement);\n if (!sourceElement) {\n return undefined;\n }\n\n if (dataSource.elementExtractType === 'TEXT') {\n return this.getText(sourceElement);\n } else if (dataSource.elementExtractType === 'ATTRIBUTE' && dataSource.attribute) {\n return sourceElement.getAttribute(dataSource.attribute);\n }\n return undefined;\n }\n\n // TODO: Extract from other source types\n return undefined;\n };\n\n // Traverse text content without cloning DOM nodes, which avoids media/network side effects\n // from recreating nested elements such as <video>, <audio>, or <img>.\n private getTextWithMaskedDescendants = (element: Element): string => {\n const maskedSelector = `[${TEXT_MASK_ATTRIBUTE}], [contenteditable]`;\n // Fast path: if no masked descendants exist, rely on native text extraction.\n if (!element.querySelector(maskedSelector)) {\n return (element as HTMLElement).innerText;\n }\n\n let output = '';\n const childNodes = Array.from(element.childNodes);\n for (const childNode of childNodes) {\n if (childNode.nodeType === Node.TEXT_NODE) {\n output += childNode.textContent || '';\n continue;\n }\n\n if (!(childNode instanceof Element)) {\n continue;\n }\n\n // Replace entire masked/contenteditable subtrees with the mask token.\n if (childNode.hasAttribute(TEXT_MASK_ATTRIBUTE) || childNode.hasAttribute('contenteditable')) {\n output += MASKED_TEXT_VALUE;\n continue;\n }\n output += this.getTextWithMaskedDescendants(childNode);\n }\n return output;\n };\n\n getText = (element: Element): string => {\n // Check if element or any parent has data-amp-mask attribute\n const hasMaskAttribute = element.closest(`[${TEXT_MASK_ATTRIBUTE}]`) !== null;\n if (hasMaskAttribute) {\n return MASKED_TEXT_VALUE;\n }\n let output = '';\n if (!element.querySelector(`[${TEXT_MASK_ATTRIBUTE}], [contenteditable]`)) {\n output = (element as HTMLElement).innerText || '';\n } else {\n output = this.getTextWithMaskedDescendants(element);\n }\n return this.replaceSensitiveString(output.substring(0, 255)).replace(/\\s+/g, ' ').trim();\n };\n\n // Returns the element properties for the given element in Visual Labeling.\n getEventTagProps = (element: Element): Record<string, JSONValue> => {\n if (!element) {\n return {};\n }\n /* istanbul ignore next */\n const tag = element?.tagName?.toLowerCase?.();\n\n const properties = {\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_TAG]: tag,\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_TEXT]: this.getText(element),\n [constants.AMPLITUDE_EVENT_PROP_PAGE_URL]: window.location.href.split('?')[0],\n };\n return removeEmptyProperties(properties) as Record<string, JSONValue>;\n };\n}\n"]}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { BrowserConfig } from '@amplitude/analytics-core';
|
|
2
2
|
import { DataExtractor } from './data-extractor';
|
|
3
3
|
/**
|
|
4
|
-
* Remote-config key for the element-selector engine payload.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* `ElementSelectorRemoteConfig`.
|
|
4
|
+
* Remote-config key for the element-selector engine payload. Mirrors the
|
|
5
|
+
* `configs.analyticsSDK.pageActions` namespace autocapture already subscribes
|
|
6
|
+
* to. The payload shape is `ElementSelectorRemoteConfig`.
|
|
8
7
|
*/
|
|
9
|
-
export declare const ELEMENT_SELECTOR_REMOTE_CONFIG_KEY = "configs.analyticsSDK.
|
|
8
|
+
export declare const ELEMENT_SELECTOR_REMOTE_CONFIG_KEY = "configs.analyticsSDK.elementSelector";
|
|
10
9
|
/**
|
|
11
10
|
* Subscribe a plugin's {@link DataExtractor} to element-selector remote config.
|
|
12
11
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"element-selector-config.d.ts","sourceRoot":"","sources":["../../src/element-selector-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD
|
|
1
|
+
{"version":3,"file":"element-selector-config.d.ts","sourceRoot":"","sources":["../../src/element-selector-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD;;;;GAIG;AACH,eAAO,MAAM,kCAAkC,yCAAyC,CAAC;AAEzF;;;;;;;;;;GAUG;AACH,wBAAgB,gCAAgC,CAC9C,MAAM,EAAE,aAAa,EACrB,aAAa,EAAE,aAAa,GAC3B,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAa1B"}
|
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.subscribeToElementSelectorConfig = exports.ELEMENT_SELECTOR_REMOTE_CONFIG_KEY = void 0;
|
|
4
4
|
/**
|
|
5
|
-
* Remote-config key for the element-selector engine payload.
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* `ElementSelectorRemoteConfig`.
|
|
5
|
+
* Remote-config key for the element-selector engine payload. Mirrors the
|
|
6
|
+
* `configs.analyticsSDK.pageActions` namespace autocapture already subscribes
|
|
7
|
+
* to. The payload shape is `ElementSelectorRemoteConfig`.
|
|
9
8
|
*/
|
|
10
|
-
exports.ELEMENT_SELECTOR_REMOTE_CONFIG_KEY = 'configs.analyticsSDK.
|
|
9
|
+
exports.ELEMENT_SELECTOR_REMOTE_CONFIG_KEY = 'configs.analyticsSDK.elementSelector';
|
|
11
10
|
/**
|
|
12
11
|
* Subscribe a plugin's {@link DataExtractor} to element-selector remote config.
|
|
13
12
|
*
|
|
@@ -24,18 +23,10 @@ function subscribeToElementSelectorConfig(config, dataExtractor) {
|
|
|
24
23
|
if (!config.fetchRemoteConfig || !remoteConfigClient) {
|
|
25
24
|
return undefined;
|
|
26
25
|
}
|
|
27
|
-
config.loggerProvider.debug("@amplitude/plugin-autocapture-browser: subscribing to element-selector remote config at \"".concat(exports.ELEMENT_SELECTOR_REMOTE_CONFIG_KEY, "\""));
|
|
28
26
|
var subscriptionId = remoteConfigClient.subscribe(exports.ELEMENT_SELECTOR_REMOTE_CONFIG_KEY, 'all', function (remoteConfig) {
|
|
29
|
-
|
|
30
|
-
var payload = remoteConfig;
|
|
31
|
-
config.loggerProvider.debug('@amplitude/plugin-autocapture-browser: element-selector remote config delivered', {
|
|
32
|
-
enabled: (_a = payload === null || payload === void 0 ? void 0 : payload.enabled) !== null && _a !== void 0 ? _a : 'default (false)',
|
|
33
|
-
hasPayload: payload !== null && payload !== undefined,
|
|
34
|
-
});
|
|
35
|
-
dataExtractor.updateSelectorConfig(payload, config.loggerProvider);
|
|
27
|
+
dataExtractor.updateSelectorConfig(remoteConfig, config.loggerProvider);
|
|
36
28
|
});
|
|
37
29
|
return function () {
|
|
38
|
-
config.loggerProvider.debug("@amplitude/plugin-autocapture-browser: unsubscribing from element-selector remote config (subscription ".concat(subscriptionId, ")"));
|
|
39
30
|
remoteConfigClient.unsubscribe(subscriptionId);
|
|
40
31
|
};
|
|
41
32
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"element-selector-config.js","sourceRoot":"","sources":["../../src/element-selector-config.ts"],"names":[],"mappings":";;;AAIA
|
|
1
|
+
{"version":3,"file":"element-selector-config.js","sourceRoot":"","sources":["../../src/element-selector-config.ts"],"names":[],"mappings":";;;AAIA;;;;GAIG;AACU,QAAA,kCAAkC,GAAG,sCAAsC,CAAC;AAEzF;;;;;;;;;;GAUG;AACH,SAAgB,gCAAgC,CAC9C,MAAqB,EACrB,aAA4B;IAE5B,IAAM,kBAAkB,GAAG,MAAM,CAAC,kBAAkB,CAAC;IACrD,IAAI,CAAC,MAAM,CAAC,iBAAiB,IAAI,CAAC,kBAAkB,EAAE;QACpD,OAAO,SAAS,CAAC;KAClB;IAED,IAAM,cAAc,GAAG,kBAAkB,CAAC,SAAS,CAAC,0CAAkC,EAAE,KAAK,EAAE,UAAC,YAAY;QAC1G,aAAa,CAAC,oBAAoB,CAAC,YAAkD,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;IAChH,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,kBAAkB,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;IACjD,CAAC,CAAC;AACJ,CAAC;AAhBD,4EAgBC","sourcesContent":["import { BrowserConfig } from '@amplitude/analytics-core';\nimport { ElementSelectorRemoteConfig } from '@amplitude/element-selector';\nimport { DataExtractor } from './data-extractor';\n\n/**\n * Remote-config key for the element-selector engine payload. Mirrors the\n * `configs.analyticsSDK.pageActions` namespace autocapture already subscribes\n * to. The payload shape is `ElementSelectorRemoteConfig`.\n */\nexport const ELEMENT_SELECTOR_REMOTE_CONFIG_KEY = 'configs.analyticsSDK.elementSelector';\n\n/**\n * Subscribe a plugin's {@link DataExtractor} to element-selector remote config.\n *\n * On each delivery, the resolved config is pushed into the extractor's engine,\n * which changes what `getElementPath` (and therefore every selector-bearing\n * autocapture event) emits. When remote config is disabled or unavailable, this\n * is a no-op and the engine stays on the dormant defaults.\n *\n * @returns an unsubscribe function when a subscription was created, otherwise\n * `undefined`.\n */\nexport function subscribeToElementSelectorConfig(\n config: BrowserConfig,\n dataExtractor: DataExtractor,\n): (() => void) | undefined {\n const remoteConfigClient = config.remoteConfigClient;\n if (!config.fetchRemoteConfig || !remoteConfigClient) {\n return undefined;\n }\n\n const subscriptionId = remoteConfigClient.subscribe(ELEMENT_SELECTOR_REMOTE_CONFIG_KEY, 'all', (remoteConfig) => {\n dataExtractor.updateSelectorConfig(remoteConfig as ElementSelectorRemoteConfig | null, config.loggerProvider);\n });\n\n return () => {\n remoteConfigClient.unsubscribe(subscriptionId);\n };\n}\n"]}
|
package/lib/cjs/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "1.28.0
|
|
1
|
+
export declare const VERSION = "1.28.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/lib/cjs/version.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,WAAW,CAAC"}
|
package/lib/cjs/version.js
CHANGED
package/lib/cjs/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":";;;AAAa,QAAA,OAAO,GAAG,
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":";;;AAAa,QAAA,OAAO,GAAG,QAAQ,CAAC","sourcesContent":["export const VERSION = '1.28.0';\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-extractor.d.ts","sourceRoot":"","sources":["../../src/data-extractor.ts"],"names":[],"mappings":"AACA,OAAO,EACL,0BAA0B,EAC1B,UAAU,EAEV,kBAAkB,EAKnB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8DAA8D,CAAC;AAW/F,OAAO,KAAK,EAAE,oBAAoB,EAAE,4BAA4B,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGjH,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAIL,KAAK,2BAA2B,EAChC,KAAK,qBAAqB,EAC3B,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"data-extractor.d.ts","sourceRoot":"","sources":["../../src/data-extractor.ts"],"names":[],"mappings":"AACA,OAAO,EACL,0BAA0B,EAC1B,UAAU,EAEV,kBAAkB,EAKnB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8DAA8D,CAAC;AAW/F,OAAO,KAAK,EAAE,oBAAoB,EAAE,4BAA4B,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGjH,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAIL,KAAK,2BAA2B,EAChC,KAAK,qBAAqB,EAC3B,MAAM,6BAA6B,CAAC;AAmBrC,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAAW;IACtD,iBAAiB,CAAC,EAAE,kBAAkB,CAAC;IAEvC;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;gBAEpC,OAAO,EAAE,0BAA0B,EAAE,OAAO,CAAC,EAAE;QAAE,iBAAiB,EAAE,kBAAkB,CAAA;KAAE;IAwBpG;;;;OAIG;IACH,sBAAsB,SAAU,MAAM,GAAG,IAAI,KAAG,MAAM,CAEpD;IAGF,YAAY,YAAa,OAAO,GAAG,IAAI,eA4CrC;IAEF,eAAe,YAAa,OAAO,KAAG,MAAM,CAiB1C;IAEF,cAAc,YAAa,OAAO,GAAG,IAAI,KAAG,MAAM,CAYhD;IAEF;;;;;;OAMG;IACH,oBAAoB,YAAa,2BAA2B,GAAG,IAAI,WAAW,qBAAqB,KAAG,IAAI,CAExG;IAGF,kBAAkB,eAAgB,UAAU,WAAW,OAAO,uBAAuB,MAAM;;MAmDzF;IAEF,mBAAmB,oJASjB;IAEF,4BAA4B,0GAGP,MAAM,EAAE,uBACN,MAAM,6DAmC3B;IAEF,yBAAyB,eAAgB,UAAU,kBAAkB,WAAW,+BAkB9E;IAIF,OAAO,CAAC,4BAA4B,CA2BlC;IAEF,OAAO,YAAa,OAAO,KAAG,MAAM,CAalC;IAGF,gBAAgB,YAAa,OAAO,KAAG,OAAO,MAAM,EAAE,SAAS,CAAC,CAa9D;CACH"}
|
|
@@ -15,10 +15,9 @@ import { createSelectorEngine, resolveSelectorConfig, } from '@amplitude/element
|
|
|
15
15
|
* while the other still uses defaults.
|
|
16
16
|
*/
|
|
17
17
|
var sharedSelectorEngine;
|
|
18
|
-
var sharedSelectorLogger;
|
|
19
18
|
function getSharedSelectorEngine() {
|
|
20
19
|
if (!sharedSelectorEngine) {
|
|
21
|
-
sharedSelectorEngine = createSelectorEngine(resolveSelectorConfig()
|
|
20
|
+
sharedSelectorEngine = createSelectorEngine(resolveSelectorConfig());
|
|
22
21
|
}
|
|
23
22
|
return sharedSelectorEngine;
|
|
24
23
|
}
|
|
@@ -111,16 +110,7 @@ var DataExtractor = /** @class */ (function () {
|
|
|
111
110
|
return '';
|
|
112
111
|
}
|
|
113
112
|
var startTime = performance.now();
|
|
114
|
-
var config = _this.selectorEngine.getConfig();
|
|
115
113
|
var elementPath = _this.selectorEngine.generate(element);
|
|
116
|
-
if (config.enabled && sharedSelectorLogger) {
|
|
117
|
-
var id = element.getAttribute('id');
|
|
118
|
-
sharedSelectorLogger.debug('@amplitude/plugin-autocapture-browser: element-selector engine enabled', {
|
|
119
|
-
elementPath: elementPath,
|
|
120
|
-
tag: element.tagName.toLowerCase(),
|
|
121
|
-
id: id || undefined,
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
114
|
var endTime = performance.now();
|
|
125
115
|
(_a = _this.diagnosticsClient) === null || _a === void 0 ? void 0 : _a.recordHistogram('autocapturePlugin.getElementPath', endTime - startTime);
|
|
126
116
|
return elementPath;
|
|
@@ -133,22 +123,7 @@ var DataExtractor = /** @class */ (function () {
|
|
|
133
123
|
* the new strategy-based selector output.
|
|
134
124
|
*/
|
|
135
125
|
this.updateSelectorConfig = function (remote, logger) {
|
|
136
|
-
|
|
137
|
-
sharedSelectorLogger = logger;
|
|
138
|
-
}
|
|
139
|
-
var resolved = resolveSelectorConfig(remote !== null && remote !== void 0 ? remote : undefined, logger);
|
|
140
|
-
var engine = getSharedSelectorEngine();
|
|
141
|
-
var previousEnabled = engine.getConfig().enabled;
|
|
142
|
-
engine.updateConfig(resolved);
|
|
143
|
-
logger === null || logger === void 0 ? void 0 : logger.debug('@amplitude/plugin-autocapture-browser: element-selector config updated', {
|
|
144
|
-
enabled: resolved.enabled,
|
|
145
|
-
wasEnabled: previousEnabled,
|
|
146
|
-
toggled: previousEnabled !== resolved.enabled,
|
|
147
|
-
explicitTrackingAttribute: resolved.explicitTrackingAttribute,
|
|
148
|
-
autogeneratedIdPatternCount: resolved.autogeneratedIdPatterns.length,
|
|
149
|
-
unstableClassPatternCount: resolved.unstableClassPatterns.length,
|
|
150
|
-
maxAncestorWalkDepth: resolved.maxAncestorWalkDepth,
|
|
151
|
-
});
|
|
126
|
+
_this.selectorEngine.updateConfig(resolveSelectorConfig(remote !== null && remote !== void 0 ? remote : undefined, logger));
|
|
152
127
|
};
|
|
153
128
|
// Returns the Amplitude event properties for the given element.
|
|
154
129
|
this.getEventProperties = function (actionType, element, dataAttributePrefix) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-extractor.js","sourceRoot":"","sources":["../../src/data-extractor.ts"],"names":[],"mappings":";AAAA,0CAA0C;AAC1C,OAAO,EAGL,YAAY,EAEZ,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,sBAAsB,GACvB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,KAAK,SAAS,MAAM,aAAa,CAAC;AACzC,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,OAAO,EACL,oBAAoB,EACpB,qBAAqB,GAItB,MAAM,6BAA6B,CAAC;AAErC;;;;;;;GAOG;AACH,IAAI,oBAAgD,CAAC;AACrD,IAAI,oBAAuD,CAAC;AAE5D,SAAS,uBAAuB;IAC9B,IAAI,CAAC,oBAAoB,EAAE;QACzB,oBAAoB,GAAG,oBAAoB,CAAC,qBAAqB,EAAE,EAAE,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAC,CAAC;KACxG;IACD,OAAO,oBAAoB,CAAC;AAC9B,CAAC;AAED;IAmBE,uBAAY,OAAmC,EAAE,OAAmD;;QAApG,iBAsBC;;QAED;;;;WAIG;QACH,2BAAsB,GAAG,UAAC,IAAmB;YAC3C,OAAO,sBAAsB,CAAC,IAAI,EAAE,KAAI,CAAC,0BAA0B,CAAC,CAAC;QACvE,CAAC,CAAC;QAEF,8FAA8F;QAC9F,iBAAY,GAAG,UAAC,OAAuB;;;YACrC,IAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAEpC,IAAI,SAAS,GAAc,EAAE,CAAC;YAC9B,IAAI,CAAC,OAAO,EAAE;gBACZ,OAAO,EAAE,CAAC;aACX;YAED,2FAA2F;YAC3F,IAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;YAExC,+BAA+B;YAC/B,IAAM,4BAA4B,GAAG,IAAI,GAAG,EAAwB,CAAC;YAErE,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;gBAC9C,IAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;gBAC1B,IAAI,IAAI,EAAE;oBACR,IAAM,gBAAgB,GAAG,qBAAqB,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC,CAAC;oBACtG,IAAM,wBAAwB,GAC5B,CAAC,KAAK,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAA,4BAA4B,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,mCAAI,IAAI,GAAG,EAAU,CAAC;oBAC5G,IAAM,wBAAwB,GAAG,IAAI,GAAG,wCAAK,wBAAwB,kBAAK,gBAAgB,UAAE,CAAC;oBAC7F,4BAA4B,CAAC,GAAG,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAAC;iBAClE;aACF;YAED,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,UAAC,EAAE,YAC3B,OAAA,oBAAoB,CAAC,EAAE,EAAE,MAAA,4BAA4B,CAAC,GAAG,CAAC,EAAE,CAAC,mCAAI,IAAI,GAAG,EAAU,CAAC,CAAA,EAAA,CACpF,CAAC;oCAGS,aAAa;gBACtB,IAAI,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,KAAK,EAAE;oBACxB,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,UAAC,EAAY;4BAAZ,KAAA,aAAY,EAAX,GAAG,QAAA,EAAE,KAAK,QAAA;wBACtD,IAAI,aAAa,CAAC,KAAK,EAAE;4BACvB,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,KAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;yBAC/D;oBACH,CAAC,CAAC,CAAC;iBACJ;;;gBARH,qDAAqD;gBACrD,KAA4B,IAAA,cAAA,SAAA,SAAS,CAAA,oCAAA;oBAAhC,IAAM,aAAa,sBAAA;4BAAb,aAAa;iBAQvB;;;;;;;;;YAED,IAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAClC,MAAA,KAAI,CAAC,iBAAiB,0CAAE,eAAe,CAAC,gCAAgC,EAAE,OAAO,GAAG,SAAS,CAAC,CAAC;YAE/F,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC;QAEF,oBAAe,GAAG,UAAC,OAAgB;YACjC,IAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;YACrC,IAAI,CAAC,MAAM,EAAE;gBACX,OAAO,EAAE,CAAC;aACX;YACD,IAAI,YAA4B,CAAC;YACjC,IAAI;gBACF,YAAY,GAAG,MAAM,CAAC,aAAa,CAAC,+BAA+B,CAAC,CAAC;aACtE;YAAC,WAAM;gBACN,0BAA0B;gBAC1B,YAAY,GAAG,IAAI,CAAC;aACrB;YACD,IAAI,YAAY,EAAE;gBAChB,0BAA0B;gBAC1B,OAAO,KAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;aACnC;YACD,OAAO,KAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QACtC,CAAC,CAAC;QAEF,mBAAc,GAAG,UAAC,OAAuB;;YACvC,IAAI,CAAC,OAAO,EAAE;gBACZ,OAAO,EAAE,CAAC;aACX;YACD,IAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAEpC,IAAM,MAAM,GAAG,KAAI,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC;YAC/C,IAAM,WAAW,GAAG,KAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAE1D,IAAI,MAAM,CAAC,OAAO,IAAI,oBAAoB,EAAE;gBAC1C,IAAM,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;gBACtC,oBAAoB,CAAC,KAAK,CAAC,wEAAwE,EAAE;oBACnG,WAAW,aAAA;oBACX,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE;oBAClC,EAAE,EAAE,EAAE,IAAI,SAAS;iBACpB,CAAC,CAAC;aACJ;YAED,IAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAClC,MAAA,KAAI,CAAC,iBAAiB,0CAAE,eAAe,CAAC,kCAAkC,EAAE,OAAO,GAAG,SAAS,CAAC,CAAC;YAEjG,OAAO,WAAW,CAAC;QACrB,CAAC,CAAC;QAEF;;;;;;WAMG;QACH,yBAAoB,GAAG,UAAC,MAA2C,EAAE,MAA8B;YACjG,IAAI,MAAM,EAAE;gBACV,oBAAoB,GAAG,MAAM,CAAC;aAC/B;YAED,IAAM,QAAQ,GAAG,qBAAqB,CAAC,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,SAAS,EAAE,MAAM,CAAC,CAAC;YACpE,IAAM,MAAM,GAAG,uBAAuB,EAAE,CAAC;YACzC,IAAM,eAAe,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC;YAEnD,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;YAE9B,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,CAAC,wEAAwE,EAAE;gBACtF,OAAO,EAAE,QAAQ,CAAC,OAAO;gBACzB,UAAU,EAAE,eAAe;gBAC3B,OAAO,EAAE,eAAe,KAAK,QAAQ,CAAC,OAAO;gBAC7C,yBAAyB,EAAE,QAAQ,CAAC,yBAAyB;gBAC7D,2BAA2B,EAAE,QAAQ,CAAC,uBAAuB,CAAC,MAAM;gBACpE,yBAAyB,EAAE,QAAQ,CAAC,qBAAqB,CAAC,MAAM;gBAChE,oBAAoB,EAAE,QAAQ,CAAC,oBAAoB;aACpD,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,gEAAgE;QAChE,uBAAkB,GAAG,UAAC,UAAsB,EAAE,OAAgB,EAAE,mBAA2B;;;YACzF,0BAA0B;YAC1B,IAAM,GAAG,GAAG,MAAA,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,0CAAE,WAAW,kDAAI,CAAC;YAC9C,0BAA0B;YAC1B,IAAM,IAAI,GACR,OAAO,OAAO,CAAC,qBAAqB,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;YAEpH,IAAM,SAAS,GAAG,KAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YAC7C,IAAM,wBAAwB,GAAG,MAAA,SAAS,CAAC,CAAC,CAAC,0CAAE,KAAK,CAAC;YACrD,IAAM,YAAY,GAAG,KAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YACnD,IAAM,UAAU,GAAG,yBAAyB,CAAC,wBAAwB,aAAxB,wBAAwB,cAAxB,wBAAwB,GAAI,EAAE,EAAE,mBAAmB,CAAC,CAAC;YAElG,0BAA0B;YAC1B,IAAM,UAAU;gBACd,GAAC,SAAS,CAAC,sCAAsC,IAAG,SAAS;gBAC7D,GAAC,SAAS,CAAC,gCAAgC,IAAG,GAAG;gBACjD,GAAC,SAAS,CAAC,iCAAiC,IAAG,KAAI,CAAC,OAAO,CAAC,OAAO,CAAC;gBACpE,GAAC,SAAS,CAAC,0CAA0C,IAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;gBACxG,GAAC,SAAS,CAAC,yCAAyC,IAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;gBACrG,GAAC,SAAS,CAAC,uCAAuC,IAAG,UAAU;gBAC/D,GAAC,SAAS,CAAC,iCAAiC,IAAG,KAAI,CAAC,cAAc,CAAC,OAAO,CAAC;gBAC3E,GAAC,SAAS,CAAC,yCAAyC,IAAG,YAAY;gBACnE,GAAC,SAAS,CAAC,6BAA6B,IAAG,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC3F,GAAC,SAAS,CAAC,+BAA+B,IACxC,YACD,CAAC,KAAI,CAAC,sBAAsB,CAAC;gBAC9B,GAAC,SAAS,CAAC,oCAAoC,IAAG,MAAM,CAAC,WAAW;gBACpE,GAAC,SAAS,CAAC,mCAAmC,IAAG,MAAM,CAAC,UAAU;mBACnE,CAAC;YAEF,IAAM,UAAU,GAAG,oBAAoB,EAAE,CAAC;YAC1C,0BAA0B;YAC1B,IAAI,UAAU,EAAE;gBACd,0BAA0B;gBAC1B,UAAU,CAAC,SAAS,CAAC,iCAAiC,CAAC,GAAG,UAAU,CAAC;aACtE;YAED,2CAA2C;YAC3C,UAAU,CAAC,SAAS,CAAC,+BAA+B,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAEzF,8CAA8C;YAC9C,UAAU,CAAC,SAAS,CAAC,kCAAkC,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YAEzF,UAAU,CAAC,SAAS,CAAC,uCAAuC,CAAC,GAAG,wBAAwB,aAAxB,wBAAwB,uBAAxB,wBAAwB,CAAG,YAAY,CAAC,CAAC;YAEzG,IAAI,GAAG,KAAK,GAAG,IAAI,UAAU,KAAK,OAAO,IAAI,OAAO,YAAY,iBAAiB,EAAE;gBACjF,IAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,oBAAoB,CAAC,CAAC;gBACvE,UAAU,CAAC,SAAS,CAAC,iCAAiC,CAAC,GAAG,KAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAAC,6EAA6E;aAC3K;YAED,OAAO,qBAAqB,CAAC,UAAU,CAAC,CAAC;QAC3C,CAAC,CAAC;QAEF,wBAAmB,GAAG,UACpB,KAAQ,EACR,IAA+E;YAE/E,OAAO;gBACL,KAAK,OAAA;gBACL,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;gBACrB,IAAI,MAAA;aACL,CAAC;QACJ,CAAC,CAAC;QAEF,iCAA4B,GAAG,UAC7B,KAAQ,EACR,IAAiC,EACjC,iBAA2B,EAC3B,mBAA2B;QAC3B,iFAAiF;QACjF,8EAA8E;QAC9E,+CAA+C;QAC/C,wBAAgC;YAAhC,yCAAA,EAAA,gCAAgC;YAEhC,IAAM,SAAS,GAAG,KAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAExD,IAAI,mBAAmB,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,MAAM,KAAK,IAAI,EAAE;gBACrE,IAAI,wBAAwB,EAAE;oBAC5B,IAAM,eAAe,GAAG,sBAAsB,CAAC,SAAS,CAAC,KAAK,CAAC,MAAiB,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;oBAClG,IAAI,eAAe,EAAE;wBACnB,SAAS,CAAC,sBAAsB,GAAG,SAAS,CAAC,KAAK,CAAC,MAAqB,CAAC;wBACzE,SAAS,CAAC,uBAAuB,GAAG,KAAI,CAAC,kBAAkB,CACzD,SAAS,CAAC,IAAI,EACd,SAAS,CAAC,sBAAsB,EAChC,mBAAmB,CACpB,CAAC;wBACF,OAAO,SAAS,CAAC;qBAClB;iBACF;gBACD,+DAA+D;gBAC/D,IAAM,sBAAsB,GAAG,iBAAiB,CAAC,SAAS,CAAC,KAAK,CAAC,MAAqB,EAAE,iBAAiB,CAAC,CAAC;gBAC3G,IAAI,sBAAsB,EAAE;oBAC1B,SAAS,CAAC,sBAAsB,GAAG,sBAAsB,CAAC;oBAC1D,SAAS,CAAC,uBAAuB,GAAG,KAAI,CAAC,kBAAkB,CACzD,SAAS,CAAC,IAAI,EACd,sBAAsB,EACtB,mBAAmB,CACpB,CAAC;iBACH;gBACD,OAAO,SAAS,CAAC;aAClB;YAED,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC;QAEF,8BAAyB,GAAG,UAAC,UAAsB,EAAE,cAA2B;YAC9E,2BAA2B;YAC3B,IAAI,UAAU,CAAC,UAAU,KAAK,aAAa,EAAE;gBAC3C,IAAM,aAAa,GAAG,aAAa,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;gBAChE,IAAI,CAAC,aAAa,EAAE;oBAClB,OAAO,SAAS,CAAC;iBAClB;gBAED,IAAI,UAAU,CAAC,kBAAkB,KAAK,MAAM,EAAE;oBAC5C,OAAO,KAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;iBACpC;qBAAM,IAAI,UAAU,CAAC,kBAAkB,KAAK,WAAW,IAAI,UAAU,CAAC,SAAS,EAAE;oBAChF,OAAO,aAAa,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;iBACzD;gBACD,OAAO,SAAS,CAAC;aAClB;YAED,wCAAwC;YACxC,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC;QAEF,2FAA2F;QAC3F,sEAAsE;QAC9D,iCAA4B,GAAG,UAAC,OAAgB;;YACtD,IAAM,cAAc,GAAG,WAAI,mBAAmB,yBAAsB,CAAC;YACrE,6EAA6E;YAC7E,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,cAAc,CAAC,EAAE;gBAC1C,OAAQ,OAAuB,CAAC,SAAS,CAAC;aAC3C;YAED,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;;gBAClD,KAAwB,IAAA,eAAA,SAAA,UAAU,CAAA,sCAAA,8DAAE;oBAA/B,IAAM,SAAS,uBAAA;oBAClB,IAAI,SAAS,CAAC,QAAQ,KAAK,IAAI,CAAC,SAAS,EAAE;wBACzC,MAAM,IAAI,SAAS,CAAC,WAAW,IAAI,EAAE,CAAC;wBACtC,SAAS;qBACV;oBAED,IAAI,CAAC,CAAC,SAAS,YAAY,OAAO,CAAC,EAAE;wBACnC,SAAS;qBACV;oBAED,sEAAsE;oBACtE,IAAI,SAAS,CAAC,YAAY,CAAC,mBAAmB,CAAC,IAAI,SAAS,CAAC,YAAY,CAAC,iBAAiB,CAAC,EAAE;wBAC5F,MAAM,IAAI,iBAAiB,CAAC;wBAC5B,SAAS;qBACV;oBACD,MAAM,IAAI,KAAI,CAAC,4BAA4B,CAAC,SAAS,CAAC,CAAC;iBACxD;;;;;;;;;YACD,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC;QAEF,YAAO,GAAG,UAAC,OAAgB;YACzB,6DAA6D;YAC7D,IAAM,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,WAAI,mBAAmB,MAAG,CAAC,KAAK,IAAI,CAAC;YAC9E,IAAI,gBAAgB,EAAE;gBACpB,OAAO,iBAAiB,CAAC;aAC1B;YACD,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,WAAI,mBAAmB,yBAAsB,CAAC,EAAE;gBACzE,MAAM,GAAI,OAAuB,CAAC,SAAS,IAAI,EAAE,CAAC;aACnD;iBAAM;gBACL,MAAM,GAAG,KAAI,CAAC,4BAA4B,CAAC,OAAO,CAAC,CAAC;aACrD;YACD,OAAO,KAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3F,CAAC,CAAC;QAEF,2EAA2E;QAC3E,qBAAgB,GAAG,UAAC,OAAgB;;;YAClC,IAAI,CAAC,OAAO,EAAE;gBACZ,OAAO,EAAE,CAAC;aACX;YACD,0BAA0B;YAC1B,IAAM,GAAG,GAAG,MAAA,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,0CAAE,WAAW,kDAAI,CAAC;YAE9C,IAAM,UAAU;gBACd,GAAC,SAAS,CAAC,gCAAgC,IAAG,GAAG;gBACjD,GAAC,SAAS,CAAC,iCAAiC,IAAG,KAAI,CAAC,OAAO,CAAC,OAAO,CAAC;gBACpE,GAAC,SAAS,CAAC,6BAA6B,IAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;mBAC9E,CAAC;YACF,OAAO,qBAAqB,CAAC,UAAU,CAA8B,CAAC;QACxE,CAAC,CAAC;QAjVA,IAAI,CAAC,iBAAiB,GAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,iBAAiB,CAAC;QACpD,IAAI,CAAC,cAAc,GAAG,uBAAuB,EAAE,CAAC;QAEhD,IAAM,WAAW,GAAG,MAAA,OAAO,CAAC,aAAa,mCAAI,EAAE,CAAC;QAEhD,IAAM,QAAQ,GAAa,EAAE,CAAC;;YAC9B,KAAoB,IAAA,gBAAA,SAAA,WAAW,CAAA,wCAAA,iEAAE;gBAA5B,IAAM,KAAK,wBAAA;gBACd,IAAI,QAAQ,CAAC,MAAM,IAAI,SAAS,CAAC,sBAAsB,EAAE;oBACvD,MAAM;iBACP;gBACD,IAAI,KAAK,YAAY,MAAM,EAAE;oBAC3B,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;iBACtB;qBAAM,IAAI,SAAS,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,EAAE;oBAClE,IAAI;wBACF,QAAQ,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;qBAC/C;oBAAC,WAAM;wBACN,iCAAiC;qBAClC;iBACF;aACF;;;;;;;;;QACD,IAAI,CAAC,0BAA0B,GAAG,QAAQ,CAAC;IAC7C,CAAC;IA6TH,oBAAC;AAAD,CAAC,AAtWD,IAsWC","sourcesContent":["/* eslint-disable no-restricted-globals */\nimport {\n ElementInteractionsOptions,\n ActionType,\n getDecodeURI,\n IDiagnosticsClient,\n MASKED_TEXT_VALUE,\n TEXT_MASK_ATTRIBUTE,\n getPageTitle,\n replaceSensitiveString,\n} from '@amplitude/analytics-core';\nimport type { DataSource } from '@amplitude/analytics-core/lib/esm/types/element-interactions';\nimport * as constants from './constants';\nimport {\n removeEmptyProperties,\n extractPrefixedAttributes,\n isElementPointerCursor,\n getClosestElement,\n isElementBasedEvent,\n parseAttributesToMask,\n getCurrentPageViewId,\n} from './helpers';\nimport type { BaseTimestampedEvent, ElementBasedTimestampedEvent, TimestampedEvent, JSONValue } from './helpers';\nimport { getAncestors, getElementProperties } from './hierarchy';\nimport { getDataSource } from './pageActions/actions';\nimport { Hierarchy } from './typings/autocapture';\nimport {\n createSelectorEngine,\n resolveSelectorConfig,\n type SelectorEngine,\n type ElementSelectorRemoteConfig,\n type ElementSelectorLogger,\n} from '@amplitude/element-selector';\n\n/**\n * Module-level shared selector engine singleton. Both autocapture-plugin and\n * frustration-plugin create separate DataExtractor instances, and each\n * subscribes to remote config independently. By sharing a single engine across\n * all extractors, whichever subscription fires first updates the engine for\n * everyone, eliminating the window where one plugin could see updated config\n * while the other still uses defaults.\n */\nlet sharedSelectorEngine: SelectorEngine | undefined;\nlet sharedSelectorLogger: ElementSelectorLogger | undefined;\n\nfunction getSharedSelectorEngine(): SelectorEngine {\n if (!sharedSelectorEngine) {\n sharedSelectorEngine = createSelectorEngine(resolveSelectorConfig(), { logger: sharedSelectorLogger });\n }\n return sharedSelectorEngine;\n}\n\nexport class DataExtractor {\n private readonly additionalMaskTextPatterns: RegExp[];\n diagnosticsClient?: IDiagnosticsClient;\n\n /**\n * Shared element-selector engine. This is the single place autocapture turns\n * an element into a selector string ({@link getElementPath}), so it's the\n * seam where the legacy `cssPath` walker is swapped for the configurable\n * engine. It ships dormant: with the default config (`enabled: false`) the\n * engine routes through the byte-identical legacy walker, so behavior is\n * unchanged until remote config flips an org onto the new algorithm via\n * {@link updateSelectorConfig}.\n *\n * The engine is shared across all DataExtractor instances to ensure\n * consistent selector output when both autocapture-plugin and\n * frustration-plugin are active.\n */\n private readonly selectorEngine: SelectorEngine;\n\n constructor(options: ElementInteractionsOptions, context?: { diagnosticsClient: IDiagnosticsClient }) {\n this.diagnosticsClient = context?.diagnosticsClient;\n this.selectorEngine = getSharedSelectorEngine();\n\n const rawPatterns = options.maskTextRegex ?? [];\n\n const compiled: RegExp[] = [];\n for (const entry of rawPatterns) {\n if (compiled.length >= constants.MAX_MASK_TEXT_PATTERNS) {\n break;\n }\n if (entry instanceof RegExp) {\n compiled.push(entry);\n } else if ('pattern' in entry && typeof entry.pattern === 'string') {\n try {\n compiled.push(new RegExp(entry.pattern, 'i'));\n } catch {\n // ignore invalid pattern strings\n }\n }\n }\n this.additionalMaskTextPatterns = compiled;\n }\n\n /**\n * Wrapper method to replace sensitive strings using the helper function\n * @param text - The text to search for sensitive data\n * @returns The text with sensitive data replaced by masked text\n */\n replaceSensitiveString = (text: string | null): string => {\n return replaceSensitiveString(text, this.additionalMaskTextPatterns);\n };\n\n // Get the DOM hierarchy of the element, starting from the target element to the root element.\n getHierarchy = (element: Element | null): Hierarchy => {\n const startTime = performance.now();\n\n let hierarchy: Hierarchy = [];\n if (!element) {\n return [];\n }\n\n // Get list of ancestors including itself and get properties at each level in the hierarchy\n const ancestors = getAncestors(element);\n\n // Build attributes to mask map\n const elementToAttributesToMaskMap = new Map<Element, Set<string>>();\n\n for (let i = ancestors.length - 1; i >= 0; i--) {\n const node = ancestors[i];\n if (node) {\n const attributesToMask = parseAttributesToMask(node.getAttribute(constants.DATA_AMP_MASK_ATTRIBUTES));\n const ancestorAttributesToMask =\n i === ancestors.length - 1 ? [] : elementToAttributesToMaskMap.get(ancestors[i + 1]) ?? new Set<string>();\n const combinedAttributesToMask = new Set([...ancestorAttributesToMask, ...attributesToMask]);\n elementToAttributesToMaskMap.set(node, combinedAttributesToMask);\n }\n }\n\n hierarchy = ancestors.map((el) =>\n getElementProperties(el, elementToAttributesToMaskMap.get(el) ?? new Set<string>()),\n );\n\n // Search for and mask any sensitive attribute values\n for (const hierarchyNode of hierarchy) {\n if (hierarchyNode?.attrs) {\n Object.entries(hierarchyNode.attrs).forEach(([key, value]) => {\n if (hierarchyNode.attrs) {\n hierarchyNode.attrs[key] = this.replaceSensitiveString(value);\n }\n });\n }\n }\n\n const endTime = performance.now();\n this.diagnosticsClient?.recordHistogram('autocapturePlugin.getHierarchy', endTime - startTime);\n\n return hierarchy;\n };\n\n getNearestLabel = (element: Element): string => {\n const parent = element.parentElement;\n if (!parent) {\n return '';\n }\n let labelElement: Element | null;\n try {\n labelElement = parent.querySelector(':scope>span,h1,h2,h3,h4,h5,h6');\n } catch {\n /* istanbul ignore next */\n labelElement = null;\n }\n if (labelElement) {\n /* istanbul ignore next */\n return this.getText(labelElement);\n }\n return this.getNearestLabel(parent);\n };\n\n getElementPath = (element: Element | null): string => {\n if (!element) {\n return '';\n }\n const startTime = performance.now();\n\n const config = this.selectorEngine.getConfig();\n const elementPath = this.selectorEngine.generate(element);\n\n if (config.enabled && sharedSelectorLogger) {\n const id = element.getAttribute('id');\n sharedSelectorLogger.debug('@amplitude/plugin-autocapture-browser: element-selector engine enabled', {\n elementPath,\n tag: element.tagName.toLowerCase(),\n id: id || undefined,\n });\n }\n\n const endTime = performance.now();\n this.diagnosticsClient?.recordHistogram('autocapturePlugin.getElementPath', endTime - startTime);\n\n return elementPath;\n };\n\n /**\n * Apply an element-selector remote-config payload to the engine. Called from\n * plugin setup when remote config is delivered. Resolving an absent/empty\n * payload yields the documented defaults (engine stays dormant on legacy\n * `cssPath`); flipping `enabled: true` switches {@link getElementPath} onto\n * the new strategy-based selector output.\n */\n updateSelectorConfig = (remote?: ElementSelectorRemoteConfig | null, logger?: ElementSelectorLogger): void => {\n if (logger) {\n sharedSelectorLogger = logger;\n }\n\n const resolved = resolveSelectorConfig(remote ?? undefined, logger);\n const engine = getSharedSelectorEngine();\n const previousEnabled = engine.getConfig().enabled;\n\n engine.updateConfig(resolved);\n\n logger?.debug('@amplitude/plugin-autocapture-browser: element-selector config updated', {\n enabled: resolved.enabled,\n wasEnabled: previousEnabled,\n toggled: previousEnabled !== resolved.enabled,\n explicitTrackingAttribute: resolved.explicitTrackingAttribute,\n autogeneratedIdPatternCount: resolved.autogeneratedIdPatterns.length,\n unstableClassPatternCount: resolved.unstableClassPatterns.length,\n maxAncestorWalkDepth: resolved.maxAncestorWalkDepth,\n });\n };\n\n // Returns the Amplitude event properties for the given element.\n getEventProperties = (actionType: ActionType, element: Element, dataAttributePrefix: string) => {\n /* istanbul ignore next */\n const tag = element?.tagName?.toLowerCase?.();\n /* istanbul ignore next */\n const rect =\n typeof element.getBoundingClientRect === 'function' ? element.getBoundingClientRect() : { left: null, top: null };\n\n const hierarchy = this.getHierarchy(element);\n const currentElementAttributes = hierarchy[0]?.attrs;\n const nearestLabel = this.getNearestLabel(element);\n const attributes = extractPrefixedAttributes(currentElementAttributes ?? {}, dataAttributePrefix);\n\n /* istanbul ignore next */\n const properties: Record<string, any> = {\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_HIERARCHY]: hierarchy,\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_TAG]: tag,\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_TEXT]: this.getText(element),\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_POSITION_LEFT]: rect.left == null ? null : Math.round(rect.left),\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_POSITION_TOP]: rect.top == null ? null : Math.round(rect.top),\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_ATTRIBUTES]: attributes,\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_PATH]: this.getElementPath(element),\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_PARENT_LABEL]: nearestLabel,\n [constants.AMPLITUDE_EVENT_PROP_PAGE_URL]: getDecodeURI(window.location.href.split('?')[0]),\n [constants.AMPLITUDE_EVENT_PROP_PAGE_TITLE]: (\n getPageTitle as (parseTitleFunction: (title: string) => string) => string\n )(this.replaceSensitiveString),\n [constants.AMPLITUDE_EVENT_PROP_VIEWPORT_HEIGHT]: window.innerHeight,\n [constants.AMPLITUDE_EVENT_PROP_VIEWPORT_WIDTH]: window.innerWidth,\n };\n\n const pageViewId = getCurrentPageViewId();\n /* istanbul ignore next */\n if (pageViewId) {\n /* istanbul ignore next */\n properties[constants.AMPLITUDE_EVENT_PROP_PAGE_VIEW_ID] = pageViewId;\n }\n\n // id is never masked, so always include it\n properties[constants.AMPLITUDE_EVENT_PROP_ELEMENT_ID] = element.getAttribute('id') || '';\n\n // class is never masked, so always include it\n properties[constants.AMPLITUDE_EVENT_PROP_ELEMENT_CLASS] = element.getAttribute('class');\n\n properties[constants.AMPLITUDE_EVENT_PROP_ELEMENT_ARIA_LABEL] = currentElementAttributes?.['aria-label'];\n\n if (tag === 'a' && actionType === 'click' && element instanceof HTMLAnchorElement) {\n const href = element.href.substring(0, constants.MAX_ATTRIBUTE_LENGTH);\n properties[constants.AMPLITUDE_EVENT_PROP_ELEMENT_HREF] = this.replaceSensitiveString(href); // we don't use hierarchy here because we don't want href value to be changed\n }\n\n return removeEmptyProperties(properties);\n };\n\n addTypeAndTimestamp = <T>(\n event: T,\n type: BaseTimestampedEvent<T>['type'] | ElementBasedTimestampedEvent<T>['type'],\n ): BaseTimestampedEvent<T> | ElementBasedTimestampedEvent<T> => {\n return {\n event,\n timestamp: Date.now(),\n type,\n };\n };\n\n addAdditionalEventProperties = <T>(\n event: T,\n type: TimestampedEvent<T>['type'],\n selectorAllowlist: string[],\n dataAttributePrefix: string,\n // capture the event if the cursor is a \"pointer\" when this element is clicked on\n // reason: a \"pointer\" cursor indicates that an element should be interactable\n // regardless of the element's tag name\n isCapturingCursorPointer = false,\n ): TimestampedEvent<T> | ElementBasedTimestampedEvent<T> => {\n const baseEvent = this.addTypeAndTimestamp(event, type);\n\n if (isElementBasedEvent(baseEvent) && baseEvent.event.target !== null) {\n if (isCapturingCursorPointer) {\n const isCursorPointer = isElementPointerCursor(baseEvent.event.target as Element, baseEvent.type);\n if (isCursorPointer) {\n baseEvent.closestTrackedAncestor = baseEvent.event.target as HTMLElement;\n baseEvent.targetElementProperties = this.getEventProperties(\n baseEvent.type,\n baseEvent.closestTrackedAncestor,\n dataAttributePrefix,\n );\n return baseEvent;\n }\n }\n // Retrieve additional event properties from the target element\n const closestTrackedAncestor = getClosestElement(baseEvent.event.target as HTMLElement, selectorAllowlist);\n if (closestTrackedAncestor) {\n baseEvent.closestTrackedAncestor = closestTrackedAncestor;\n baseEvent.targetElementProperties = this.getEventProperties(\n baseEvent.type,\n closestTrackedAncestor,\n dataAttributePrefix,\n );\n }\n return baseEvent;\n }\n\n return baseEvent;\n };\n\n extractDataFromDataSource = (dataSource: DataSource, contextElement: HTMLElement) => {\n // Extract from DOM Element\n if (dataSource.sourceType === 'DOM_ELEMENT') {\n const sourceElement = getDataSource(dataSource, contextElement);\n if (!sourceElement) {\n return undefined;\n }\n\n if (dataSource.elementExtractType === 'TEXT') {\n return this.getText(sourceElement);\n } else if (dataSource.elementExtractType === 'ATTRIBUTE' && dataSource.attribute) {\n return sourceElement.getAttribute(dataSource.attribute);\n }\n return undefined;\n }\n\n // TODO: Extract from other source types\n return undefined;\n };\n\n // Traverse text content without cloning DOM nodes, which avoids media/network side effects\n // from recreating nested elements such as <video>, <audio>, or <img>.\n private getTextWithMaskedDescendants = (element: Element): string => {\n const maskedSelector = `[${TEXT_MASK_ATTRIBUTE}], [contenteditable]`;\n // Fast path: if no masked descendants exist, rely on native text extraction.\n if (!element.querySelector(maskedSelector)) {\n return (element as HTMLElement).innerText;\n }\n\n let output = '';\n const childNodes = Array.from(element.childNodes);\n for (const childNode of childNodes) {\n if (childNode.nodeType === Node.TEXT_NODE) {\n output += childNode.textContent || '';\n continue;\n }\n\n if (!(childNode instanceof Element)) {\n continue;\n }\n\n // Replace entire masked/contenteditable subtrees with the mask token.\n if (childNode.hasAttribute(TEXT_MASK_ATTRIBUTE) || childNode.hasAttribute('contenteditable')) {\n output += MASKED_TEXT_VALUE;\n continue;\n }\n output += this.getTextWithMaskedDescendants(childNode);\n }\n return output;\n };\n\n getText = (element: Element): string => {\n // Check if element or any parent has data-amp-mask attribute\n const hasMaskAttribute = element.closest(`[${TEXT_MASK_ATTRIBUTE}]`) !== null;\n if (hasMaskAttribute) {\n return MASKED_TEXT_VALUE;\n }\n let output = '';\n if (!element.querySelector(`[${TEXT_MASK_ATTRIBUTE}], [contenteditable]`)) {\n output = (element as HTMLElement).innerText || '';\n } else {\n output = this.getTextWithMaskedDescendants(element);\n }\n return this.replaceSensitiveString(output.substring(0, 255)).replace(/\\s+/g, ' ').trim();\n };\n\n // Returns the element properties for the given element in Visual Labeling.\n getEventTagProps = (element: Element): Record<string, JSONValue> => {\n if (!element) {\n return {};\n }\n /* istanbul ignore next */\n const tag = element?.tagName?.toLowerCase?.();\n\n const properties = {\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_TAG]: tag,\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_TEXT]: this.getText(element),\n [constants.AMPLITUDE_EVENT_PROP_PAGE_URL]: window.location.href.split('?')[0],\n };\n return removeEmptyProperties(properties) as Record<string, JSONValue>;\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"data-extractor.js","sourceRoot":"","sources":["../../src/data-extractor.ts"],"names":[],"mappings":";AAAA,0CAA0C;AAC1C,OAAO,EAGL,YAAY,EAEZ,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,sBAAsB,GACvB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,KAAK,SAAS,MAAM,aAAa,CAAC;AACzC,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,OAAO,EACL,oBAAoB,EACpB,qBAAqB,GAItB,MAAM,6BAA6B,CAAC;AAErC;;;;;;;GAOG;AACH,IAAI,oBAAgD,CAAC;AAErD,SAAS,uBAAuB;IAC9B,IAAI,CAAC,oBAAoB,EAAE;QACzB,oBAAoB,GAAG,oBAAoB,CAAC,qBAAqB,EAAE,CAAC,CAAC;KACtE;IACD,OAAO,oBAAoB,CAAC;AAC9B,CAAC;AAED;IAmBE,uBAAY,OAAmC,EAAE,OAAmD;;QAApG,iBAsBC;;QAED;;;;WAIG;QACH,2BAAsB,GAAG,UAAC,IAAmB;YAC3C,OAAO,sBAAsB,CAAC,IAAI,EAAE,KAAI,CAAC,0BAA0B,CAAC,CAAC;QACvE,CAAC,CAAC;QAEF,8FAA8F;QAC9F,iBAAY,GAAG,UAAC,OAAuB;;;YACrC,IAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAEpC,IAAI,SAAS,GAAc,EAAE,CAAC;YAC9B,IAAI,CAAC,OAAO,EAAE;gBACZ,OAAO,EAAE,CAAC;aACX;YAED,2FAA2F;YAC3F,IAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;YAExC,+BAA+B;YAC/B,IAAM,4BAA4B,GAAG,IAAI,GAAG,EAAwB,CAAC;YAErE,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;gBAC9C,IAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;gBAC1B,IAAI,IAAI,EAAE;oBACR,IAAM,gBAAgB,GAAG,qBAAqB,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC,CAAC;oBACtG,IAAM,wBAAwB,GAC5B,CAAC,KAAK,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAA,4BAA4B,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,mCAAI,IAAI,GAAG,EAAU,CAAC;oBAC5G,IAAM,wBAAwB,GAAG,IAAI,GAAG,wCAAK,wBAAwB,kBAAK,gBAAgB,UAAE,CAAC;oBAC7F,4BAA4B,CAAC,GAAG,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAAC;iBAClE;aACF;YAED,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,UAAC,EAAE,YAC3B,OAAA,oBAAoB,CAAC,EAAE,EAAE,MAAA,4BAA4B,CAAC,GAAG,CAAC,EAAE,CAAC,mCAAI,IAAI,GAAG,EAAU,CAAC,CAAA,EAAA,CACpF,CAAC;oCAGS,aAAa;gBACtB,IAAI,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,KAAK,EAAE;oBACxB,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,UAAC,EAAY;4BAAZ,KAAA,aAAY,EAAX,GAAG,QAAA,EAAE,KAAK,QAAA;wBACtD,IAAI,aAAa,CAAC,KAAK,EAAE;4BACvB,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,KAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;yBAC/D;oBACH,CAAC,CAAC,CAAC;iBACJ;;;gBARH,qDAAqD;gBACrD,KAA4B,IAAA,cAAA,SAAA,SAAS,CAAA,oCAAA;oBAAhC,IAAM,aAAa,sBAAA;4BAAb,aAAa;iBAQvB;;;;;;;;;YAED,IAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAClC,MAAA,KAAI,CAAC,iBAAiB,0CAAE,eAAe,CAAC,gCAAgC,EAAE,OAAO,GAAG,SAAS,CAAC,CAAC;YAE/F,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC;QAEF,oBAAe,GAAG,UAAC,OAAgB;YACjC,IAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;YACrC,IAAI,CAAC,MAAM,EAAE;gBACX,OAAO,EAAE,CAAC;aACX;YACD,IAAI,YAA4B,CAAC;YACjC,IAAI;gBACF,YAAY,GAAG,MAAM,CAAC,aAAa,CAAC,+BAA+B,CAAC,CAAC;aACtE;YAAC,WAAM;gBACN,0BAA0B;gBAC1B,YAAY,GAAG,IAAI,CAAC;aACrB;YACD,IAAI,YAAY,EAAE;gBAChB,0BAA0B;gBAC1B,OAAO,KAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;aACnC;YACD,OAAO,KAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QACtC,CAAC,CAAC;QAEF,mBAAc,GAAG,UAAC,OAAuB;;YACvC,IAAI,CAAC,OAAO,EAAE;gBACZ,OAAO,EAAE,CAAC;aACX;YACD,IAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAEpC,IAAM,WAAW,GAAG,KAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAE1D,IAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAClC,MAAA,KAAI,CAAC,iBAAiB,0CAAE,eAAe,CAAC,kCAAkC,EAAE,OAAO,GAAG,SAAS,CAAC,CAAC;YAEjG,OAAO,WAAW,CAAC;QACrB,CAAC,CAAC;QAEF;;;;;;WAMG;QACH,yBAAoB,GAAG,UAAC,MAA2C,EAAE,MAA8B;YACjG,KAAI,CAAC,cAAc,CAAC,YAAY,CAAC,qBAAqB,CAAC,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;QACvF,CAAC,CAAC;QAEF,gEAAgE;QAChE,uBAAkB,GAAG,UAAC,UAAsB,EAAE,OAAgB,EAAE,mBAA2B;;;YACzF,0BAA0B;YAC1B,IAAM,GAAG,GAAG,MAAA,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,0CAAE,WAAW,kDAAI,CAAC;YAC9C,0BAA0B;YAC1B,IAAM,IAAI,GACR,OAAO,OAAO,CAAC,qBAAqB,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;YAEpH,IAAM,SAAS,GAAG,KAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YAC7C,IAAM,wBAAwB,GAAG,MAAA,SAAS,CAAC,CAAC,CAAC,0CAAE,KAAK,CAAC;YACrD,IAAM,YAAY,GAAG,KAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YACnD,IAAM,UAAU,GAAG,yBAAyB,CAAC,wBAAwB,aAAxB,wBAAwB,cAAxB,wBAAwB,GAAI,EAAE,EAAE,mBAAmB,CAAC,CAAC;YAElG,0BAA0B;YAC1B,IAAM,UAAU;gBACd,GAAC,SAAS,CAAC,sCAAsC,IAAG,SAAS;gBAC7D,GAAC,SAAS,CAAC,gCAAgC,IAAG,GAAG;gBACjD,GAAC,SAAS,CAAC,iCAAiC,IAAG,KAAI,CAAC,OAAO,CAAC,OAAO,CAAC;gBACpE,GAAC,SAAS,CAAC,0CAA0C,IAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;gBACxG,GAAC,SAAS,CAAC,yCAAyC,IAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;gBACrG,GAAC,SAAS,CAAC,uCAAuC,IAAG,UAAU;gBAC/D,GAAC,SAAS,CAAC,iCAAiC,IAAG,KAAI,CAAC,cAAc,CAAC,OAAO,CAAC;gBAC3E,GAAC,SAAS,CAAC,yCAAyC,IAAG,YAAY;gBACnE,GAAC,SAAS,CAAC,6BAA6B,IAAG,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC3F,GAAC,SAAS,CAAC,+BAA+B,IACxC,YACD,CAAC,KAAI,CAAC,sBAAsB,CAAC;gBAC9B,GAAC,SAAS,CAAC,oCAAoC,IAAG,MAAM,CAAC,WAAW;gBACpE,GAAC,SAAS,CAAC,mCAAmC,IAAG,MAAM,CAAC,UAAU;mBACnE,CAAC;YAEF,IAAM,UAAU,GAAG,oBAAoB,EAAE,CAAC;YAC1C,0BAA0B;YAC1B,IAAI,UAAU,EAAE;gBACd,0BAA0B;gBAC1B,UAAU,CAAC,SAAS,CAAC,iCAAiC,CAAC,GAAG,UAAU,CAAC;aACtE;YAED,2CAA2C;YAC3C,UAAU,CAAC,SAAS,CAAC,+BAA+B,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAEzF,8CAA8C;YAC9C,UAAU,CAAC,SAAS,CAAC,kCAAkC,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YAEzF,UAAU,CAAC,SAAS,CAAC,uCAAuC,CAAC,GAAG,wBAAwB,aAAxB,wBAAwB,uBAAxB,wBAAwB,CAAG,YAAY,CAAC,CAAC;YAEzG,IAAI,GAAG,KAAK,GAAG,IAAI,UAAU,KAAK,OAAO,IAAI,OAAO,YAAY,iBAAiB,EAAE;gBACjF,IAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,oBAAoB,CAAC,CAAC;gBACvE,UAAU,CAAC,SAAS,CAAC,iCAAiC,CAAC,GAAG,KAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAAC,6EAA6E;aAC3K;YAED,OAAO,qBAAqB,CAAC,UAAU,CAAC,CAAC;QAC3C,CAAC,CAAC;QAEF,wBAAmB,GAAG,UACpB,KAAQ,EACR,IAA+E;YAE/E,OAAO;gBACL,KAAK,OAAA;gBACL,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;gBACrB,IAAI,MAAA;aACL,CAAC;QACJ,CAAC,CAAC;QAEF,iCAA4B,GAAG,UAC7B,KAAQ,EACR,IAAiC,EACjC,iBAA2B,EAC3B,mBAA2B;QAC3B,iFAAiF;QACjF,8EAA8E;QAC9E,+CAA+C;QAC/C,wBAAgC;YAAhC,yCAAA,EAAA,gCAAgC;YAEhC,IAAM,SAAS,GAAG,KAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAExD,IAAI,mBAAmB,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,MAAM,KAAK,IAAI,EAAE;gBACrE,IAAI,wBAAwB,EAAE;oBAC5B,IAAM,eAAe,GAAG,sBAAsB,CAAC,SAAS,CAAC,KAAK,CAAC,MAAiB,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;oBAClG,IAAI,eAAe,EAAE;wBACnB,SAAS,CAAC,sBAAsB,GAAG,SAAS,CAAC,KAAK,CAAC,MAAqB,CAAC;wBACzE,SAAS,CAAC,uBAAuB,GAAG,KAAI,CAAC,kBAAkB,CACzD,SAAS,CAAC,IAAI,EACd,SAAS,CAAC,sBAAsB,EAChC,mBAAmB,CACpB,CAAC;wBACF,OAAO,SAAS,CAAC;qBAClB;iBACF;gBACD,+DAA+D;gBAC/D,IAAM,sBAAsB,GAAG,iBAAiB,CAAC,SAAS,CAAC,KAAK,CAAC,MAAqB,EAAE,iBAAiB,CAAC,CAAC;gBAC3G,IAAI,sBAAsB,EAAE;oBAC1B,SAAS,CAAC,sBAAsB,GAAG,sBAAsB,CAAC;oBAC1D,SAAS,CAAC,uBAAuB,GAAG,KAAI,CAAC,kBAAkB,CACzD,SAAS,CAAC,IAAI,EACd,sBAAsB,EACtB,mBAAmB,CACpB,CAAC;iBACH;gBACD,OAAO,SAAS,CAAC;aAClB;YAED,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC;QAEF,8BAAyB,GAAG,UAAC,UAAsB,EAAE,cAA2B;YAC9E,2BAA2B;YAC3B,IAAI,UAAU,CAAC,UAAU,KAAK,aAAa,EAAE;gBAC3C,IAAM,aAAa,GAAG,aAAa,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;gBAChE,IAAI,CAAC,aAAa,EAAE;oBAClB,OAAO,SAAS,CAAC;iBAClB;gBAED,IAAI,UAAU,CAAC,kBAAkB,KAAK,MAAM,EAAE;oBAC5C,OAAO,KAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;iBACpC;qBAAM,IAAI,UAAU,CAAC,kBAAkB,KAAK,WAAW,IAAI,UAAU,CAAC,SAAS,EAAE;oBAChF,OAAO,aAAa,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;iBACzD;gBACD,OAAO,SAAS,CAAC;aAClB;YAED,wCAAwC;YACxC,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC;QAEF,2FAA2F;QAC3F,sEAAsE;QAC9D,iCAA4B,GAAG,UAAC,OAAgB;;YACtD,IAAM,cAAc,GAAG,WAAI,mBAAmB,yBAAsB,CAAC;YACrE,6EAA6E;YAC7E,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,cAAc,CAAC,EAAE;gBAC1C,OAAQ,OAAuB,CAAC,SAAS,CAAC;aAC3C;YAED,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;;gBAClD,KAAwB,IAAA,eAAA,SAAA,UAAU,CAAA,sCAAA,8DAAE;oBAA/B,IAAM,SAAS,uBAAA;oBAClB,IAAI,SAAS,CAAC,QAAQ,KAAK,IAAI,CAAC,SAAS,EAAE;wBACzC,MAAM,IAAI,SAAS,CAAC,WAAW,IAAI,EAAE,CAAC;wBACtC,SAAS;qBACV;oBAED,IAAI,CAAC,CAAC,SAAS,YAAY,OAAO,CAAC,EAAE;wBACnC,SAAS;qBACV;oBAED,sEAAsE;oBACtE,IAAI,SAAS,CAAC,YAAY,CAAC,mBAAmB,CAAC,IAAI,SAAS,CAAC,YAAY,CAAC,iBAAiB,CAAC,EAAE;wBAC5F,MAAM,IAAI,iBAAiB,CAAC;wBAC5B,SAAS;qBACV;oBACD,MAAM,IAAI,KAAI,CAAC,4BAA4B,CAAC,SAAS,CAAC,CAAC;iBACxD;;;;;;;;;YACD,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC;QAEF,YAAO,GAAG,UAAC,OAAgB;YACzB,6DAA6D;YAC7D,IAAM,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,WAAI,mBAAmB,MAAG,CAAC,KAAK,IAAI,CAAC;YAC9E,IAAI,gBAAgB,EAAE;gBACpB,OAAO,iBAAiB,CAAC;aAC1B;YACD,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,WAAI,mBAAmB,yBAAsB,CAAC,EAAE;gBACzE,MAAM,GAAI,OAAuB,CAAC,SAAS,IAAI,EAAE,CAAC;aACnD;iBAAM;gBACL,MAAM,GAAG,KAAI,CAAC,4BAA4B,CAAC,OAAO,CAAC,CAAC;aACrD;YACD,OAAO,KAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3F,CAAC,CAAC;QAEF,2EAA2E;QAC3E,qBAAgB,GAAG,UAAC,OAAgB;;;YAClC,IAAI,CAAC,OAAO,EAAE;gBACZ,OAAO,EAAE,CAAC;aACX;YACD,0BAA0B;YAC1B,IAAM,GAAG,GAAG,MAAA,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,0CAAE,WAAW,kDAAI,CAAC;YAE9C,IAAM,UAAU;gBACd,GAAC,SAAS,CAAC,gCAAgC,IAAG,GAAG;gBACjD,GAAC,SAAS,CAAC,iCAAiC,IAAG,KAAI,CAAC,OAAO,CAAC,OAAO,CAAC;gBACpE,GAAC,SAAS,CAAC,6BAA6B,IAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;mBAC9E,CAAC;YACF,OAAO,qBAAqB,CAAC,UAAU,CAA8B,CAAC;QACxE,CAAC,CAAC;QArTA,IAAI,CAAC,iBAAiB,GAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,iBAAiB,CAAC;QACpD,IAAI,CAAC,cAAc,GAAG,uBAAuB,EAAE,CAAC;QAEhD,IAAM,WAAW,GAAG,MAAA,OAAO,CAAC,aAAa,mCAAI,EAAE,CAAC;QAEhD,IAAM,QAAQ,GAAa,EAAE,CAAC;;YAC9B,KAAoB,IAAA,gBAAA,SAAA,WAAW,CAAA,wCAAA,iEAAE;gBAA5B,IAAM,KAAK,wBAAA;gBACd,IAAI,QAAQ,CAAC,MAAM,IAAI,SAAS,CAAC,sBAAsB,EAAE;oBACvD,MAAM;iBACP;gBACD,IAAI,KAAK,YAAY,MAAM,EAAE;oBAC3B,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;iBACtB;qBAAM,IAAI,SAAS,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,EAAE;oBAClE,IAAI;wBACF,QAAQ,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;qBAC/C;oBAAC,WAAM;wBACN,iCAAiC;qBAClC;iBACF;aACF;;;;;;;;;QACD,IAAI,CAAC,0BAA0B,GAAG,QAAQ,CAAC;IAC7C,CAAC;IAiSH,oBAAC;AAAD,CAAC,AA1UD,IA0UC","sourcesContent":["/* eslint-disable no-restricted-globals */\nimport {\n ElementInteractionsOptions,\n ActionType,\n getDecodeURI,\n IDiagnosticsClient,\n MASKED_TEXT_VALUE,\n TEXT_MASK_ATTRIBUTE,\n getPageTitle,\n replaceSensitiveString,\n} from '@amplitude/analytics-core';\nimport type { DataSource } from '@amplitude/analytics-core/lib/esm/types/element-interactions';\nimport * as constants from './constants';\nimport {\n removeEmptyProperties,\n extractPrefixedAttributes,\n isElementPointerCursor,\n getClosestElement,\n isElementBasedEvent,\n parseAttributesToMask,\n getCurrentPageViewId,\n} from './helpers';\nimport type { BaseTimestampedEvent, ElementBasedTimestampedEvent, TimestampedEvent, JSONValue } from './helpers';\nimport { getAncestors, getElementProperties } from './hierarchy';\nimport { getDataSource } from './pageActions/actions';\nimport { Hierarchy } from './typings/autocapture';\nimport {\n createSelectorEngine,\n resolveSelectorConfig,\n type SelectorEngine,\n type ElementSelectorRemoteConfig,\n type ElementSelectorLogger,\n} from '@amplitude/element-selector';\n\n/**\n * Module-level shared selector engine singleton. Both autocapture-plugin and\n * frustration-plugin create separate DataExtractor instances, and each\n * subscribes to remote config independently. By sharing a single engine across\n * all extractors, whichever subscription fires first updates the engine for\n * everyone, eliminating the window where one plugin could see updated config\n * while the other still uses defaults.\n */\nlet sharedSelectorEngine: SelectorEngine | undefined;\n\nfunction getSharedSelectorEngine(): SelectorEngine {\n if (!sharedSelectorEngine) {\n sharedSelectorEngine = createSelectorEngine(resolveSelectorConfig());\n }\n return sharedSelectorEngine;\n}\n\nexport class DataExtractor {\n private readonly additionalMaskTextPatterns: RegExp[];\n diagnosticsClient?: IDiagnosticsClient;\n\n /**\n * Shared element-selector engine. This is the single place autocapture turns\n * an element into a selector string ({@link getElementPath}), so it's the\n * seam where the legacy `cssPath` walker is swapped for the configurable\n * engine. It ships dormant: with the default config (`enabled: false`) the\n * engine routes through the byte-identical legacy walker, so behavior is\n * unchanged until remote config flips an org onto the new algorithm via\n * {@link updateSelectorConfig}.\n *\n * The engine is shared across all DataExtractor instances to ensure\n * consistent selector output when both autocapture-plugin and\n * frustration-plugin are active.\n */\n private readonly selectorEngine: SelectorEngine;\n\n constructor(options: ElementInteractionsOptions, context?: { diagnosticsClient: IDiagnosticsClient }) {\n this.diagnosticsClient = context?.diagnosticsClient;\n this.selectorEngine = getSharedSelectorEngine();\n\n const rawPatterns = options.maskTextRegex ?? [];\n\n const compiled: RegExp[] = [];\n for (const entry of rawPatterns) {\n if (compiled.length >= constants.MAX_MASK_TEXT_PATTERNS) {\n break;\n }\n if (entry instanceof RegExp) {\n compiled.push(entry);\n } else if ('pattern' in entry && typeof entry.pattern === 'string') {\n try {\n compiled.push(new RegExp(entry.pattern, 'i'));\n } catch {\n // ignore invalid pattern strings\n }\n }\n }\n this.additionalMaskTextPatterns = compiled;\n }\n\n /**\n * Wrapper method to replace sensitive strings using the helper function\n * @param text - The text to search for sensitive data\n * @returns The text with sensitive data replaced by masked text\n */\n replaceSensitiveString = (text: string | null): string => {\n return replaceSensitiveString(text, this.additionalMaskTextPatterns);\n };\n\n // Get the DOM hierarchy of the element, starting from the target element to the root element.\n getHierarchy = (element: Element | null): Hierarchy => {\n const startTime = performance.now();\n\n let hierarchy: Hierarchy = [];\n if (!element) {\n return [];\n }\n\n // Get list of ancestors including itself and get properties at each level in the hierarchy\n const ancestors = getAncestors(element);\n\n // Build attributes to mask map\n const elementToAttributesToMaskMap = new Map<Element, Set<string>>();\n\n for (let i = ancestors.length - 1; i >= 0; i--) {\n const node = ancestors[i];\n if (node) {\n const attributesToMask = parseAttributesToMask(node.getAttribute(constants.DATA_AMP_MASK_ATTRIBUTES));\n const ancestorAttributesToMask =\n i === ancestors.length - 1 ? [] : elementToAttributesToMaskMap.get(ancestors[i + 1]) ?? new Set<string>();\n const combinedAttributesToMask = new Set([...ancestorAttributesToMask, ...attributesToMask]);\n elementToAttributesToMaskMap.set(node, combinedAttributesToMask);\n }\n }\n\n hierarchy = ancestors.map((el) =>\n getElementProperties(el, elementToAttributesToMaskMap.get(el) ?? new Set<string>()),\n );\n\n // Search for and mask any sensitive attribute values\n for (const hierarchyNode of hierarchy) {\n if (hierarchyNode?.attrs) {\n Object.entries(hierarchyNode.attrs).forEach(([key, value]) => {\n if (hierarchyNode.attrs) {\n hierarchyNode.attrs[key] = this.replaceSensitiveString(value);\n }\n });\n }\n }\n\n const endTime = performance.now();\n this.diagnosticsClient?.recordHistogram('autocapturePlugin.getHierarchy', endTime - startTime);\n\n return hierarchy;\n };\n\n getNearestLabel = (element: Element): string => {\n const parent = element.parentElement;\n if (!parent) {\n return '';\n }\n let labelElement: Element | null;\n try {\n labelElement = parent.querySelector(':scope>span,h1,h2,h3,h4,h5,h6');\n } catch {\n /* istanbul ignore next */\n labelElement = null;\n }\n if (labelElement) {\n /* istanbul ignore next */\n return this.getText(labelElement);\n }\n return this.getNearestLabel(parent);\n };\n\n getElementPath = (element: Element | null): string => {\n if (!element) {\n return '';\n }\n const startTime = performance.now();\n\n const elementPath = this.selectorEngine.generate(element);\n\n const endTime = performance.now();\n this.diagnosticsClient?.recordHistogram('autocapturePlugin.getElementPath', endTime - startTime);\n\n return elementPath;\n };\n\n /**\n * Apply an element-selector remote-config payload to the engine. Called from\n * plugin setup when remote config is delivered. Resolving an absent/empty\n * payload yields the documented defaults (engine stays dormant on legacy\n * `cssPath`); flipping `enabled: true` switches {@link getElementPath} onto\n * the new strategy-based selector output.\n */\n updateSelectorConfig = (remote?: ElementSelectorRemoteConfig | null, logger?: ElementSelectorLogger): void => {\n this.selectorEngine.updateConfig(resolveSelectorConfig(remote ?? undefined, logger));\n };\n\n // Returns the Amplitude event properties for the given element.\n getEventProperties = (actionType: ActionType, element: Element, dataAttributePrefix: string) => {\n /* istanbul ignore next */\n const tag = element?.tagName?.toLowerCase?.();\n /* istanbul ignore next */\n const rect =\n typeof element.getBoundingClientRect === 'function' ? element.getBoundingClientRect() : { left: null, top: null };\n\n const hierarchy = this.getHierarchy(element);\n const currentElementAttributes = hierarchy[0]?.attrs;\n const nearestLabel = this.getNearestLabel(element);\n const attributes = extractPrefixedAttributes(currentElementAttributes ?? {}, dataAttributePrefix);\n\n /* istanbul ignore next */\n const properties: Record<string, any> = {\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_HIERARCHY]: hierarchy,\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_TAG]: tag,\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_TEXT]: this.getText(element),\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_POSITION_LEFT]: rect.left == null ? null : Math.round(rect.left),\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_POSITION_TOP]: rect.top == null ? null : Math.round(rect.top),\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_ATTRIBUTES]: attributes,\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_PATH]: this.getElementPath(element),\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_PARENT_LABEL]: nearestLabel,\n [constants.AMPLITUDE_EVENT_PROP_PAGE_URL]: getDecodeURI(window.location.href.split('?')[0]),\n [constants.AMPLITUDE_EVENT_PROP_PAGE_TITLE]: (\n getPageTitle as (parseTitleFunction: (title: string) => string) => string\n )(this.replaceSensitiveString),\n [constants.AMPLITUDE_EVENT_PROP_VIEWPORT_HEIGHT]: window.innerHeight,\n [constants.AMPLITUDE_EVENT_PROP_VIEWPORT_WIDTH]: window.innerWidth,\n };\n\n const pageViewId = getCurrentPageViewId();\n /* istanbul ignore next */\n if (pageViewId) {\n /* istanbul ignore next */\n properties[constants.AMPLITUDE_EVENT_PROP_PAGE_VIEW_ID] = pageViewId;\n }\n\n // id is never masked, so always include it\n properties[constants.AMPLITUDE_EVENT_PROP_ELEMENT_ID] = element.getAttribute('id') || '';\n\n // class is never masked, so always include it\n properties[constants.AMPLITUDE_EVENT_PROP_ELEMENT_CLASS] = element.getAttribute('class');\n\n properties[constants.AMPLITUDE_EVENT_PROP_ELEMENT_ARIA_LABEL] = currentElementAttributes?.['aria-label'];\n\n if (tag === 'a' && actionType === 'click' && element instanceof HTMLAnchorElement) {\n const href = element.href.substring(0, constants.MAX_ATTRIBUTE_LENGTH);\n properties[constants.AMPLITUDE_EVENT_PROP_ELEMENT_HREF] = this.replaceSensitiveString(href); // we don't use hierarchy here because we don't want href value to be changed\n }\n\n return removeEmptyProperties(properties);\n };\n\n addTypeAndTimestamp = <T>(\n event: T,\n type: BaseTimestampedEvent<T>['type'] | ElementBasedTimestampedEvent<T>['type'],\n ): BaseTimestampedEvent<T> | ElementBasedTimestampedEvent<T> => {\n return {\n event,\n timestamp: Date.now(),\n type,\n };\n };\n\n addAdditionalEventProperties = <T>(\n event: T,\n type: TimestampedEvent<T>['type'],\n selectorAllowlist: string[],\n dataAttributePrefix: string,\n // capture the event if the cursor is a \"pointer\" when this element is clicked on\n // reason: a \"pointer\" cursor indicates that an element should be interactable\n // regardless of the element's tag name\n isCapturingCursorPointer = false,\n ): TimestampedEvent<T> | ElementBasedTimestampedEvent<T> => {\n const baseEvent = this.addTypeAndTimestamp(event, type);\n\n if (isElementBasedEvent(baseEvent) && baseEvent.event.target !== null) {\n if (isCapturingCursorPointer) {\n const isCursorPointer = isElementPointerCursor(baseEvent.event.target as Element, baseEvent.type);\n if (isCursorPointer) {\n baseEvent.closestTrackedAncestor = baseEvent.event.target as HTMLElement;\n baseEvent.targetElementProperties = this.getEventProperties(\n baseEvent.type,\n baseEvent.closestTrackedAncestor,\n dataAttributePrefix,\n );\n return baseEvent;\n }\n }\n // Retrieve additional event properties from the target element\n const closestTrackedAncestor = getClosestElement(baseEvent.event.target as HTMLElement, selectorAllowlist);\n if (closestTrackedAncestor) {\n baseEvent.closestTrackedAncestor = closestTrackedAncestor;\n baseEvent.targetElementProperties = this.getEventProperties(\n baseEvent.type,\n closestTrackedAncestor,\n dataAttributePrefix,\n );\n }\n return baseEvent;\n }\n\n return baseEvent;\n };\n\n extractDataFromDataSource = (dataSource: DataSource, contextElement: HTMLElement) => {\n // Extract from DOM Element\n if (dataSource.sourceType === 'DOM_ELEMENT') {\n const sourceElement = getDataSource(dataSource, contextElement);\n if (!sourceElement) {\n return undefined;\n }\n\n if (dataSource.elementExtractType === 'TEXT') {\n return this.getText(sourceElement);\n } else if (dataSource.elementExtractType === 'ATTRIBUTE' && dataSource.attribute) {\n return sourceElement.getAttribute(dataSource.attribute);\n }\n return undefined;\n }\n\n // TODO: Extract from other source types\n return undefined;\n };\n\n // Traverse text content without cloning DOM nodes, which avoids media/network side effects\n // from recreating nested elements such as <video>, <audio>, or <img>.\n private getTextWithMaskedDescendants = (element: Element): string => {\n const maskedSelector = `[${TEXT_MASK_ATTRIBUTE}], [contenteditable]`;\n // Fast path: if no masked descendants exist, rely on native text extraction.\n if (!element.querySelector(maskedSelector)) {\n return (element as HTMLElement).innerText;\n }\n\n let output = '';\n const childNodes = Array.from(element.childNodes);\n for (const childNode of childNodes) {\n if (childNode.nodeType === Node.TEXT_NODE) {\n output += childNode.textContent || '';\n continue;\n }\n\n if (!(childNode instanceof Element)) {\n continue;\n }\n\n // Replace entire masked/contenteditable subtrees with the mask token.\n if (childNode.hasAttribute(TEXT_MASK_ATTRIBUTE) || childNode.hasAttribute('contenteditable')) {\n output += MASKED_TEXT_VALUE;\n continue;\n }\n output += this.getTextWithMaskedDescendants(childNode);\n }\n return output;\n };\n\n getText = (element: Element): string => {\n // Check if element or any parent has data-amp-mask attribute\n const hasMaskAttribute = element.closest(`[${TEXT_MASK_ATTRIBUTE}]`) !== null;\n if (hasMaskAttribute) {\n return MASKED_TEXT_VALUE;\n }\n let output = '';\n if (!element.querySelector(`[${TEXT_MASK_ATTRIBUTE}], [contenteditable]`)) {\n output = (element as HTMLElement).innerText || '';\n } else {\n output = this.getTextWithMaskedDescendants(element);\n }\n return this.replaceSensitiveString(output.substring(0, 255)).replace(/\\s+/g, ' ').trim();\n };\n\n // Returns the element properties for the given element in Visual Labeling.\n getEventTagProps = (element: Element): Record<string, JSONValue> => {\n if (!element) {\n return {};\n }\n /* istanbul ignore next */\n const tag = element?.tagName?.toLowerCase?.();\n\n const properties = {\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_TAG]: tag,\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_TEXT]: this.getText(element),\n [constants.AMPLITUDE_EVENT_PROP_PAGE_URL]: window.location.href.split('?')[0],\n };\n return removeEmptyProperties(properties) as Record<string, JSONValue>;\n };\n}\n"]}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { BrowserConfig } from '@amplitude/analytics-core';
|
|
2
2
|
import { DataExtractor } from './data-extractor';
|
|
3
3
|
/**
|
|
4
|
-
* Remote-config key for the element-selector engine payload.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* `ElementSelectorRemoteConfig`.
|
|
4
|
+
* Remote-config key for the element-selector engine payload. Mirrors the
|
|
5
|
+
* `configs.analyticsSDK.pageActions` namespace autocapture already subscribes
|
|
6
|
+
* to. The payload shape is `ElementSelectorRemoteConfig`.
|
|
8
7
|
*/
|
|
9
|
-
export declare const ELEMENT_SELECTOR_REMOTE_CONFIG_KEY = "configs.analyticsSDK.
|
|
8
|
+
export declare const ELEMENT_SELECTOR_REMOTE_CONFIG_KEY = "configs.analyticsSDK.elementSelector";
|
|
10
9
|
/**
|
|
11
10
|
* Subscribe a plugin's {@link DataExtractor} to element-selector remote config.
|
|
12
11
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"element-selector-config.d.ts","sourceRoot":"","sources":["../../src/element-selector-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD
|
|
1
|
+
{"version":3,"file":"element-selector-config.d.ts","sourceRoot":"","sources":["../../src/element-selector-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD;;;;GAIG;AACH,eAAO,MAAM,kCAAkC,yCAAyC,CAAC;AAEzF;;;;;;;;;;GAUG;AACH,wBAAgB,gCAAgC,CAC9C,MAAM,EAAE,aAAa,EACrB,aAAa,EAAE,aAAa,GAC3B,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAa1B"}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Remote-config key for the element-selector engine payload.
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* `ElementSelectorRemoteConfig`.
|
|
2
|
+
* Remote-config key for the element-selector engine payload. Mirrors the
|
|
3
|
+
* `configs.analyticsSDK.pageActions` namespace autocapture already subscribes
|
|
4
|
+
* to. The payload shape is `ElementSelectorRemoteConfig`.
|
|
6
5
|
*/
|
|
7
|
-
export var ELEMENT_SELECTOR_REMOTE_CONFIG_KEY = 'configs.analyticsSDK.
|
|
6
|
+
export var ELEMENT_SELECTOR_REMOTE_CONFIG_KEY = 'configs.analyticsSDK.elementSelector';
|
|
8
7
|
/**
|
|
9
8
|
* Subscribe a plugin's {@link DataExtractor} to element-selector remote config.
|
|
10
9
|
*
|
|
@@ -21,18 +20,10 @@ export function subscribeToElementSelectorConfig(config, dataExtractor) {
|
|
|
21
20
|
if (!config.fetchRemoteConfig || !remoteConfigClient) {
|
|
22
21
|
return undefined;
|
|
23
22
|
}
|
|
24
|
-
config.loggerProvider.debug("@amplitude/plugin-autocapture-browser: subscribing to element-selector remote config at \"".concat(ELEMENT_SELECTOR_REMOTE_CONFIG_KEY, "\""));
|
|
25
23
|
var subscriptionId = remoteConfigClient.subscribe(ELEMENT_SELECTOR_REMOTE_CONFIG_KEY, 'all', function (remoteConfig) {
|
|
26
|
-
|
|
27
|
-
var payload = remoteConfig;
|
|
28
|
-
config.loggerProvider.debug('@amplitude/plugin-autocapture-browser: element-selector remote config delivered', {
|
|
29
|
-
enabled: (_a = payload === null || payload === void 0 ? void 0 : payload.enabled) !== null && _a !== void 0 ? _a : 'default (false)',
|
|
30
|
-
hasPayload: payload !== null && payload !== undefined,
|
|
31
|
-
});
|
|
32
|
-
dataExtractor.updateSelectorConfig(payload, config.loggerProvider);
|
|
24
|
+
dataExtractor.updateSelectorConfig(remoteConfig, config.loggerProvider);
|
|
33
25
|
});
|
|
34
26
|
return function () {
|
|
35
|
-
config.loggerProvider.debug("@amplitude/plugin-autocapture-browser: unsubscribing from element-selector remote config (subscription ".concat(subscriptionId, ")"));
|
|
36
27
|
remoteConfigClient.unsubscribe(subscriptionId);
|
|
37
28
|
};
|
|
38
29
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"element-selector-config.js","sourceRoot":"","sources":["../../src/element-selector-config.ts"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"element-selector-config.js","sourceRoot":"","sources":["../../src/element-selector-config.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,MAAM,CAAC,IAAM,kCAAkC,GAAG,sCAAsC,CAAC;AAEzF;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gCAAgC,CAC9C,MAAqB,EACrB,aAA4B;IAE5B,IAAM,kBAAkB,GAAG,MAAM,CAAC,kBAAkB,CAAC;IACrD,IAAI,CAAC,MAAM,CAAC,iBAAiB,IAAI,CAAC,kBAAkB,EAAE;QACpD,OAAO,SAAS,CAAC;KAClB;IAED,IAAM,cAAc,GAAG,kBAAkB,CAAC,SAAS,CAAC,kCAAkC,EAAE,KAAK,EAAE,UAAC,YAAY;QAC1G,aAAa,CAAC,oBAAoB,CAAC,YAAkD,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;IAChH,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,kBAAkB,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;IACjD,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { BrowserConfig } from '@amplitude/analytics-core';\nimport { ElementSelectorRemoteConfig } from '@amplitude/element-selector';\nimport { DataExtractor } from './data-extractor';\n\n/**\n * Remote-config key for the element-selector engine payload. Mirrors the\n * `configs.analyticsSDK.pageActions` namespace autocapture already subscribes\n * to. The payload shape is `ElementSelectorRemoteConfig`.\n */\nexport const ELEMENT_SELECTOR_REMOTE_CONFIG_KEY = 'configs.analyticsSDK.elementSelector';\n\n/**\n * Subscribe a plugin's {@link DataExtractor} to element-selector remote config.\n *\n * On each delivery, the resolved config is pushed into the extractor's engine,\n * which changes what `getElementPath` (and therefore every selector-bearing\n * autocapture event) emits. When remote config is disabled or unavailable, this\n * is a no-op and the engine stays on the dormant defaults.\n *\n * @returns an unsubscribe function when a subscription was created, otherwise\n * `undefined`.\n */\nexport function subscribeToElementSelectorConfig(\n config: BrowserConfig,\n dataExtractor: DataExtractor,\n): (() => void) | undefined {\n const remoteConfigClient = config.remoteConfigClient;\n if (!config.fetchRemoteConfig || !remoteConfigClient) {\n return undefined;\n }\n\n const subscriptionId = remoteConfigClient.subscribe(ELEMENT_SELECTOR_REMOTE_CONFIG_KEY, 'all', (remoteConfig) => {\n dataExtractor.updateSelectorConfig(remoteConfig as ElementSelectorRemoteConfig | null, config.loggerProvider);\n });\n\n return () => {\n remoteConfigClient.unsubscribe(subscriptionId);\n };\n}\n"]}
|
package/lib/esm/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "1.28.0
|
|
1
|
+
export declare const VERSION = "1.28.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/lib/esm/version.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,WAAW,CAAC"}
|
package/lib/esm/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export var VERSION = '1.28.0
|
|
1
|
+
export var VERSION = '1.28.0';
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
package/lib/esm/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,IAAM,OAAO,GAAG,
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,IAAM,OAAO,GAAG,QAAQ,CAAC","sourcesContent":["export const VERSION = '1.28.0';\n"]}
|