@newrelic/browser-agent 1.302.0-rc.9 → 1.303.0-rc.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/CHANGELOG.md +20 -0
- package/dist/cjs/common/config/runtime.js +9 -0
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/harvest/harvester.js +1 -1
- package/dist/cjs/common/util/mfe.js +8 -5
- package/dist/cjs/features/utils/agent-session.js +0 -8
- package/dist/cjs/loaders/api/consent.js +16 -3
- package/dist/cjs/loaders/api/register-api-types.js +5 -2
- package/dist/cjs/loaders/api/register.js +12 -10
- package/dist/esm/common/config/runtime.js +9 -0
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/harvest/harvester.js +1 -1
- package/dist/esm/common/util/mfe.js +7 -5
- package/dist/esm/features/utils/agent-session.js +0 -8
- package/dist/esm/loaders/api/consent.js +16 -3
- package/dist/esm/loaders/api/register-api-types.js +5 -2
- package/dist/esm/loaders/api/register.js +13 -10
- package/dist/types/common/config/runtime.d.ts.map +1 -1
- package/dist/types/common/util/mfe.d.ts +3 -0
- package/dist/types/common/util/mfe.d.ts.map +1 -1
- package/dist/types/features/utils/agent-session.d.ts.map +1 -1
- package/dist/types/loaders/api/consent.d.ts.map +1 -1
- package/dist/types/loaders/api/register-api-types.d.ts +18 -4
- package/dist/types/loaders/api/register-api-types.d.ts.map +1 -1
- package/dist/types/loaders/api/register.d.ts +0 -16
- package/dist/types/loaders/api/register.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/common/config/runtime.js +10 -0
- package/src/common/harvest/harvester.js +1 -1
- package/src/common/util/mfe.js +10 -4
- package/src/features/utils/agent-session.js +0 -8
- package/src/loaders/api/consent.js +16 -3
- package/src/loaders/api/register-api-types.js +5 -2
- package/src/loaders/api/register.js +13 -10
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,26 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [1.303.0](https://github.com/newrelic/newrelic-browser-agent/compare/v1.302.0...v1.303.0) (2025-11-13)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* Add custom event support to register API ([#1606](https://github.com/newrelic/newrelic-browser-agent/issues/1606)) ([4137dcb](https://github.com/newrelic/newrelic-browser-agent/commit/4137dcbb339642219164d68695b84a8e48fa9b6f))
|
|
12
|
+
* Add measure support to register API ([#1623](https://github.com/newrelic/newrelic-browser-agent/issues/1623)) ([c2785f3](https://github.com/newrelic/newrelic-browser-agent/commit/c2785f39ca9ea1f5b87f3e2cf4fc7e462d6084e7))
|
|
13
|
+
* Add consent API ([#1533](https://github.com/newrelic/newrelic-browser-agent/issues/1533)) ([4e8ad2a](https://github.com/newrelic/newrelic-browser-agent/commit/4e8ad2a6aea34bbaa39b6beb67c3947feee3c01d))
|
|
14
|
+
* Additional validation to prepare agent for MFE registrations ([#1625](https://github.com/newrelic/newrelic-browser-agent/issues/1625)) ([aa8c02f](https://github.com/newrelic/newrelic-browser-agent/commit/aa8c02f966e9c7df5c4e83c911f9342b2183447f))
|
|
15
|
+
* Allow consent API to be invoked without localStorage access ([#1627](https://github.com/newrelic/newrelic-browser-agent/issues/1627)) ([0690a65](https://github.com/newrelic/newrelic-browser-agent/commit/0690a65bcfa35eabe0e83b13c058398746e924b8))
|
|
16
|
+
* Allow nested registrations ([#1616](https://github.com/newrelic/newrelic-browser-agent/issues/1616)) ([74a8d4a](https://github.com/newrelic/newrelic-browser-agent/commit/74a8d4ac745cff33eb15f9469775f85fd2641097))
|
|
17
|
+
* Retry initial connect call ([#1605](https://github.com/newrelic/newrelic-browser-agent/issues/1605)) ([9770132](https://github.com/newrelic/newrelic-browser-agent/commit/9770132209b9fb1320b3f60eedfa932b0fcfa3a4))
|
|
18
|
+
* SMs for browser connect response ([#1611](https://github.com/newrelic/newrelic-browser-agent/issues/1611)) ([29f5bdf](https://github.com/newrelic/newrelic-browser-agent/commit/29f5bdf6fa36020a87e5c0aa443d64ce55722c85))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Bug Fixes
|
|
22
|
+
|
|
23
|
+
* memoize promise context propagation to avoid safari hangs ([#1597](https://github.com/newrelic/newrelic-browser-agent/issues/1597)) ([23cb559](https://github.com/newrelic/newrelic-browser-agent/commit/23cb55993add2eb7e7b14b0d77c6fa3bbb9abcf1))
|
|
24
|
+
* Obfuscate custom attributes for logs added after PVE ([#1622](https://github.com/newrelic/newrelic-browser-agent/issues/1622)) ([f648e3f](https://github.com/newrelic/newrelic-browser-agent/commit/f648e3f1f843913d4c9be6534b0d1e3ba47eb260))
|
|
25
|
+
|
|
6
26
|
## [1.302.0](https://github.com/newrelic/newrelic-browser-agent/compare/v1.301.0...v1.302.0) (2025-10-24)
|
|
7
27
|
|
|
8
28
|
|
|
@@ -23,9 +23,18 @@ const ReadOnly = {
|
|
|
23
23
|
version: _env.VERSION,
|
|
24
24
|
originTime: _runtime.originTime
|
|
25
25
|
};
|
|
26
|
+
const hiddenState = {
|
|
27
|
+
consented: false
|
|
28
|
+
};
|
|
26
29
|
const RuntimeModel = {
|
|
27
30
|
/** Agent-specific metadata found in the RUM call response. ex. entityGuid */
|
|
28
31
|
appMetadata: {},
|
|
32
|
+
get consented() {
|
|
33
|
+
return this.session?.state?.consent || hiddenState.consented;
|
|
34
|
+
},
|
|
35
|
+
set consented(value) {
|
|
36
|
+
hiddenState.consented = value;
|
|
37
|
+
},
|
|
29
38
|
customTransaction: undefined,
|
|
30
39
|
denyList: undefined,
|
|
31
40
|
disabled: false,
|
|
@@ -17,7 +17,7 @@ exports.VERSION = exports.RRWEB_VERSION = exports.RRWEB_PACKAGE_NAME = exports.D
|
|
|
17
17
|
/**
|
|
18
18
|
* Exposes the version of the agent
|
|
19
19
|
*/
|
|
20
|
-
const VERSION = exports.VERSION = "1.
|
|
20
|
+
const VERSION = exports.VERSION = "1.303.0-rc.0";
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Exposes the build type of the agent
|
|
@@ -17,7 +17,7 @@ exports.VERSION = exports.RRWEB_VERSION = exports.RRWEB_PACKAGE_NAME = exports.D
|
|
|
17
17
|
/**
|
|
18
18
|
* Exposes the version of the agent
|
|
19
19
|
*/
|
|
20
|
-
const VERSION = exports.VERSION = "1.
|
|
20
|
+
const VERSION = exports.VERSION = "1.303.0-rc.0";
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Exposes the build type of the agent
|
|
@@ -69,7 +69,7 @@ class Harvester {
|
|
|
69
69
|
endpointVersion: aggregateInst.harvestEndpointVersion || 1
|
|
70
70
|
};
|
|
71
71
|
if (aggregateInst.blocked) return output;
|
|
72
|
-
if (this.agentRef.init?.browser_consent_mode?.enabled && !this.agentRef.runtime
|
|
72
|
+
if (this.agentRef.init?.browser_consent_mode?.enabled && !this.agentRef.runtime.consented) return output;
|
|
73
73
|
const submitMethod = (0, _submitData.getSubmitMethod)(localOpts);
|
|
74
74
|
if (!submitMethod) return output;
|
|
75
75
|
const shouldRetryOnFail = !localOpts.isFinalHarvest && submitMethod === _submitData.xhr; // always retry all features harvests except for final
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.getVersion2Attributes = getVersion2Attributes;
|
|
7
|
+
exports.hasValidValue = hasValidValue;
|
|
7
8
|
exports.isValidMFETarget = isValidMFETarget;
|
|
8
9
|
/**
|
|
9
10
|
* Copyright 2020-2025 New Relic, Inc. All rights reserved.
|
|
@@ -17,9 +18,14 @@ exports.isValidMFETarget = isValidMFETarget;
|
|
|
17
18
|
function isValidMFETarget(target = {}) {
|
|
18
19
|
return !!(target.id && target.name);
|
|
19
20
|
}
|
|
21
|
+
function hasValidValue(val) {
|
|
22
|
+
return typeof val === 'string' && val.trim().length < 501 || typeof val === 'number';
|
|
23
|
+
}
|
|
20
24
|
|
|
21
25
|
/**
|
|
22
26
|
* When given a valid target, returns an object with the MFE payload attributes. Returns an empty object otherwise.
|
|
27
|
+
* @note Field names may change as the schema is finalized
|
|
28
|
+
*
|
|
23
29
|
* @param {Object} [target] the registered target
|
|
24
30
|
* @param {AggregateInstance} [aggregateInstance] the aggregate instance calling the method
|
|
25
31
|
* @returns {{'mfe.id': *, 'mfe.name': String}|{}} returns an empty object if args are not supplied or the aggregate instance is not supporting version 2
|
|
@@ -35,11 +41,8 @@ function getVersion2Attributes(target, aggregateInstance) {
|
|
|
35
41
|
}
|
|
36
42
|
return {
|
|
37
43
|
'mfe.id': target.id,
|
|
38
|
-
// these field names may change as the schema is finalized
|
|
39
44
|
'mfe.name': target.name,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
// these field names may change as the schema is finalized
|
|
43
|
-
'parent.id': containerAgentEntityGuid
|
|
45
|
+
eventSource: target.eventSource,
|
|
46
|
+
'parent.id': target.parent?.id || containerAgentEntityGuid
|
|
44
47
|
};
|
|
45
48
|
}
|
|
@@ -63,14 +63,6 @@ function setupAgentSession(agentRef) {
|
|
|
63
63
|
agentRef.runtime.session.write({
|
|
64
64
|
consent: accept === undefined ? true : accept
|
|
65
65
|
});
|
|
66
|
-
|
|
67
|
-
// call sendRum if it wasn't called yet
|
|
68
|
-
agentRef.features.page_view_event.onAggregateImported.then(loaded => {
|
|
69
|
-
const pveAgg = agentRef.features.page_view_event.featAggregate;
|
|
70
|
-
if (loaded && !pveAgg.sentRum) {
|
|
71
|
-
pveAgg.sendRum();
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
66
|
}, 'session', sharedEE);
|
|
75
67
|
(0, _drain.drain)(agentRef.agentIdentifier, 'session');
|
|
76
68
|
return agentRef.runtime.session;
|
|
@@ -14,11 +14,24 @@ var _console = require("../../common/util/console");
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
function setupConsentAPI(agent) {
|
|
17
|
-
(0, _sharedHandlers.setupAPI)(_constants.CONSENT, function (accept) {
|
|
18
|
-
if (
|
|
17
|
+
(0, _sharedHandlers.setupAPI)(_constants.CONSENT, function (accept = true) {
|
|
18
|
+
if (typeof accept !== 'boolean') {
|
|
19
19
|
(0, _console.warn)(65, typeof accept);
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
|
-
|
|
22
|
+
/** harvester, by way of "consented" getter, checks session state first, and falls back on runtime state if not available. Set both here */
|
|
23
|
+
(0, _handle.handle)(_constants.prefix + _constants.CONSENT, [accept], undefined, 'session', agent.ee); // sets session state (if available)
|
|
24
|
+
agent.runtime.consented = accept; // sets runtime state
|
|
25
|
+
|
|
26
|
+
/** if consent is granted, attempt to make a PageView event harvest if one has not already been made */
|
|
27
|
+
if (accept) {
|
|
28
|
+
const pveInst = agent.features.page_view_event;
|
|
29
|
+
pveInst.onAggregateImported.then(loaded => {
|
|
30
|
+
const pveAgg = pveInst.featAggregate;
|
|
31
|
+
if (loaded && !pveAgg.sentRum) {
|
|
32
|
+
pveAgg.sendRum();
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
23
36
|
}, agent);
|
|
24
37
|
}
|
|
@@ -13,8 +13,9 @@ exports.default = void 0;
|
|
|
13
13
|
* @property {(name: string, attributes?: object) => void} addPageAction - Add a page action for the registered entity.
|
|
14
14
|
* @property {(message: string, options?: { customAttributes?: object, level?: 'ERROR' | 'TRACE' | 'DEBUG' | 'INFO' | 'WARN'}) => void} log - Capture a log for the registered entity.
|
|
15
15
|
* @property {(error: Error | string, customAttributes?: object) => void} noticeError - Notice an error for the registered entity.
|
|
16
|
+
* @property {(target: RegisterAPIConstructor) => RegisterAPI} register - Record a custom event for the registered entity.
|
|
16
17
|
* @property {(eventType: string, attributes?: Object) => void} recordCustomEvent - Record a custom event for the registered entity.
|
|
17
|
-
* @property {(eventType: string, options?: {start: number, end: number, duration: number, customAttributes: object}) => {
|
|
18
|
+
* @property {(eventType: string, options?: {start: number, end: number, duration: number, customAttributes: object}) => ({start: number, end: number, duration: number, customAttributes: object})} measure - Measures a task that is recorded as a BrowserPerformance event.
|
|
18
19
|
* @property {(value: string | null) => void} setApplicationVersion - Add an application.version attribute to all outgoing data for the registered entity.
|
|
19
20
|
* @property {(name: string, value: string | number | boolean | null, persist?: boolean) => void} setCustomAttribute - Add a custom attribute to outgoing data for the registered entity.
|
|
20
21
|
* @property {(value: string | null) => void} setUserId - Add an enduser.id attribute to all outgoing API data for the registered entity.
|
|
@@ -24,13 +25,15 @@ exports.default = void 0;
|
|
|
24
25
|
* @typedef {Object} RegisterAPIConstructor
|
|
25
26
|
* @property {string|number} id - The unique id for the registered entity. This will be assigned to any synthesized entities.
|
|
26
27
|
* @property {string} name - The readable name for the registered entity. This will be assigned to any synthesized entities.
|
|
28
|
+
* @property {string} [parentId] - The parentId for the registered entity. If none was supplied, it will assume the entity guid from the main agent.
|
|
27
29
|
*/
|
|
28
30
|
/**
|
|
29
31
|
* @typedef {Object} RegisterAPIMetadata
|
|
30
32
|
* @property {Object} customAttributes - The custom attributes for the registered entity.
|
|
31
33
|
* @property {Object} target - The options for the registered entity.
|
|
32
|
-
* @property {string} target.licenseKey - The license key for the registered entity. If none was supplied, it will assume the license key from the main agent.
|
|
34
|
+
* @property {string} [target.licenseKey] - The license key for the registered entity. If none was supplied, it will assume the license key from the main agent.
|
|
33
35
|
* @property {string} target.id - The ID for the registered entity.
|
|
34
36
|
* @property {string} target.name - The name returned for the registered entity.
|
|
37
|
+
* @property {string} [target.parentId] - The parentId for the registered entity. If none was supplied, it will assume the entity guid from the main agent.
|
|
35
38
|
*/
|
|
36
39
|
var _default = exports.default = {};
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.buildRegisterApi = buildRegisterApi;
|
|
7
6
|
exports.setupRegisterAPI = setupRegisterAPI;
|
|
8
7
|
var _handle = require("../../common/event-emitter/handle");
|
|
9
8
|
var _console = require("../../common/util/console");
|
|
@@ -35,7 +34,7 @@ var _recordCustomEvent = require("./recordCustomEvent");
|
|
|
35
34
|
*/
|
|
36
35
|
function setupRegisterAPI(agent) {
|
|
37
36
|
(0, _sharedHandlers.setupAPI)(_constants2.REGISTER, function (target) {
|
|
38
|
-
return
|
|
37
|
+
return register(agent, target);
|
|
39
38
|
}, agent);
|
|
40
39
|
}
|
|
41
40
|
|
|
@@ -43,19 +42,18 @@ function setupRegisterAPI(agent) {
|
|
|
43
42
|
* Builds the api object that will be returned from the register api method.
|
|
44
43
|
* Also conducts certain side-effects, such as harvesting a PageView event when triggered and gathering metadata for the registered entity.
|
|
45
44
|
* @param {Object} agentRef the reference to the base agent instance
|
|
46
|
-
* @param {
|
|
47
|
-
* @param {
|
|
48
|
-
* @param {string} [target.licenseKey] the license key of the target to report data to
|
|
49
|
-
* @param {string} target.id the entity ID of the target to report data to
|
|
50
|
-
* @param {string} target.name the entity name of the target to report data to
|
|
45
|
+
* @param {import('./register-api-types').RegisterAPIConstructor} target
|
|
46
|
+
* @param {import('./register-api-types').RegisterAPIConstructor} [parent]
|
|
51
47
|
* @returns {RegisterAPI} the api object to be returned from the register api method
|
|
52
48
|
*/
|
|
53
|
-
function
|
|
49
|
+
function register(agentRef, target, parent) {
|
|
54
50
|
const attrs = {};
|
|
55
51
|
(0, _console.warn)(54, 'newrelic.register');
|
|
56
52
|
target ||= {};
|
|
53
|
+
target.eventSource = 'MicroFrontendBrowserAgent';
|
|
57
54
|
target.licenseKey ||= agentRef.info.licenseKey; // will inherit the license key from the container agent if not provided for brevity. A future state may dictate that we need different license keys to do different things.
|
|
58
55
|
target.blocked = false;
|
|
56
|
+
target.parent = parent || {};
|
|
59
57
|
|
|
60
58
|
/** @type {Function} a function that is set and reports when APIs are triggered -- warns the customer of the invalid state */
|
|
61
59
|
let invalidApiResponse = () => {};
|
|
@@ -88,6 +86,9 @@ function buildRegisterApi(agentRef, target) {
|
|
|
88
86
|
/** primary cases that can block the register API from working at init time */
|
|
89
87
|
if (!agentRef.init.api.allow_registered_children) block((0, _invoke.single)(() => (0, _console.warn)(55)));
|
|
90
88
|
if (!(0, _mfe.isValidMFETarget)(target)) block((0, _invoke.single)(() => (0, _console.warn)(48, target)));
|
|
89
|
+
if (!(0, _mfe.hasValidValue)(target.id) || !(0, _mfe.hasValidValue)(target.name)) {
|
|
90
|
+
block((0, _invoke.single)(() => (0, _console.warn)(48, target)));
|
|
91
|
+
}
|
|
91
92
|
|
|
92
93
|
/** @type {RegisterAPI} */
|
|
93
94
|
const api = {
|
|
@@ -113,6 +114,7 @@ function buildRegisterApi(agentRef, target) {
|
|
|
113
114
|
...attrs,
|
|
114
115
|
...attributes
|
|
115
116
|
}, agentRef], target),
|
|
117
|
+
register: (target = {}) => report(register, [agentRef, target], api.metadata.target),
|
|
116
118
|
recordCustomEvent: (eventType, attributes = {}) => report(_recordCustomEvent.recordCustomEvent, [eventType, {
|
|
117
119
|
...attrs,
|
|
118
120
|
...attributes
|
|
@@ -164,8 +166,8 @@ function buildRegisterApi(agentRef, target) {
|
|
|
164
166
|
const timestamp = (0, _now.now)();
|
|
165
167
|
(0, _handle.handle)(_constants.SUPPORTABILITY_METRIC_CHANNEL, ["API/register/".concat(methodToCall.name, "/called")], undefined, _features.FEATURE_NAMES.metrics, agentRef.ee);
|
|
166
168
|
try {
|
|
167
|
-
const shouldDuplicate = agentRef.init.api.duplicate_registered_data;
|
|
168
|
-
if (shouldDuplicate
|
|
169
|
+
const shouldDuplicate = agentRef.init.api.duplicate_registered_data && methodToCall.name !== 'register';
|
|
170
|
+
if (shouldDuplicate) {
|
|
169
171
|
// also report to container by providing undefined target
|
|
170
172
|
methodToCall(...args, undefined, timestamp);
|
|
171
173
|
}
|
|
@@ -17,9 +17,18 @@ const ReadOnly = {
|
|
|
17
17
|
version: VERSION,
|
|
18
18
|
originTime
|
|
19
19
|
};
|
|
20
|
+
const hiddenState = {
|
|
21
|
+
consented: false
|
|
22
|
+
};
|
|
20
23
|
const RuntimeModel = {
|
|
21
24
|
/** Agent-specific metadata found in the RUM call response. ex. entityGuid */
|
|
22
25
|
appMetadata: {},
|
|
26
|
+
get consented() {
|
|
27
|
+
return this.session?.state?.consent || hiddenState.consented;
|
|
28
|
+
},
|
|
29
|
+
set consented(value) {
|
|
30
|
+
hiddenState.consented = value;
|
|
31
|
+
},
|
|
23
32
|
customTransaction: undefined,
|
|
24
33
|
denyList: undefined,
|
|
25
34
|
disabled: false,
|
|
@@ -61,7 +61,7 @@ export class Harvester {
|
|
|
61
61
|
endpointVersion: aggregateInst.harvestEndpointVersion || 1
|
|
62
62
|
};
|
|
63
63
|
if (aggregateInst.blocked) return output;
|
|
64
|
-
if (this.agentRef.init?.browser_consent_mode?.enabled && !this.agentRef.runtime
|
|
64
|
+
if (this.agentRef.init?.browser_consent_mode?.enabled && !this.agentRef.runtime.consented) return output;
|
|
65
65
|
const submitMethod = getSubmitMethod(localOpts);
|
|
66
66
|
if (!submitMethod) return output;
|
|
67
67
|
const shouldRetryOnFail = !localOpts.isFinalHarvest && submitMethod === xhrMethod; // always retry all features harvests except for final
|
|
@@ -10,9 +10,14 @@
|
|
|
10
10
|
export function isValidMFETarget(target = {}) {
|
|
11
11
|
return !!(target.id && target.name);
|
|
12
12
|
}
|
|
13
|
+
export function hasValidValue(val) {
|
|
14
|
+
return typeof val === 'string' && val.trim().length < 501 || typeof val === 'number';
|
|
15
|
+
}
|
|
13
16
|
|
|
14
17
|
/**
|
|
15
18
|
* When given a valid target, returns an object with the MFE payload attributes. Returns an empty object otherwise.
|
|
19
|
+
* @note Field names may change as the schema is finalized
|
|
20
|
+
*
|
|
16
21
|
* @param {Object} [target] the registered target
|
|
17
22
|
* @param {AggregateInstance} [aggregateInstance] the aggregate instance calling the method
|
|
18
23
|
* @returns {{'mfe.id': *, 'mfe.name': String}|{}} returns an empty object if args are not supplied or the aggregate instance is not supporting version 2
|
|
@@ -28,11 +33,8 @@ export function getVersion2Attributes(target, aggregateInstance) {
|
|
|
28
33
|
}
|
|
29
34
|
return {
|
|
30
35
|
'mfe.id': target.id,
|
|
31
|
-
// these field names may change as the schema is finalized
|
|
32
36
|
'mfe.name': target.name,
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
// these field names may change as the schema is finalized
|
|
36
|
-
'parent.id': containerAgentEntityGuid
|
|
37
|
+
eventSource: target.eventSource,
|
|
38
|
+
'parent.id': target.parent?.id || containerAgentEntityGuid
|
|
37
39
|
};
|
|
38
40
|
}
|
|
@@ -56,14 +56,6 @@ export function setupAgentSession(agentRef) {
|
|
|
56
56
|
agentRef.runtime.session.write({
|
|
57
57
|
consent: accept === undefined ? true : accept
|
|
58
58
|
});
|
|
59
|
-
|
|
60
|
-
// call sendRum if it wasn't called yet
|
|
61
|
-
agentRef.features.page_view_event.onAggregateImported.then(loaded => {
|
|
62
|
-
const pveAgg = agentRef.features.page_view_event.featAggregate;
|
|
63
|
-
if (loaded && !pveAgg.sentRum) {
|
|
64
|
-
pveAgg.sendRum();
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
59
|
}, 'session', sharedEE);
|
|
68
60
|
drain(agentRef.agentIdentifier, 'session');
|
|
69
61
|
return agentRef.runtime.session;
|
|
@@ -7,11 +7,24 @@ import { setupAPI } from './sharedHandlers';
|
|
|
7
7
|
import { handle } from '../../common/event-emitter/handle';
|
|
8
8
|
import { warn } from '../../common/util/console';
|
|
9
9
|
export function setupConsentAPI(agent) {
|
|
10
|
-
setupAPI(CONSENT, function (accept) {
|
|
11
|
-
if (
|
|
10
|
+
setupAPI(CONSENT, function (accept = true) {
|
|
11
|
+
if (typeof accept !== 'boolean') {
|
|
12
12
|
warn(65, typeof accept);
|
|
13
13
|
return;
|
|
14
14
|
}
|
|
15
|
-
|
|
15
|
+
/** harvester, by way of "consented" getter, checks session state first, and falls back on runtime state if not available. Set both here */
|
|
16
|
+
handle(prefix + CONSENT, [accept], undefined, 'session', agent.ee); // sets session state (if available)
|
|
17
|
+
agent.runtime.consented = accept; // sets runtime state
|
|
18
|
+
|
|
19
|
+
/** if consent is granted, attempt to make a PageView event harvest if one has not already been made */
|
|
20
|
+
if (accept) {
|
|
21
|
+
const pveInst = agent.features.page_view_event;
|
|
22
|
+
pveInst.onAggregateImported.then(loaded => {
|
|
23
|
+
const pveAgg = pveInst.featAggregate;
|
|
24
|
+
if (loaded && !pveAgg.sentRum) {
|
|
25
|
+
pveAgg.sendRum();
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
16
29
|
}, agent);
|
|
17
30
|
}
|
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
* @property {(name: string, attributes?: object) => void} addPageAction - Add a page action for the registered entity.
|
|
9
9
|
* @property {(message: string, options?: { customAttributes?: object, level?: 'ERROR' | 'TRACE' | 'DEBUG' | 'INFO' | 'WARN'}) => void} log - Capture a log for the registered entity.
|
|
10
10
|
* @property {(error: Error | string, customAttributes?: object) => void} noticeError - Notice an error for the registered entity.
|
|
11
|
+
* @property {(target: RegisterAPIConstructor) => RegisterAPI} register - Record a custom event for the registered entity.
|
|
11
12
|
* @property {(eventType: string, attributes?: Object) => void} recordCustomEvent - Record a custom event for the registered entity.
|
|
12
|
-
* @property {(eventType: string, options?: {start: number, end: number, duration: number, customAttributes: object}) => {
|
|
13
|
+
* @property {(eventType: string, options?: {start: number, end: number, duration: number, customAttributes: object}) => ({start: number, end: number, duration: number, customAttributes: object})} measure - Measures a task that is recorded as a BrowserPerformance event.
|
|
13
14
|
* @property {(value: string | null) => void} setApplicationVersion - Add an application.version attribute to all outgoing data for the registered entity.
|
|
14
15
|
* @property {(name: string, value: string | number | boolean | null, persist?: boolean) => void} setCustomAttribute - Add a custom attribute to outgoing data for the registered entity.
|
|
15
16
|
* @property {(value: string | null) => void} setUserId - Add an enduser.id attribute to all outgoing API data for the registered entity.
|
|
@@ -20,15 +21,17 @@
|
|
|
20
21
|
* @typedef {Object} RegisterAPIConstructor
|
|
21
22
|
* @property {string|number} id - The unique id for the registered entity. This will be assigned to any synthesized entities.
|
|
22
23
|
* @property {string} name - The readable name for the registered entity. This will be assigned to any synthesized entities.
|
|
24
|
+
* @property {string} [parentId] - The parentId for the registered entity. If none was supplied, it will assume the entity guid from the main agent.
|
|
23
25
|
*/
|
|
24
26
|
|
|
25
27
|
/**
|
|
26
28
|
* @typedef {Object} RegisterAPIMetadata
|
|
27
29
|
* @property {Object} customAttributes - The custom attributes for the registered entity.
|
|
28
30
|
* @property {Object} target - The options for the registered entity.
|
|
29
|
-
* @property {string} target.licenseKey - The license key for the registered entity. If none was supplied, it will assume the license key from the main agent.
|
|
31
|
+
* @property {string} [target.licenseKey] - The license key for the registered entity. If none was supplied, it will assume the license key from the main agent.
|
|
30
32
|
* @property {string} target.id - The ID for the registered entity.
|
|
31
33
|
* @property {string} target.name - The name returned for the registered entity.
|
|
34
|
+
* @property {string} [target.parentId] - The parentId for the registered entity. If none was supplied, it will assume the entity guid from the main agent.
|
|
32
35
|
*/
|
|
33
36
|
|
|
34
37
|
export default {};
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { handle } from '../../common/event-emitter/handle';
|
|
6
6
|
import { warn } from '../../common/util/console';
|
|
7
|
-
import { isValidMFETarget } from '../../common/util/mfe';
|
|
7
|
+
import { hasValidValue, isValidMFETarget } from '../../common/util/mfe';
|
|
8
8
|
import { FEATURE_NAMES } from '../features/features';
|
|
9
9
|
import { now } from '../../common/timing/now';
|
|
10
10
|
import { SUPPORTABILITY_METRIC_CHANNEL } from '../../features/metrics/constants';
|
|
@@ -28,7 +28,7 @@ import { recordCustomEvent } from './recordCustomEvent';
|
|
|
28
28
|
*/
|
|
29
29
|
export function setupRegisterAPI(agent) {
|
|
30
30
|
setupAPI(REGISTER, function (target) {
|
|
31
|
-
return
|
|
31
|
+
return register(agent, target);
|
|
32
32
|
}, agent);
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -36,19 +36,18 @@ export function setupRegisterAPI(agent) {
|
|
|
36
36
|
* Builds the api object that will be returned from the register api method.
|
|
37
37
|
* Also conducts certain side-effects, such as harvesting a PageView event when triggered and gathering metadata for the registered entity.
|
|
38
38
|
* @param {Object} agentRef the reference to the base agent instance
|
|
39
|
-
* @param {
|
|
40
|
-
* @param {
|
|
41
|
-
* @param {string} [target.licenseKey] the license key of the target to report data to
|
|
42
|
-
* @param {string} target.id the entity ID of the target to report data to
|
|
43
|
-
* @param {string} target.name the entity name of the target to report data to
|
|
39
|
+
* @param {import('./register-api-types').RegisterAPIConstructor} target
|
|
40
|
+
* @param {import('./register-api-types').RegisterAPIConstructor} [parent]
|
|
44
41
|
* @returns {RegisterAPI} the api object to be returned from the register api method
|
|
45
42
|
*/
|
|
46
|
-
|
|
43
|
+
function register(agentRef, target, parent) {
|
|
47
44
|
const attrs = {};
|
|
48
45
|
warn(54, 'newrelic.register');
|
|
49
46
|
target ||= {};
|
|
47
|
+
target.eventSource = 'MicroFrontendBrowserAgent';
|
|
50
48
|
target.licenseKey ||= agentRef.info.licenseKey; // will inherit the license key from the container agent if not provided for brevity. A future state may dictate that we need different license keys to do different things.
|
|
51
49
|
target.blocked = false;
|
|
50
|
+
target.parent = parent || {};
|
|
52
51
|
|
|
53
52
|
/** @type {Function} a function that is set and reports when APIs are triggered -- warns the customer of the invalid state */
|
|
54
53
|
let invalidApiResponse = () => {};
|
|
@@ -81,6 +80,9 @@ export function buildRegisterApi(agentRef, target) {
|
|
|
81
80
|
/** primary cases that can block the register API from working at init time */
|
|
82
81
|
if (!agentRef.init.api.allow_registered_children) block(single(() => warn(55)));
|
|
83
82
|
if (!isValidMFETarget(target)) block(single(() => warn(48, target)));
|
|
83
|
+
if (!hasValidValue(target.id) || !hasValidValue(target.name)) {
|
|
84
|
+
block(single(() => warn(48, target)));
|
|
85
|
+
}
|
|
84
86
|
|
|
85
87
|
/** @type {RegisterAPI} */
|
|
86
88
|
const api = {
|
|
@@ -106,6 +108,7 @@ export function buildRegisterApi(agentRef, target) {
|
|
|
106
108
|
...attrs,
|
|
107
109
|
...attributes
|
|
108
110
|
}, agentRef], target),
|
|
111
|
+
register: (target = {}) => report(register, [agentRef, target], api.metadata.target),
|
|
109
112
|
recordCustomEvent: (eventType, attributes = {}) => report(recordCustomEvent, [eventType, {
|
|
110
113
|
...attrs,
|
|
111
114
|
...attributes
|
|
@@ -157,8 +160,8 @@ export function buildRegisterApi(agentRef, target) {
|
|
|
157
160
|
const timestamp = now();
|
|
158
161
|
handle(SUPPORTABILITY_METRIC_CHANNEL, ["API/register/".concat(methodToCall.name, "/called")], undefined, FEATURE_NAMES.metrics, agentRef.ee);
|
|
159
162
|
try {
|
|
160
|
-
const shouldDuplicate = agentRef.init.api.duplicate_registered_data;
|
|
161
|
-
if (shouldDuplicate
|
|
163
|
+
const shouldDuplicate = agentRef.init.api.duplicate_registered_data && methodToCall.name !== 'register';
|
|
164
|
+
if (shouldDuplicate) {
|
|
162
165
|
// also report to container by providing undefined target
|
|
163
166
|
methodToCall(...args, undefined, timestamp);
|
|
164
167
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../../src/common/config/runtime.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../../src/common/config/runtime.js"],"names":[],"mappings":"AAsDO,gDAON"}
|
|
@@ -7,8 +7,11 @@
|
|
|
7
7
|
* @returns {boolean}
|
|
8
8
|
*/
|
|
9
9
|
export function isValidMFETarget(target?: Object): boolean;
|
|
10
|
+
export function hasValidValue(val: any): boolean;
|
|
10
11
|
/**
|
|
11
12
|
* When given a valid target, returns an object with the MFE payload attributes. Returns an empty object otherwise.
|
|
13
|
+
* @note Field names may change as the schema is finalized
|
|
14
|
+
*
|
|
12
15
|
* @param {Object} [target] the registered target
|
|
13
16
|
* @param {AggregateInstance} [aggregateInstance] the aggregate instance calling the method
|
|
14
17
|
* @returns {{'mfe.id': *, 'mfe.name': String}|{}} returns an empty object if args are not supplied or the aggregate instance is not supporting version 2
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mfe.d.ts","sourceRoot":"","sources":["../../../../src/common/util/mfe.js"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,0CAHW,MAAM,GACJ,OAAO,CAInB;AAED
|
|
1
|
+
{"version":3,"file":"mfe.d.ts","sourceRoot":"","sources":["../../../../src/common/util/mfe.js"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,0CAHW,MAAM,GACJ,OAAO,CAInB;AAED,iDAEC;AAED;;;;;;;GAOG;AACH,+CAJW,MAAM,sBACN,iBAAiB,GACf;IAAC,QAAQ,EAAE,GAAC,CAAC;IAAC,UAAU,SAAQ;CAAC,GAAC,EAAE,CAiBhD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-session.d.ts","sourceRoot":"","sources":["../../../../src/features/utils/agent-session.js"],"names":[],"mappings":"AAaA,
|
|
1
|
+
{"version":3,"file":"agent-session.d.ts","sourceRoot":"","sources":["../../../../src/features/utils/agent-session.js"],"names":[],"mappings":"AAaA,sDAoDC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consent.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/consent.js"],"names":[],"mappings":"AASA,
|
|
1
|
+
{"version":3,"file":"consent.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/consent.js"],"names":[],"mappings":"AASA,kDAqBC"}
|
|
@@ -16,19 +16,28 @@ export type RegisterAPI = {
|
|
|
16
16
|
* - Notice an error for the registered entity.
|
|
17
17
|
*/
|
|
18
18
|
noticeError: (error: Error | string, customAttributes?: object) => void;
|
|
19
|
+
/**
|
|
20
|
+
* - Record a custom event for the registered entity.
|
|
21
|
+
*/
|
|
22
|
+
register: (target: RegisterAPIConstructor) => RegisterAPI;
|
|
19
23
|
/**
|
|
20
24
|
* - Record a custom event for the registered entity.
|
|
21
25
|
*/
|
|
22
26
|
recordCustomEvent: (eventType: string, attributes?: Object) => void;
|
|
23
27
|
/**
|
|
24
|
-
*
|
|
28
|
+
* - Measures a task that is recorded as a BrowserPerformance event.
|
|
25
29
|
*/
|
|
26
|
-
|
|
30
|
+
measure: (eventType: string, options?: {
|
|
27
31
|
start: number;
|
|
28
32
|
end: number;
|
|
29
33
|
duration: number;
|
|
30
34
|
customAttributes: object;
|
|
31
|
-
}) => {
|
|
35
|
+
}) => ({
|
|
36
|
+
start: number;
|
|
37
|
+
end: number;
|
|
38
|
+
duration: number;
|
|
39
|
+
customAttributes: object;
|
|
40
|
+
});
|
|
32
41
|
/**
|
|
33
42
|
* - Add an application.version attribute to all outgoing data for the registered entity.
|
|
34
43
|
*/
|
|
@@ -55,6 +64,10 @@ export type RegisterAPIConstructor = {
|
|
|
55
64
|
* - The readable name for the registered entity. This will be assigned to any synthesized entities.
|
|
56
65
|
*/
|
|
57
66
|
name: string;
|
|
67
|
+
/**
|
|
68
|
+
* - The parentId for the registered entity. If none was supplied, it will assume the entity guid from the main agent.
|
|
69
|
+
*/
|
|
70
|
+
parentId?: string | undefined;
|
|
58
71
|
};
|
|
59
72
|
export type RegisterAPIMetadata = {
|
|
60
73
|
/**
|
|
@@ -65,9 +78,10 @@ export type RegisterAPIMetadata = {
|
|
|
65
78
|
* - The options for the registered entity.
|
|
66
79
|
*/
|
|
67
80
|
target: {
|
|
68
|
-
licenseKey
|
|
81
|
+
licenseKey?: string | undefined;
|
|
69
82
|
id: string;
|
|
70
83
|
name: string;
|
|
84
|
+
parentId?: string | undefined;
|
|
71
85
|
};
|
|
72
86
|
};
|
|
73
87
|
//# sourceMappingURL=register-api-types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register-api-types.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/register-api-types.js"],"names":[],"mappings":";;;;;;mBAOc,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI;;;;SAC3C,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;KAAC,KAAK,IAAI;;;;iBACxH,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,KAAK,IAAI;;;;
|
|
1
|
+
{"version":3,"file":"register-api-types.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/register-api-types.js"],"names":[],"mappings":";;;;;;mBAOc,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI;;;;SAC3C,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;KAAC,KAAK,IAAI;;;;iBACxH,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,KAAK,IAAI;;;;cAC1D,CAAC,MAAM,EAAE,sBAAsB,KAAK,WAAW;;;;uBAC/C,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI;;;;aAChD,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAC,KAAK,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAC,CAAC;;;;2BACrL,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI;;;;wBAC9B,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI;;;;eAClF,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI;;;;cAC9B,mBAAmB;;;;;;QAKnB,MAAM,GAAC,MAAM;;;;UACb,MAAM;;;;;;;;;;sBAMN,MAAM;;;;YAEjB;QAA2B,UAAU;QACX,EAAE,EAAjB,MAAM;QACS,IAAI,EAAnB,MAAM;QACU,QAAQ;KACrC"}
|
|
@@ -7,21 +7,5 @@
|
|
|
7
7
|
* It is not recommended for use in production environments and will not receive support for issues.
|
|
8
8
|
*/
|
|
9
9
|
export function setupRegisterAPI(agent: any): void;
|
|
10
|
-
/**
|
|
11
|
-
* Builds the api object that will be returned from the register api method.
|
|
12
|
-
* Also conducts certain side-effects, such as harvesting a PageView event when triggered and gathering metadata for the registered entity.
|
|
13
|
-
* @param {Object} agentRef the reference to the base agent instance
|
|
14
|
-
* @param {Object} handlers the shared handlers to be used by both the base agent's API and the external target's API
|
|
15
|
-
* @param {Object} target the target information to be used by the external target's API to send data to the correct location
|
|
16
|
-
* @param {string} [target.licenseKey] the license key of the target to report data to
|
|
17
|
-
* @param {string} target.id the entity ID of the target to report data to
|
|
18
|
-
* @param {string} target.name the entity name of the target to report data to
|
|
19
|
-
* @returns {RegisterAPI} the api object to be returned from the register api method
|
|
20
|
-
*/
|
|
21
|
-
export function buildRegisterApi(agentRef: Object, target: {
|
|
22
|
-
licenseKey?: string | undefined;
|
|
23
|
-
id: string;
|
|
24
|
-
name: string;
|
|
25
|
-
}): RegisterAPI;
|
|
26
10
|
export type RegisterAPI = import("./register-api-types").RegisterAPI;
|
|
27
11
|
//# sourceMappingURL=register.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/register.js"],"names":[],"mappings":"AAmBA;;GAEG;AAEH;;;;GAIG;AACH,mDAIC;
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/register.js"],"names":[],"mappings":"AAmBA;;GAEG;AAEH;;;;GAIG;AACH,mDAIC;0BAZY,OAAO,sBAAsB,EAAE,WAAW"}
|
package/package.json
CHANGED
|
@@ -19,9 +19,19 @@ const ReadOnly = {
|
|
|
19
19
|
originTime
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
const hiddenState = {
|
|
23
|
+
consented: false
|
|
24
|
+
}
|
|
25
|
+
|
|
22
26
|
const RuntimeModel = {
|
|
23
27
|
/** Agent-specific metadata found in the RUM call response. ex. entityGuid */
|
|
24
28
|
appMetadata: {},
|
|
29
|
+
get consented () {
|
|
30
|
+
return this.session?.state?.consent || hiddenState.consented
|
|
31
|
+
},
|
|
32
|
+
set consented (value) {
|
|
33
|
+
hiddenState.consented = value
|
|
34
|
+
},
|
|
25
35
|
customTransaction: undefined,
|
|
26
36
|
denyList: undefined,
|
|
27
37
|
disabled: false,
|
|
@@ -59,7 +59,7 @@ export class Harvester {
|
|
|
59
59
|
triggerHarvestFor (aggregateInst, localOpts = {}) {
|
|
60
60
|
const output = { ranSend: false, payload: undefined, endpointVersion: aggregateInst.harvestEndpointVersion || 1 }
|
|
61
61
|
if (aggregateInst.blocked) return output
|
|
62
|
-
if (this.agentRef.init?.browser_consent_mode?.enabled && !this.agentRef.runtime
|
|
62
|
+
if (this.agentRef.init?.browser_consent_mode?.enabled && !this.agentRef.runtime.consented) return output
|
|
63
63
|
|
|
64
64
|
const submitMethod = getSubmitMethod(localOpts)
|
|
65
65
|
if (!submitMethod) return output
|
package/src/common/util/mfe.js
CHANGED
|
@@ -11,8 +11,14 @@ export function isValidMFETarget (target = {}) {
|
|
|
11
11
|
return !!(target.id && target.name)
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
export function hasValidValue (val) {
|
|
15
|
+
return (typeof val === 'string' && val.trim().length < 501) || (typeof val === 'number')
|
|
16
|
+
}
|
|
17
|
+
|
|
14
18
|
/**
|
|
15
19
|
* When given a valid target, returns an object with the MFE payload attributes. Returns an empty object otherwise.
|
|
20
|
+
* @note Field names may change as the schema is finalized
|
|
21
|
+
*
|
|
16
22
|
* @param {Object} [target] the registered target
|
|
17
23
|
* @param {AggregateInstance} [aggregateInstance] the aggregate instance calling the method
|
|
18
24
|
* @returns {{'mfe.id': *, 'mfe.name': String}|{}} returns an empty object if args are not supplied or the aggregate instance is not supporting version 2
|
|
@@ -27,9 +33,9 @@ export function getVersion2Attributes (target, aggregateInstance) {
|
|
|
27
33
|
}
|
|
28
34
|
}
|
|
29
35
|
return {
|
|
30
|
-
'mfe.id': target.id,
|
|
31
|
-
'mfe.name': target.name,
|
|
32
|
-
eventSource:
|
|
33
|
-
'parent.id': containerAgentEntityGuid
|
|
36
|
+
'mfe.id': target.id,
|
|
37
|
+
'mfe.name': target.name,
|
|
38
|
+
eventSource: target.eventSource,
|
|
39
|
+
'parent.id': target.parent?.id || containerAgentEntityGuid
|
|
34
40
|
}
|
|
35
41
|
}
|
|
@@ -58,14 +58,6 @@ export function setupAgentSession (agentRef) {
|
|
|
58
58
|
|
|
59
59
|
registerHandler('api-consent', (accept) => {
|
|
60
60
|
agentRef.runtime.session.write({ consent: accept === undefined ? true : accept })
|
|
61
|
-
|
|
62
|
-
// call sendRum if it wasn't called yet
|
|
63
|
-
agentRef.features.page_view_event.onAggregateImported.then((loaded) => {
|
|
64
|
-
const pveAgg = agentRef.features.page_view_event.featAggregate
|
|
65
|
-
if (loaded && !pveAgg.sentRum) {
|
|
66
|
-
pveAgg.sendRum()
|
|
67
|
-
}
|
|
68
|
-
})
|
|
69
61
|
}, 'session', sharedEE)
|
|
70
62
|
|
|
71
63
|
drain(agentRef.agentIdentifier, 'session')
|
|
@@ -8,11 +8,24 @@ import { handle } from '../../common/event-emitter/handle'
|
|
|
8
8
|
import { warn } from '../../common/util/console'
|
|
9
9
|
|
|
10
10
|
export function setupConsentAPI (agent) {
|
|
11
|
-
setupAPI(CONSENT, function (accept) {
|
|
12
|
-
if (
|
|
11
|
+
setupAPI(CONSENT, function (accept = true) {
|
|
12
|
+
if (typeof accept !== 'boolean') {
|
|
13
13
|
warn(65, typeof accept)
|
|
14
14
|
return
|
|
15
15
|
}
|
|
16
|
-
|
|
16
|
+
/** harvester, by way of "consented" getter, checks session state first, and falls back on runtime state if not available. Set both here */
|
|
17
|
+
handle(prefix + CONSENT, [accept], undefined, 'session', agent.ee) // sets session state (if available)
|
|
18
|
+
agent.runtime.consented = accept // sets runtime state
|
|
19
|
+
|
|
20
|
+
/** if consent is granted, attempt to make a PageView event harvest if one has not already been made */
|
|
21
|
+
if (accept) {
|
|
22
|
+
const pveInst = agent.features.page_view_event
|
|
23
|
+
pveInst.onAggregateImported.then((loaded) => {
|
|
24
|
+
const pveAgg = pveInst.featAggregate
|
|
25
|
+
if (loaded && !pveAgg.sentRum) {
|
|
26
|
+
pveAgg.sendRum()
|
|
27
|
+
}
|
|
28
|
+
})
|
|
29
|
+
}
|
|
17
30
|
}, agent)
|
|
18
31
|
}
|
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
* @property {(name: string, attributes?: object) => void} addPageAction - Add a page action for the registered entity.
|
|
9
9
|
* @property {(message: string, options?: { customAttributes?: object, level?: 'ERROR' | 'TRACE' | 'DEBUG' | 'INFO' | 'WARN'}) => void} log - Capture a log for the registered entity.
|
|
10
10
|
* @property {(error: Error | string, customAttributes?: object) => void} noticeError - Notice an error for the registered entity.
|
|
11
|
+
* @property {(target: RegisterAPIConstructor) => RegisterAPI} register - Record a custom event for the registered entity.
|
|
11
12
|
* @property {(eventType: string, attributes?: Object) => void} recordCustomEvent - Record a custom event for the registered entity.
|
|
12
|
-
* @property {(eventType: string, options?: {start: number, end: number, duration: number, customAttributes: object}) => {
|
|
13
|
+
* @property {(eventType: string, options?: {start: number, end: number, duration: number, customAttributes: object}) => ({start: number, end: number, duration: number, customAttributes: object})} measure - Measures a task that is recorded as a BrowserPerformance event.
|
|
13
14
|
* @property {(value: string | null) => void} setApplicationVersion - Add an application.version attribute to all outgoing data for the registered entity.
|
|
14
15
|
* @property {(name: string, value: string | number | boolean | null, persist?: boolean) => void} setCustomAttribute - Add a custom attribute to outgoing data for the registered entity.
|
|
15
16
|
* @property {(value: string | null) => void} setUserId - Add an enduser.id attribute to all outgoing API data for the registered entity.
|
|
@@ -20,15 +21,17 @@
|
|
|
20
21
|
* @typedef {Object} RegisterAPIConstructor
|
|
21
22
|
* @property {string|number} id - The unique id for the registered entity. This will be assigned to any synthesized entities.
|
|
22
23
|
* @property {string} name - The readable name for the registered entity. This will be assigned to any synthesized entities.
|
|
24
|
+
* @property {string} [parentId] - The parentId for the registered entity. If none was supplied, it will assume the entity guid from the main agent.
|
|
23
25
|
*/
|
|
24
26
|
|
|
25
27
|
/**
|
|
26
28
|
* @typedef {Object} RegisterAPIMetadata
|
|
27
29
|
* @property {Object} customAttributes - The custom attributes for the registered entity.
|
|
28
30
|
* @property {Object} target - The options for the registered entity.
|
|
29
|
-
* @property {string} target.licenseKey - The license key for the registered entity. If none was supplied, it will assume the license key from the main agent.
|
|
31
|
+
* @property {string} [target.licenseKey] - The license key for the registered entity. If none was supplied, it will assume the license key from the main agent.
|
|
30
32
|
* @property {string} target.id - The ID for the registered entity.
|
|
31
33
|
* @property {string} target.name - The name returned for the registered entity.
|
|
34
|
+
* @property {string} [target.parentId] - The parentId for the registered entity. If none was supplied, it will assume the entity guid from the main agent.
|
|
32
35
|
*/
|
|
33
36
|
|
|
34
37
|
export default {}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { handle } from '../../common/event-emitter/handle'
|
|
6
6
|
import { warn } from '../../common/util/console'
|
|
7
|
-
import { isValidMFETarget } from '../../common/util/mfe'
|
|
7
|
+
import { hasValidValue, isValidMFETarget } from '../../common/util/mfe'
|
|
8
8
|
import { FEATURE_NAMES } from '../features/features'
|
|
9
9
|
import { now } from '../../common/timing/now'
|
|
10
10
|
import { SUPPORTABILITY_METRIC_CHANNEL } from '../../features/metrics/constants'
|
|
@@ -28,7 +28,7 @@ import { recordCustomEvent } from './recordCustomEvent'
|
|
|
28
28
|
*/
|
|
29
29
|
export function setupRegisterAPI (agent) {
|
|
30
30
|
setupAPI(REGISTER, function (target) {
|
|
31
|
-
return
|
|
31
|
+
return register(agent, target)
|
|
32
32
|
}, agent)
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -36,20 +36,19 @@ export function setupRegisterAPI (agent) {
|
|
|
36
36
|
* Builds the api object that will be returned from the register api method.
|
|
37
37
|
* Also conducts certain side-effects, such as harvesting a PageView event when triggered and gathering metadata for the registered entity.
|
|
38
38
|
* @param {Object} agentRef the reference to the base agent instance
|
|
39
|
-
* @param {
|
|
40
|
-
* @param {
|
|
41
|
-
* @param {string} [target.licenseKey] the license key of the target to report data to
|
|
42
|
-
* @param {string} target.id the entity ID of the target to report data to
|
|
43
|
-
* @param {string} target.name the entity name of the target to report data to
|
|
39
|
+
* @param {import('./register-api-types').RegisterAPIConstructor} target
|
|
40
|
+
* @param {import('./register-api-types').RegisterAPIConstructor} [parent]
|
|
44
41
|
* @returns {RegisterAPI} the api object to be returned from the register api method
|
|
45
42
|
*/
|
|
46
|
-
|
|
43
|
+
function register (agentRef, target, parent) {
|
|
47
44
|
const attrs = {}
|
|
48
45
|
warn(54, 'newrelic.register')
|
|
49
46
|
|
|
50
47
|
target ||= {}
|
|
48
|
+
target.eventSource = 'MicroFrontendBrowserAgent'
|
|
51
49
|
target.licenseKey ||= agentRef.info.licenseKey // will inherit the license key from the container agent if not provided for brevity. A future state may dictate that we need different license keys to do different things.
|
|
52
50
|
target.blocked = false
|
|
51
|
+
target.parent = parent || {}
|
|
53
52
|
|
|
54
53
|
/** @type {Function} a function that is set and reports when APIs are triggered -- warns the customer of the invalid state */
|
|
55
54
|
let invalidApiResponse = () => {}
|
|
@@ -75,6 +74,9 @@ export function buildRegisterApi (agentRef, target) {
|
|
|
75
74
|
/** primary cases that can block the register API from working at init time */
|
|
76
75
|
if (!agentRef.init.api.allow_registered_children) block(single(() => warn(55)))
|
|
77
76
|
if (!isValidMFETarget(target)) block(single(() => warn(48, target)))
|
|
77
|
+
if (!hasValidValue(target.id) || !hasValidValue(target.name)) {
|
|
78
|
+
block(single(() => warn(48, target)))
|
|
79
|
+
}
|
|
78
80
|
|
|
79
81
|
/** @type {RegisterAPI} */
|
|
80
82
|
const api = {
|
|
@@ -82,6 +84,7 @@ export function buildRegisterApi (agentRef, target) {
|
|
|
82
84
|
log: (message, options = {}) => report(log, [message, { ...options, customAttributes: { ...attrs, ...(options.customAttributes || {}) } }, agentRef], target),
|
|
83
85
|
measure: (name, options = {}) => report(measure, [name, { ...options, customAttributes: { ...attrs, ...(options.customAttributes || {}) } }, agentRef], target),
|
|
84
86
|
noticeError: (error, attributes = {}) => report(noticeError, [error, { ...attrs, ...attributes }, agentRef], target),
|
|
87
|
+
register: (target = {}) => report(register, [agentRef, target], api.metadata.target),
|
|
85
88
|
recordCustomEvent: (eventType, attributes = {}) => report(recordCustomEvent, [eventType, { ...attrs, ...attributes }, agentRef], target),
|
|
86
89
|
setApplicationVersion: (value) => setLocalValue('application.version', value),
|
|
87
90
|
setCustomAttribute: (key, value) => setLocalValue(key, value),
|
|
@@ -130,8 +133,8 @@ export function buildRegisterApi (agentRef, target) {
|
|
|
130
133
|
const timestamp = now()
|
|
131
134
|
handle(SUPPORTABILITY_METRIC_CHANNEL, [`API/register/${methodToCall.name}/called`], undefined, FEATURE_NAMES.metrics, agentRef.ee)
|
|
132
135
|
try {
|
|
133
|
-
const shouldDuplicate = agentRef.init.api.duplicate_registered_data
|
|
134
|
-
if (shouldDuplicate
|
|
136
|
+
const shouldDuplicate = agentRef.init.api.duplicate_registered_data && methodToCall.name !== 'register'
|
|
137
|
+
if (shouldDuplicate) {
|
|
135
138
|
// also report to container by providing undefined target
|
|
136
139
|
methodToCall(...args, undefined, timestamp)
|
|
137
140
|
}
|