clarity-analytics-sdk 1.0.5 → 1.0.7
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/package.json +1 -1
- package/src/index.js +61 -28
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -20,11 +20,9 @@
|
|
|
20
20
|
apiUrl: 'https://apps.helo.ai/api/v1/sdk/clarity/events/publish-event',
|
|
21
21
|
fetchUserIdUrl: 'https://apps.helo.ai/api/v1/sdk/clarity/projects?id=',
|
|
22
22
|
projectId: config.projectId,
|
|
23
|
-
projectName:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
systemUserId: null, // Will be fetched from backend API
|
|
27
|
-
sessionId: config.sessionId || this._generateSessionId(),
|
|
23
|
+
projectName: null,
|
|
24
|
+
userId: null, // customer: should come from app
|
|
25
|
+
systemUserId: null, // Will be fetched from backend API(user who logged in clarity)
|
|
28
26
|
debug: config.debug || false,
|
|
29
27
|
retryAttempts: config.retryAttempts || 3,
|
|
30
28
|
timeout: config.timeout || 10000,
|
|
@@ -50,15 +48,20 @@
|
|
|
50
48
|
async _initialize (config) {
|
|
51
49
|
try {
|
|
52
50
|
// Fetch user ID from backend
|
|
53
|
-
const {
|
|
54
|
-
|
|
55
|
-
if (!userId) {
|
|
51
|
+
const { systemUserId, ipaddress, projectName } = await this._fetchUserId(this.config.projectId)
|
|
52
|
+
if (!systemUserId) {
|
|
56
53
|
throw new Error('Failed to fetch user ID from backend')
|
|
57
54
|
}
|
|
58
55
|
|
|
59
|
-
|
|
56
|
+
if (!projectName) {
|
|
57
|
+
throw new Error('Failed to fetch project name from backend111')
|
|
58
|
+
}
|
|
59
|
+
|
|
60
60
|
this.config.ipaddress = ipaddress
|
|
61
|
-
this.config.systemUserId =
|
|
61
|
+
this.config.systemUserId = systemUserId // Set to empty string if not provided
|
|
62
|
+
this.config.projectName = projectName
|
|
63
|
+
this.config.customerId = this._generateId()
|
|
64
|
+
this.config.sessionId = this._generateId()
|
|
62
65
|
this._isInitialized = true
|
|
63
66
|
|
|
64
67
|
// Auto-collect page view if enabled
|
|
@@ -111,21 +114,23 @@
|
|
|
111
114
|
// Extract userId from response (supports multiple response structures)
|
|
112
115
|
let userId = null
|
|
113
116
|
let ipaddress = null
|
|
114
|
-
|
|
117
|
+
let projectName = null
|
|
115
118
|
// Check if response has a 'data' wrapper
|
|
116
119
|
if (responseData?.data) {
|
|
117
120
|
userId = responseData?.data?.userId
|
|
118
121
|
ipaddress = responseData?.data?.ipaddress
|
|
122
|
+
projectName = responseData?.data?.projectName
|
|
119
123
|
} else {
|
|
120
124
|
userId = responseData?.userId
|
|
121
125
|
ipaddress = responseData?.ipaddress
|
|
126
|
+
projectName = responseData?.projectName
|
|
122
127
|
}
|
|
123
128
|
|
|
124
129
|
if (!userId) {
|
|
125
130
|
throw new Error('User ID not found in API response')
|
|
126
131
|
}
|
|
127
132
|
|
|
128
|
-
return { userId, ipaddress }
|
|
133
|
+
return { systemUserId: userId, ipaddress, projectName }
|
|
129
134
|
} catch (error) {
|
|
130
135
|
clearTimeout(timeoutId)
|
|
131
136
|
throw error
|
|
@@ -156,16 +161,54 @@
|
|
|
156
161
|
throw new Error('Event name is required')
|
|
157
162
|
}
|
|
158
163
|
|
|
164
|
+
// Validate event name length
|
|
165
|
+
if (typeof eventName !== 'string') {
|
|
166
|
+
throw new Error('Event name must be a string')
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const eventNameLength = eventName.trim().length
|
|
170
|
+
if (eventNameLength < 4 || eventNameLength > 50) {
|
|
171
|
+
throw new Error('Event name must be between 5 and 50 characters')
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Validate properties is an object
|
|
175
|
+
if (properties !== null && (typeof properties !== 'object' || Array.isArray(properties))) {
|
|
176
|
+
throw new Error('Properties must be an object')
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Validate properties size (max 16KB)
|
|
180
|
+
if (properties && typeof properties === 'object') {
|
|
181
|
+
const propertiesJson = JSON.stringify(properties)
|
|
182
|
+
let propertiesSize
|
|
183
|
+
|
|
184
|
+
// Calculate size in bytes (works in both browser and Node.js)
|
|
185
|
+
if (typeof Blob !== 'undefined') {
|
|
186
|
+
propertiesSize = new Blob([propertiesJson]).size
|
|
187
|
+
} else if (typeof TextEncoder !== 'undefined') {
|
|
188
|
+
propertiesSize = new TextEncoder().encode(propertiesJson).length
|
|
189
|
+
} else if (typeof Buffer !== 'undefined') {
|
|
190
|
+
propertiesSize = Buffer.byteLength(propertiesJson, 'utf8')
|
|
191
|
+
} else {
|
|
192
|
+
// Fallback: approximate size using string length (UTF-8)
|
|
193
|
+
propertiesSize = propertiesJson.length
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const maxSize = 16 * 1024 // 16KB in bytes
|
|
197
|
+
if (propertiesSize > maxSize) {
|
|
198
|
+
throw new Error(`Properties object size (${propertiesSize} bytes) exceeds maximum allowed size of 16KB`)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
159
202
|
const eventData = this._buildEventPayload({
|
|
160
203
|
eventType: options.eventType || 'custom',
|
|
161
204
|
eventName,
|
|
162
205
|
eventKey: options.eventKey || this._sanitizeEventName(eventName),
|
|
163
206
|
properties,
|
|
164
|
-
sessionId: properties.sessionId || options.sessionId,
|
|
207
|
+
sessionId: properties.sessionId || options.sessionId || this.config.sessionId,
|
|
165
208
|
context: options.context || {},
|
|
166
209
|
traits: options.traits || {},
|
|
167
|
-
ipaddress: options.ipaddress || this.config.ipaddress,
|
|
168
|
-
|
|
210
|
+
ipaddress: properties.ipaddress || options.ipaddress || this.config.ipaddress,
|
|
211
|
+
customerId: properties.userId || properties.customerId || options.userId || options.customerId || this.config.customerId,
|
|
169
212
|
})
|
|
170
213
|
return this._sendEvent(eventData)
|
|
171
214
|
}
|
|
@@ -178,11 +221,10 @@
|
|
|
178
221
|
const timestamp = Date.now()
|
|
179
222
|
const eventId = this._generateUUID()
|
|
180
223
|
const requestId = this._generateRequestId()
|
|
181
|
-
const userId = data.
|
|
224
|
+
const userId = data.customerId // actual customer id from app
|
|
182
225
|
|
|
183
226
|
// system_user_id comes from API response only, default to empty string if not available
|
|
184
227
|
const systemUserId = this.config.systemUserId || ''
|
|
185
|
-
const finalUserId = userId
|
|
186
228
|
|
|
187
229
|
// Build flat event payload (matching staging.js structure)
|
|
188
230
|
return {
|
|
@@ -193,13 +235,13 @@
|
|
|
193
235
|
timestamp: timestamp,
|
|
194
236
|
|
|
195
237
|
// User and session
|
|
196
|
-
user_id:
|
|
238
|
+
user_id: userId,
|
|
197
239
|
session_id: data.sessionId || this.config.sessionId,
|
|
198
240
|
system_user_id: systemUserId,
|
|
199
241
|
|
|
200
242
|
// Project information
|
|
201
243
|
project_id: this.config.projectId,
|
|
202
|
-
project_name: this.config.projectName
|
|
244
|
+
project_name: this.config.projectName,
|
|
203
245
|
|
|
204
246
|
// Device information (flattened)
|
|
205
247
|
device: this._deviceInfo.device.type,
|
|
@@ -275,7 +317,6 @@
|
|
|
275
317
|
try {
|
|
276
318
|
// Validate mandatory fields before sending
|
|
277
319
|
this._validateMandatoryFields(eventData)
|
|
278
|
-
|
|
279
320
|
const headers = {
|
|
280
321
|
'Content-Type': 'application/json'
|
|
281
322
|
}
|
|
@@ -495,14 +536,6 @@
|
|
|
495
536
|
}
|
|
496
537
|
}
|
|
497
538
|
|
|
498
|
-
/**
|
|
499
|
-
* Generate session ID
|
|
500
|
-
* @private
|
|
501
|
-
*/
|
|
502
|
-
_generateSessionId () {
|
|
503
|
-
return 'sess_' + this._generateId()
|
|
504
|
-
}
|
|
505
|
-
|
|
506
539
|
/**
|
|
507
540
|
* Generate UUID v4
|
|
508
541
|
* @private
|