-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathlogClientEvent.tsx
More file actions
127 lines (116 loc) · 3.26 KB
/
logClientEvent.tsx
File metadata and controls
127 lines (116 loc) · 3.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Import shared types
import LOG_ROUTE_PATH from '../constants/LOG_ROUTE_PATH';
import LogBuiltInMetadata from '../types/LogBuiltInMetadata';
import LogFunction from '../types/LogFunction';
import LogLevel from '../types/LogLevel';
// Import shared functions
// TODO: fix dependency cycle
// eslint-disable-next-line import/no-cycle
import visitServerEndpoint from './visitServerEndpoint';
// Import status
import { appHasNoServer } from './initClient';
/* ------- Metadata Populator ------- */
// Type of a metadata populator function
type MetadataPopulator = () => { [k: string]: any } | Promise<{ [k: string]: any }>;
// Current metadata populator function
let metadataPopulator: MetadataPopulator;
/**
* Set the metadata populator function that will be called before every client
* event is logged. The function should return a set of metadata values that
* will be added to all client events
* @author Gabe Abrams
* @param metadataPopulator function to call that will return a set of metadata
* values that will be added to all client events
*/
export const setClientEventMetadataPopulator = (
newMetadataPopulator: MetadataPopulator,
) => {
metadataPopulator = newMetadataPopulator;
};
/* -------------- Main -------------- */
/**
* Log a user action on the client (cannot be used on the server)
* @author Gabe Abrams
*/
const logClientEvent: LogFunction = async (opts) => {
// Don't write to the server if there is none
if (appHasNoServer()) {
return;
}
// Populate metadata
let metadata = (opts.metadata ?? {});
if (metadataPopulator) {
try {
const autoPopulatedMetadata = await metadataPopulator();
metadata = {
...autoPopulatedMetadata,
...metadata,
};
} catch (err) {
// Add error to metadata
metadata = {
autoPopulatedMetadataNotAvailable: true,
...metadata,
};
}
}
// Send to server
return visitServerEndpoint({
path: LOG_ROUTE_PATH,
method: 'POST',
params: {
context: (
typeof opts.context === 'string'
? opts.context
: (
((opts.context as any) ?? {})._
?? LogBuiltInMetadata.Context.Uncategorized
)
),
subcontext: (
opts.subcontext
?? LogBuiltInMetadata.Context.Uncategorized
),
level: (
opts.level
?? LogLevel.Info
),
tags: JSON.stringify(opts.tags ?? []),
metadata: JSON.stringify(metadata),
errorMessage: (
(opts as any).error
? (opts as any).error.message
: undefined
),
errorCode: (
(opts as any).error
? (opts as any).error.code
: undefined
),
errorStack: (
(opts as any).error
? (opts as any).error.stack
: undefined
),
target: (
(opts as any).action
? (
(opts as any).target
?? LogBuiltInMetadata.Target.NoTarget
)
: undefined
),
action: (
(opts as any).action
? (opts as any).action
: undefined
),
overriddenUserInfo: {
userId: opts.userId,
userFirstName: opts.userFirstName,
userLastName: opts.userLastName,
},
},
});
};
export default logClientEvent;