@crimson-education/browser-logger 4.1.4 → 5.0.0-beta.10
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/README.md +81 -29
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +22 -41
- package/lib/index.js.map +1 -1
- package/lib/logger/consoleTransport.d.ts +1 -1
- package/lib/logger/consoleTransport.d.ts.map +1 -1
- package/lib/logger/consoleTransport.js +16 -22
- package/lib/logger/consoleTransport.js.map +1 -1
- package/lib/logger/datadogTransport.d.ts +1 -1
- package/lib/logger/datadogTransport.d.ts.map +1 -1
- package/lib/logger/datadogTransport.js +4 -8
- package/lib/logger/datadogTransport.js.map +1 -1
- package/lib/logger/index.js +29 -49
- package/lib/logger/index.js.map +1 -1
- package/lib/logger/index.test.js +16 -18
- package/lib/logger/index.test.js.map +1 -1
- package/lib/logger/utils.js +4 -9
- package/lib/logger/utils.js.map +1 -1
- package/lib/reporters/amplifyReporter.d.ts +4 -4
- package/lib/reporters/amplifyReporter.d.ts.map +1 -1
- package/lib/reporters/amplifyReporter.js +210 -133
- package/lib/reporters/amplifyReporter.js.map +1 -1
- package/lib/reporters/amplifyReporter.test.js +9 -12
- package/lib/reporters/amplifyReporter.test.js.map +1 -1
- package/lib/reporters/datadogReporter.d.ts +1 -1
- package/lib/reporters/datadogReporter.d.ts.map +1 -1
- package/lib/reporters/datadogReporter.js +118 -48
- package/lib/reporters/datadogReporter.js.map +1 -1
- package/lib/reporters/gtmReporter.d.ts +1 -1
- package/lib/reporters/gtmReporter.d.ts.map +1 -1
- package/lib/reporters/gtmReporter.js +1 -5
- package/lib/reporters/gtmReporter.js.map +1 -1
- package/lib/reporters/index.js +46 -71
- package/lib/reporters/index.js.map +1 -1
- package/lib/reporters/logReporter.js +24 -34
- package/lib/reporters/logReporter.js.map +1 -1
- package/lib/types/index.js +2 -18
- package/lib/types/index.js.map +1 -1
- package/lib/types/logger.d.ts +3 -3
- package/lib/types/logger.d.ts.map +1 -1
- package/lib/types/logger.js +2 -5
- package/lib/types/logger.js.map +1 -1
- package/lib/types/reporter.d.ts +6 -6
- package/lib/types/reporter.d.ts.map +1 -1
- package/lib/types/reporter.js +1 -2
- package/lib/utils.js +1 -5
- package/lib/utils.js.map +1 -1
- package/lib/utils.test.js +2 -4
- package/lib/utils.test.js.map +1 -1
- package/package.json +14 -16
- package/src/reporters/amplifyReporter.ts +233 -138
- package/src/reporters/datadogReporter.ts +107 -19
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crimson-education/browser-logger",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0-beta.10",
|
|
4
4
|
"description": "An abstract logger and reporting utility for browser environments",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"prepack": "npm run build",
|
|
@@ -28,24 +28,22 @@
|
|
|
28
28
|
},
|
|
29
29
|
"homepage": "https://github.com/crimson-education/browser-logger#readme",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@
|
|
32
|
-
"@
|
|
31
|
+
"@aws-sdk/client-cognito-identity": "^3.844.0",
|
|
32
|
+
"@aws-sdk/protocol-http": "^3.370.0",
|
|
33
|
+
"@datadog/browser-logs": "^6.13.0",
|
|
34
|
+
"@datadog/browser-rum": "^6.13.0",
|
|
35
|
+
"aws-amplify": "^6.15.3"
|
|
33
36
|
},
|
|
34
37
|
"devDependencies": {
|
|
35
38
|
"@crimson-education/eslint-config": "^2.1.0",
|
|
36
|
-
"@types/jest": "^
|
|
37
|
-
"eslint": "^
|
|
38
|
-
"eslint-config-prettier": "^
|
|
39
|
-
"eslint-plugin-jest": "^
|
|
40
|
-
"jest": "^
|
|
41
|
-
"rimraf": "^
|
|
42
|
-
"ts-jest": "^
|
|
43
|
-
"typescript": "
|
|
44
|
-
},
|
|
45
|
-
"peerDependencies": {
|
|
46
|
-
"@aws-amplify/analytics": ">=5.2.22",
|
|
47
|
-
"@aws-amplify/auth": ">=4.6.8",
|
|
48
|
-
"@aws-sdk/client-pinpoint": ">=3.370.0"
|
|
39
|
+
"@types/jest": "^29.5.12",
|
|
40
|
+
"eslint": "^8.57.0",
|
|
41
|
+
"eslint-config-prettier": "^9.1.0",
|
|
42
|
+
"eslint-plugin-jest": "^28.9.0",
|
|
43
|
+
"jest": "^29.7.0",
|
|
44
|
+
"rimraf": "^5.0.5",
|
|
45
|
+
"ts-jest": "^29.1.2",
|
|
46
|
+
"typescript": "5.1.6"
|
|
49
47
|
},
|
|
50
48
|
"files": [
|
|
51
49
|
"lib",
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { PinpointClient, ServiceInputTypes, ServiceOutputTypes } from '@aws-sdk/client-pinpoint';
|
|
1
|
+
import { identifyUser, record } from '@aws-amplify/analytics';
|
|
2
|
+
// import { Endpoint, FinalizeRequestMiddleware } from '@aws-sdk/types';
|
|
3
|
+
// import { HttpRequest } from '@aws-sdk/protocol-http';
|
|
4
|
+
// import { PinpointClient, ServiceInputTypes, ServiceOutputTypes } from '@aws-sdk/client-pinpoint';
|
|
6
5
|
|
|
7
6
|
import {
|
|
8
7
|
IReporter,
|
|
@@ -14,12 +13,142 @@ import {
|
|
|
14
13
|
ServiceInfo,
|
|
15
14
|
} from '../types';
|
|
16
15
|
import { logger } from '../logger';
|
|
16
|
+
// Note: fetchAuthSession was previously imported but unused; removing to satisfy linter
|
|
17
|
+
import { Amplify } from 'aws-amplify';
|
|
17
18
|
|
|
18
19
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
19
20
|
type AttributeMap = Record<string, string[] | string | null>;
|
|
20
21
|
|
|
21
22
|
type AmplifyAutoTrackSource = 'pageView' | 'event' | 'session';
|
|
22
23
|
|
|
24
|
+
// Auto-tracking implementation for Gen2
|
|
25
|
+
class AmplifyAutoTracker {
|
|
26
|
+
private config: AmplifyReporterConfig;
|
|
27
|
+
private allMetadata: AttributeMap;
|
|
28
|
+
private currentUser: ReportUser | null = null;
|
|
29
|
+
private sessionStartTime: number = Date.now();
|
|
30
|
+
private pageViewCount: number = 0;
|
|
31
|
+
private lastPageUrl: string = window.location.href;
|
|
32
|
+
private isPageVisible: boolean = !document.hidden;
|
|
33
|
+
|
|
34
|
+
constructor(config: AmplifyReporterConfig, allMetadata: AttributeMap) {
|
|
35
|
+
this.config = config;
|
|
36
|
+
this.allMetadata = allMetadata;
|
|
37
|
+
this.setupEventListeners();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private setupEventListeners() {
|
|
41
|
+
// Page visibility tracking
|
|
42
|
+
document.addEventListener('visibilitychange', () => {
|
|
43
|
+
this.isPageVisible = !document.hidden;
|
|
44
|
+
if (this.config.autoTrackSessions) {
|
|
45
|
+
this.trackSessionState();
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Page view tracking
|
|
50
|
+
if (this.config.autoTrackPageViews) {
|
|
51
|
+
this.trackPageView();
|
|
52
|
+
|
|
53
|
+
// Track route changes for SPAs
|
|
54
|
+
let currentUrl = window.location.href;
|
|
55
|
+
const observer = new MutationObserver(() => {
|
|
56
|
+
if (window.location.href !== currentUrl) {
|
|
57
|
+
currentUrl = window.location.href;
|
|
58
|
+
this.trackPageView();
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// User interaction tracking
|
|
65
|
+
if (this.config.autoTrackEvents) {
|
|
66
|
+
this.setupInteractionTracking();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private trackPageView() {
|
|
71
|
+
this.pageViewCount++;
|
|
72
|
+
const pageViewEvent = {
|
|
73
|
+
message: 'Page View',
|
|
74
|
+
metadata: {
|
|
75
|
+
url: window.location.href,
|
|
76
|
+
title: document.title,
|
|
77
|
+
referrer: document.referrer,
|
|
78
|
+
pageViewCount: this.pageViewCount,
|
|
79
|
+
...this.getAutoTrackMetadata('pageView'),
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
record({
|
|
84
|
+
name: pageViewEvent.message,
|
|
85
|
+
attributes: asAttributeMap(pageViewEvent.metadata, false) as Record<string, string>,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private trackSessionState() {
|
|
90
|
+
const sessionDuration = Date.now() - this.sessionStartTime;
|
|
91
|
+
const sessionEvent = {
|
|
92
|
+
message: this.isPageVisible ? 'Session Active' : 'Session Inactive',
|
|
93
|
+
metadata: {
|
|
94
|
+
sessionDuration,
|
|
95
|
+
isVisible: this.isPageVisible,
|
|
96
|
+
...this.getAutoTrackMetadata('session'),
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
record({
|
|
101
|
+
name: sessionEvent.message,
|
|
102
|
+
attributes: asAttributeMap(sessionEvent.metadata, false) as Record<string, string>,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
private setupInteractionTracking() {
|
|
107
|
+
const selectorPrefix = this.config.selectorPrefix ?? 'data-analytics-';
|
|
108
|
+
|
|
109
|
+
document.addEventListener('click', (event) => {
|
|
110
|
+
const target = event.target as HTMLElement;
|
|
111
|
+
if (!target) return;
|
|
112
|
+
|
|
113
|
+
// Find the closest element with analytics attributes
|
|
114
|
+
const analyticsElement = target.closest(`[${selectorPrefix}name]`);
|
|
115
|
+
if (!analyticsElement) return;
|
|
116
|
+
|
|
117
|
+
const analyticsName = analyticsElement.getAttribute(`${selectorPrefix}name`);
|
|
118
|
+
if (!analyticsName) return;
|
|
119
|
+
|
|
120
|
+
const interactionEvent = {
|
|
121
|
+
message: 'User Interaction',
|
|
122
|
+
metadata: {
|
|
123
|
+
elementName: analyticsName,
|
|
124
|
+
elementType: target.tagName.toLowerCase(),
|
|
125
|
+
elementText: target.textContent?.slice(0, 100),
|
|
126
|
+
interactionType: 'click',
|
|
127
|
+
...this.getAutoTrackMetadata('event'),
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
record({
|
|
132
|
+
name: interactionEvent.message,
|
|
133
|
+
attributes: asAttributeMap(interactionEvent.metadata, false) as Record<string, string>,
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
private getAutoTrackMetadata(source: AmplifyAutoTrackSource): Metadata {
|
|
139
|
+
const { beforeAutoTrack } = this.config;
|
|
140
|
+
return typeof beforeAutoTrack === 'function' ? (beforeAutoTrack(source) ?? {}) : {};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
public setUser(user: ReportUser | null) {
|
|
144
|
+
this.currentUser = user;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
public updateMetadata(metadata: AttributeMap) {
|
|
148
|
+
Object.assign(this.allMetadata, metadata);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
23
152
|
export interface AmplifyReporterConfig extends ReporterConfigBase {
|
|
24
153
|
/**
|
|
25
154
|
* AWS Region for Amplify.
|
|
@@ -29,7 +158,7 @@ export interface AmplifyReporterConfig extends ReporterConfigBase {
|
|
|
29
158
|
* The Identity Pool Id to use for reporting, if set to false, Auth.configure is not called.
|
|
30
159
|
* This must be called manually for the reporter to work.
|
|
31
160
|
*/
|
|
32
|
-
identityPoolId: string
|
|
161
|
+
identityPoolId: string;
|
|
33
162
|
/**
|
|
34
163
|
* The Pinpoint App Id to report to.
|
|
35
164
|
*/
|
|
@@ -96,19 +225,21 @@ type AmplifyReporterBufferingConfig = {
|
|
|
96
225
|
};
|
|
97
226
|
|
|
98
227
|
export function amplifyReporter(info: ServiceInfo, config: AmplifyReporterConfig): IReporter {
|
|
99
|
-
|
|
100
|
-
Auth
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
228
|
+
Amplify.configure({
|
|
229
|
+
Auth: {
|
|
230
|
+
Cognito: {
|
|
231
|
+
identityPoolId: config.identityPoolId,
|
|
232
|
+
allowGuestAccess: true,
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
Analytics: {
|
|
236
|
+
Pinpoint: {
|
|
237
|
+
appId: config.analyticsAppId,
|
|
238
|
+
region: config.region,
|
|
239
|
+
...config.buffering,
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
});
|
|
112
243
|
|
|
113
244
|
const allMetadata = asAttributeMap({
|
|
114
245
|
appName: info.service,
|
|
@@ -118,48 +249,16 @@ export function amplifyReporter(info: ServiceInfo, config: AmplifyReporterConfig
|
|
|
118
249
|
version: info.version,
|
|
119
250
|
});
|
|
120
251
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
appId: config.analyticsAppId,
|
|
124
|
-
endpoint: {
|
|
125
|
-
attributes: allMetadata,
|
|
126
|
-
},
|
|
127
|
-
...config.buffering,
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
// Session autotracking is enabled by default for backwards compatibility reasons, so we _must_
|
|
131
|
-
// call this unconditionally to ensure we opt out of session tracking when `autoTrackSessions` isn't set
|
|
132
|
-
// See: https://docs.amplify.aws/lib/analytics/autotrack/q/platform/js/#session-tracking
|
|
133
|
-
Analytics.autoTrack('session', {
|
|
134
|
-
enable: config.autoTrackSessions === true,
|
|
135
|
-
attributes: wrapAutoTrackMiddleware('session'),
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
if (config.autoTrackPageViews) {
|
|
139
|
-
Analytics.autoTrack('pageView', {
|
|
140
|
-
enable: true,
|
|
141
|
-
eventName: 'pageView',
|
|
142
|
-
type: 'SPA',
|
|
143
|
-
provider: 'AWSPinpoint',
|
|
144
|
-
attributes: wrapAutoTrackMiddleware('pageView'),
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
if (config.autoTrackEvents) {
|
|
149
|
-
Analytics.autoTrack('event', {
|
|
150
|
-
enable: true,
|
|
151
|
-
selectorPrefix: config.selectorPrefix ?? 'data-analytics-',
|
|
152
|
-
attributes: wrapAutoTrackMiddleware('event'),
|
|
153
|
-
});
|
|
154
|
-
}
|
|
252
|
+
// Initialize auto-tracker for Gen2
|
|
253
|
+
const autoTracker = new AmplifyAutoTracker(config, allMetadata);
|
|
155
254
|
|
|
156
255
|
if (config.proxyUrl) {
|
|
157
|
-
installPinpointProxy(new URL(config.proxyUrl));
|
|
256
|
+
// installPinpointProxy(new URL(config.proxyUrl));
|
|
158
257
|
}
|
|
159
258
|
|
|
160
259
|
const reporter: IReporter = {
|
|
161
260
|
trackEvent: function (event: ReporterEvent): void {
|
|
162
|
-
|
|
261
|
+
record({
|
|
163
262
|
name: event.message,
|
|
164
263
|
attributes: asAttributeMap(
|
|
165
264
|
{
|
|
@@ -169,8 +268,6 @@ export function amplifyReporter(info: ServiceInfo, config: AmplifyReporterConfig
|
|
|
169
268
|
false,
|
|
170
269
|
) as Record<string, string>,
|
|
171
270
|
metrics: event.metrics,
|
|
172
|
-
}).catch(() => {
|
|
173
|
-
// Swallow; see: https://crimsonhq.slack.com/archives/G4UN6Q4KF/p1648599302847539
|
|
174
271
|
});
|
|
175
272
|
},
|
|
176
273
|
addBreadcrumb: function (breadcrumb: ReporterBreadcrumb): void {
|
|
@@ -184,11 +281,9 @@ export function amplifyReporter(info: ServiceInfo, config: AmplifyReporterConfig
|
|
|
184
281
|
},
|
|
185
282
|
addMetadata: function (metadata: Metadata): void {
|
|
186
283
|
Object.assign(allMetadata, asAttributeMap(metadata, true));
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
// Swallow; see: https://crimsonhq.slack.com/archives/G4UN6Q4KF/p1648599302847539
|
|
191
|
-
});
|
|
284
|
+
autoTracker.updateMetadata(asAttributeMap(metadata, true));
|
|
285
|
+
// Note: updateEndpoint is not available in Amplify v7
|
|
286
|
+
// Metadata updates would need to be handled differently
|
|
192
287
|
},
|
|
193
288
|
setUser: function (user: ReportUser | null): void {
|
|
194
289
|
const userMetadata = user
|
|
@@ -197,19 +292,14 @@ export function amplifyReporter(info: ServiceInfo, config: AmplifyReporterConfig
|
|
|
197
292
|
})
|
|
198
293
|
: {};
|
|
199
294
|
Object.assign(allMetadata, asAttributeMap(userMetadata, true));
|
|
200
|
-
|
|
295
|
+
autoTracker.setUser(user);
|
|
296
|
+
// Note: updateEndpoint is not available in Amplify v7
|
|
297
|
+
// User updates would need to be handled differently
|
|
298
|
+
identifyUser({
|
|
201
299
|
userId: user?.id ?? '',
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
id: user.id,
|
|
206
|
-
email: user.email,
|
|
207
|
-
name: user.name ?? user.email,
|
|
208
|
-
username: user.username,
|
|
209
|
-
})
|
|
210
|
-
: {},
|
|
211
|
-
}).catch(() => {
|
|
212
|
-
// Swallow; see: https://crimsonhq.slack.com/archives/G4UN6Q4KF/p1648599302847539
|
|
300
|
+
userProfile: {
|
|
301
|
+
email: user?.email,
|
|
302
|
+
},
|
|
213
303
|
});
|
|
214
304
|
},
|
|
215
305
|
setRouteName: function (routeName: string): void {
|
|
@@ -232,8 +322,8 @@ export function asAttributeMap(values: Record<string, unknown>, groupValues = tr
|
|
|
232
322
|
const checkedEntries = Object.entries(attributeMap).map(([key, value]) => {
|
|
233
323
|
const truncatedKey = key.length > 50 ? `___${key.slice(-47)}` : key;
|
|
234
324
|
const truncatedValue = Array.isArray(value)
|
|
235
|
-
? value?.map((val) => val.slice(0, 100)) ?? null
|
|
236
|
-
: value?.slice(0, 100) ?? null;
|
|
325
|
+
? (value?.map((val) => val.slice(0, 100)) ?? null)
|
|
326
|
+
: (value?.slice(0, 100) ?? null);
|
|
237
327
|
|
|
238
328
|
return [truncatedKey, truncatedValue];
|
|
239
329
|
});
|
|
@@ -264,8 +354,13 @@ export function buildAttributeMap(
|
|
|
264
354
|
Object.entries(values).forEach(([key, value]) => {
|
|
265
355
|
const combinedKey = parentKey ? [parentKey, key].join('.') : key;
|
|
266
356
|
|
|
267
|
-
|
|
268
|
-
|
|
357
|
+
// Only treat undefined or null as empty; avoid converting falsy values like ''/0/false to null
|
|
358
|
+
if (value === undefined || value === null) {
|
|
359
|
+
// For event attributes (groupValues === false), Pinpoint rejects null values.
|
|
360
|
+
// In that case we omit the key entirely to avoid "Event attribute value can not be null".
|
|
361
|
+
if (groupValues) {
|
|
362
|
+
valuesWithStringArrays[combinedKey] = null;
|
|
363
|
+
}
|
|
269
364
|
} else if (groupValues && Array.isArray(value)) {
|
|
270
365
|
valuesWithStringArrays[combinedKey] = value.map((element) =>
|
|
271
366
|
typeof element === 'string' ? element : JSON.stringify(element),
|
|
@@ -282,63 +377,63 @@ export function buildAttributeMap(
|
|
|
282
377
|
return valuesWithStringArrays;
|
|
283
378
|
}
|
|
284
379
|
|
|
285
|
-
function installPinpointProxy(proxyUrl: URL) {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
}
|
|
380
|
+
// function installPinpointProxy(proxyUrl: URL) {
|
|
381
|
+
// // No public API for overriding where the Pinpoint client sends events to... 🤮
|
|
382
|
+
// // In theory you can pass in an `endpoint` to the Pinpoint client's constructor like any other AWS
|
|
383
|
+
// // client, but Amplify's analytics doesn't expose anything we can use to get an endpoint threaded
|
|
384
|
+
// // down to the Pinpoint client's constructor.
|
|
385
|
+
// //
|
|
386
|
+
// // The Pinpoint client _also_ isn't available synchronously because it is instantiated when events
|
|
387
|
+
// // get sent out, and then reconfigured whenever the API credentials change. We need to hook `_initClients`
|
|
388
|
+
// // to ensure that the Pinpoint client being used is always patched with our custom endpoint.
|
|
389
|
+
// const provider = (globalThis as any).Analytics?.getPluggable?.('AWSPinpoint') as any;
|
|
390
|
+
// if (!provider || typeof provider._initClients !== 'function') {
|
|
391
|
+
// logger.error(
|
|
392
|
+
// 'Installation of the Pinpoint proxy failed. This likely means the internals of the @aws-amplify/analytics package have changed.',
|
|
393
|
+
// );
|
|
394
|
+
// return;
|
|
395
|
+
// }
|
|
396
|
+
|
|
397
|
+
// const originalInitClients = provider._initClients;
|
|
398
|
+
// const requestMiddleware: FinalizeRequestMiddleware<ServiceInputTypes, ServiceOutputTypes> =
|
|
399
|
+
// (next) => async (args) => {
|
|
400
|
+
// const pinpointClient = provider.pinpointClient as PinpointClient | undefined;
|
|
401
|
+
|
|
402
|
+
// if (pinpointClient && proxyUrl.pathname !== '/' && HttpRequest.isInstance(args.request)) {
|
|
403
|
+
// // Add proxyUrl.pathname to final request url if it was provided
|
|
404
|
+
// const shouldStripSlash = proxyUrl.pathname.endsWith('/');
|
|
405
|
+
// args.request.path = `${proxyUrl.pathname}${args.request.path.slice(shouldStripSlash ? 1 : 0)}`;
|
|
406
|
+
|
|
407
|
+
// // Wrap request body so the proxy has signing info
|
|
408
|
+
// if (typeof args.request.body === 'string') {
|
|
409
|
+
// const credentials = await pinpointClient.config.credentials();
|
|
410
|
+
// args.request.body = JSON.stringify({
|
|
411
|
+
// credentials,
|
|
412
|
+
// data: JSON.parse(args.request.body),
|
|
413
|
+
// });
|
|
414
|
+
// }
|
|
415
|
+
// }
|
|
416
|
+
|
|
417
|
+
// return next(args);
|
|
418
|
+
// };
|
|
419
|
+
|
|
420
|
+
// provider._initClients = async (credentials: unknown) => {
|
|
421
|
+
// const result = await originalInitClients.call(provider, credentials);
|
|
422
|
+
// const pinpointClient = provider.pinpointClient as PinpointClient | undefined;
|
|
423
|
+
|
|
424
|
+
// if (pinpointClient) {
|
|
425
|
+
// pinpointClient.config.endpoint = (): Promise<Endpoint> =>
|
|
426
|
+
// Promise.resolve({
|
|
427
|
+
// hostname: proxyUrl.hostname,
|
|
428
|
+
// // Passing proxyUrl.pathname here doesn't work; it gets overridden
|
|
429
|
+
// path: '/',
|
|
430
|
+
// port: undefined,
|
|
431
|
+
// protocol: proxyUrl.protocol,
|
|
432
|
+
// });
|
|
433
|
+
|
|
434
|
+
// pinpointClient.middlewareStack.remove(requestMiddleware);
|
|
435
|
+
// pinpointClient.middlewareStack.add(requestMiddleware, { step: 'finalizeRequest' });
|
|
436
|
+
// }
|
|
437
|
+
// return result;
|
|
438
|
+
// };
|
|
439
|
+
// }
|