@drivemetadata-ai/sdk 0.1.1-beta.4 → 0.1.1
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 +152 -21
- package/dist/angular/index.cjs +173 -8
- package/dist/angular/index.cjs.map +1 -1
- package/dist/angular/index.js +173 -8
- package/dist/angular/index.js.map +1 -1
- package/dist/browser/index.cjs +173 -8
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.js +173 -8
- package/dist/browser/index.js.map +1 -1
- package/dist/next/index.cjs +173 -8
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.js +173 -8
- package/dist/next/index.js.map +1 -1
- package/dist/react/index.cjs +173 -8
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +173 -8
- package/dist/react/index.js.map +1 -1
- package/docs/integration.md +177 -5
- package/package.json +2 -1
package/dist/browser/index.js
CHANGED
|
@@ -224,6 +224,15 @@ var sensitiveKeys = /* @__PURE__ */ new Set([
|
|
|
224
224
|
"session",
|
|
225
225
|
"cookie"
|
|
226
226
|
]);
|
|
227
|
+
function redactUrl(url, allowQueryKeys = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"]) {
|
|
228
|
+
const parsed = new URL(url, "https://placeholder.local");
|
|
229
|
+
for (const key of Array.from(parsed.searchParams.keys())) {
|
|
230
|
+
if (!allowQueryKeys.includes(key)) {
|
|
231
|
+
parsed.searchParams.set(key, "[REDACTED]");
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return url.startsWith("http") ? parsed.toString() : `${parsed.pathname}${parsed.search}`;
|
|
235
|
+
}
|
|
227
236
|
function sanitizeValue(value, allow, path = []) {
|
|
228
237
|
if (Array.isArray(value)) {
|
|
229
238
|
return value.map((item) => sanitizeValue(item, allow, path));
|
|
@@ -245,6 +254,127 @@ function sanitizeProperties(input, allowRawKeys = []) {
|
|
|
245
254
|
return sanitizeValue(input, allow);
|
|
246
255
|
}
|
|
247
256
|
|
|
257
|
+
// src/browser/core/attribute-persistence.ts
|
|
258
|
+
var DMD_ATTRIBUTES_STORAGE_KEY = "dmd_attributes";
|
|
259
|
+
var SESSION_STORAGE_KEY = "sessionData";
|
|
260
|
+
var SESSION_ID_KEY = "sessionId";
|
|
261
|
+
var SESSION_TIMESTAMP_KEY = "timestamp";
|
|
262
|
+
function isBlankValue(value) {
|
|
263
|
+
return value === null || value === void 0 || typeof value === "string" && value.trim() === "";
|
|
264
|
+
}
|
|
265
|
+
function readAttributes(base) {
|
|
266
|
+
const raw = base.getItem(DMD_ATTRIBUTES_STORAGE_KEY);
|
|
267
|
+
if (!raw) return {};
|
|
268
|
+
try {
|
|
269
|
+
const parsed = JSON.parse(raw);
|
|
270
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
271
|
+
} catch {
|
|
272
|
+
base.removeItem(DMD_ATTRIBUTES_STORAGE_KEY);
|
|
273
|
+
return {};
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
function sanitizeAttributes(attributes) {
|
|
277
|
+
return Object.fromEntries(Object.entries(attributes).filter(([, value]) => !isBlankValue(value)));
|
|
278
|
+
}
|
|
279
|
+
function writeAttributes(base, attributes) {
|
|
280
|
+
const sanitized = sanitizeAttributes(attributes);
|
|
281
|
+
if (Object.keys(sanitized).length === 0) {
|
|
282
|
+
base.removeItem(DMD_ATTRIBUTES_STORAGE_KEY);
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
base.setItem(DMD_ATTRIBUTES_STORAGE_KEY, JSON.stringify(sanitized));
|
|
286
|
+
}
|
|
287
|
+
function parseSessionData(value) {
|
|
288
|
+
try {
|
|
289
|
+
const parsed = JSON.parse(value);
|
|
290
|
+
const sessionData = {};
|
|
291
|
+
const sessionId = typeof parsed.sessionId === "string" && parsed.sessionId.trim() !== "" ? parsed.sessionId : void 0;
|
|
292
|
+
const timestamp = typeof parsed.timestamp === "number" ? parsed.timestamp : void 0;
|
|
293
|
+
if (sessionId !== void 0) sessionData.sessionId = sessionId;
|
|
294
|
+
if (timestamp !== void 0) sessionData.timestamp = timestamp;
|
|
295
|
+
return sessionData;
|
|
296
|
+
} catch {
|
|
297
|
+
return {};
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function getAggregateValue(attributes, key) {
|
|
301
|
+
if (key === SESSION_STORAGE_KEY) {
|
|
302
|
+
const sessionId = attributes[SESSION_ID_KEY];
|
|
303
|
+
const timestamp = attributes[SESSION_TIMESTAMP_KEY];
|
|
304
|
+
if (typeof sessionId === "string" && !isBlankValue(sessionId) && typeof timestamp === "number") {
|
|
305
|
+
return JSON.stringify({ sessionId, timestamp });
|
|
306
|
+
}
|
|
307
|
+
return null;
|
|
308
|
+
}
|
|
309
|
+
const value = attributes[key];
|
|
310
|
+
if (isBlankValue(value)) return null;
|
|
311
|
+
return typeof value === "string" ? value : JSON.stringify(value);
|
|
312
|
+
}
|
|
313
|
+
function setAggregateValue(attributes, key, value) {
|
|
314
|
+
if (key === SESSION_STORAGE_KEY) {
|
|
315
|
+
const sessionData = parseSessionData(value);
|
|
316
|
+
if (sessionData.sessionId === void 0 || sessionData.timestamp === void 0) {
|
|
317
|
+
delete attributes[SESSION_ID_KEY];
|
|
318
|
+
delete attributes[SESSION_TIMESTAMP_KEY];
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
attributes[SESSION_ID_KEY] = sessionData.sessionId;
|
|
322
|
+
attributes[SESSION_TIMESTAMP_KEY] = sessionData.timestamp;
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
attributes[key] = value;
|
|
326
|
+
}
|
|
327
|
+
function removeAggregateValue(attributes, key) {
|
|
328
|
+
if (key === SESSION_STORAGE_KEY) {
|
|
329
|
+
delete attributes[SESSION_ID_KEY];
|
|
330
|
+
delete attributes[SESSION_TIMESTAMP_KEY];
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
delete attributes[key];
|
|
334
|
+
}
|
|
335
|
+
function createDmdAttributesPersistence(base) {
|
|
336
|
+
return {
|
|
337
|
+
getItem(key) {
|
|
338
|
+
if (key === DMD_ATTRIBUTES_STORAGE_KEY) return base.getItem(key);
|
|
339
|
+
const attributes = readAttributes(base);
|
|
340
|
+
const aggregateValue = getAggregateValue(attributes, key);
|
|
341
|
+
if (aggregateValue !== null) return aggregateValue;
|
|
342
|
+
const legacyValue = base.getItem(key);
|
|
343
|
+
if (isBlankValue(legacyValue)) return null;
|
|
344
|
+
setAggregateValue(attributes, key, String(legacyValue));
|
|
345
|
+
writeAttributes(base, attributes);
|
|
346
|
+
return legacyValue;
|
|
347
|
+
},
|
|
348
|
+
setItem(key, value) {
|
|
349
|
+
if (key === DMD_ATTRIBUTES_STORAGE_KEY) return base.setItem(key, value);
|
|
350
|
+
const attributes = readAttributes(base);
|
|
351
|
+
if (isBlankValue(value)) {
|
|
352
|
+
removeAggregateValue(attributes, key);
|
|
353
|
+
writeAttributes(base, attributes);
|
|
354
|
+
base.removeItem(key);
|
|
355
|
+
return true;
|
|
356
|
+
}
|
|
357
|
+
setAggregateValue(attributes, key, value);
|
|
358
|
+
writeAttributes(base, attributes);
|
|
359
|
+
base.setItem(key, value);
|
|
360
|
+
return true;
|
|
361
|
+
},
|
|
362
|
+
removeItem(key) {
|
|
363
|
+
if (key === DMD_ATTRIBUTES_STORAGE_KEY) {
|
|
364
|
+
base.removeItem(key);
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
const attributes = readAttributes(base);
|
|
368
|
+
removeAggregateValue(attributes, key);
|
|
369
|
+
writeAttributes(base, attributes);
|
|
370
|
+
base.removeItem(key);
|
|
371
|
+
},
|
|
372
|
+
getHealth() {
|
|
373
|
+
return base.getHealth();
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
|
|
248
378
|
// src/core/attribution.ts
|
|
249
379
|
var dmdUtmKeys = [
|
|
250
380
|
"utm_source",
|
|
@@ -281,6 +411,10 @@ function mergeAttributionRecords(explicitProperties, stored) {
|
|
|
281
411
|
}
|
|
282
412
|
|
|
283
413
|
// src/browser/core/attribution.ts
|
|
414
|
+
var DMD_CLICK_ID_QUERY_KEY = "click_id";
|
|
415
|
+
var DMD_CLICK_ID_LEGACY_QUERY_KEY = "dmd_click_id";
|
|
416
|
+
var DMD_CLICK_ID_STORAGE_KEY = "dmd_click_id";
|
|
417
|
+
var DMD_CLICK_ID_ATTRIBUTE_KEY = "click_id";
|
|
284
418
|
function getCurrentUrl() {
|
|
285
419
|
return getBrowserWindow()?.location?.href;
|
|
286
420
|
}
|
|
@@ -299,6 +433,9 @@ function setIfPresent(persistence, key, value) {
|
|
|
299
433
|
persistence.setItem(key, value);
|
|
300
434
|
}
|
|
301
435
|
}
|
|
436
|
+
function getClickIdParam(params) {
|
|
437
|
+
return params.get(DMD_CLICK_ID_LEGACY_QUERY_KEY) || params.get(DMD_CLICK_ID_QUERY_KEY);
|
|
438
|
+
}
|
|
302
439
|
function getStoredString(persistence, key) {
|
|
303
440
|
const value = persistence.getItem(key);
|
|
304
441
|
return value === null || value === "" ? void 0 : value;
|
|
@@ -318,6 +455,9 @@ function captureAttributionFromUrl(persistence, url = getCurrentUrl()) {
|
|
|
318
455
|
for (const key of dmdCampaignKeys) {
|
|
319
456
|
setIfPresent(persistence, key, params.get(key));
|
|
320
457
|
}
|
|
458
|
+
const clickId = getClickIdParam(params);
|
|
459
|
+
setIfPresent(persistence, DMD_CLICK_ID_ATTRIBUTE_KEY, clickId);
|
|
460
|
+
setIfPresent(persistence, DMD_CLICK_ID_STORAGE_KEY, clickId);
|
|
321
461
|
for (const [param, sdkPubId] of dmdClickIdSources) {
|
|
322
462
|
const value = params.get(param);
|
|
323
463
|
if (value) {
|
|
@@ -333,7 +473,8 @@ function getStoredAttributionData(persistence) {
|
|
|
333
473
|
fbc: getStoredString(persistence, "fbc") ?? getCookie("_fbc"),
|
|
334
474
|
fbp: getStoredString(persistence, "fbp") ?? getCookie("_fbp"),
|
|
335
475
|
campaign_id: getStoredString(persistence, "campaign_id"),
|
|
336
|
-
ad_id: getStoredString(persistence, "ad_id")
|
|
476
|
+
ad_id: getStoredString(persistence, "ad_id"),
|
|
477
|
+
click_id: getStoredString(persistence, DMD_CLICK_ID_STORAGE_KEY) ?? getStoredString(persistence, DMD_CLICK_ID_ATTRIBUTE_KEY)
|
|
337
478
|
});
|
|
338
479
|
}
|
|
339
480
|
function getStoredUtmParameter(persistence) {
|
|
@@ -852,6 +993,24 @@ function resetAnonymousId(persistence) {
|
|
|
852
993
|
return anonymousId;
|
|
853
994
|
}
|
|
854
995
|
|
|
996
|
+
// src/browser/core/page-context.ts
|
|
997
|
+
function redactSearch(search) {
|
|
998
|
+
const redacted = redactUrl(search);
|
|
999
|
+
return redacted.startsWith("/?") ? redacted.slice(1) : redacted;
|
|
1000
|
+
}
|
|
1001
|
+
function getBrowserPageContext() {
|
|
1002
|
+
const browserWindow = getBrowserWindow();
|
|
1003
|
+
const documentRef = browserWindow?.document ?? globalThis.document;
|
|
1004
|
+
const location = browserWindow?.location;
|
|
1005
|
+
const page2 = {};
|
|
1006
|
+
if (location?.href) page2.url = location.href;
|
|
1007
|
+
if (location?.pathname) page2.path = location.pathname;
|
|
1008
|
+
if (location?.search) page2.search = redactSearch(location.search);
|
|
1009
|
+
if (documentRef?.title) page2.title = documentRef.title;
|
|
1010
|
+
if (documentRef?.referrer) page2.referrer = redactUrl(documentRef.referrer);
|
|
1011
|
+
return page2;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
855
1014
|
// src/browser/core/persistence.ts
|
|
856
1015
|
function createPersistenceHealth(requested) {
|
|
857
1016
|
return {
|
|
@@ -1018,7 +1177,7 @@ function createBrowserPersistence(mode = "localStorage+cookie") {
|
|
|
1018
1177
|
}
|
|
1019
1178
|
|
|
1020
1179
|
// src/browser/core/session.ts
|
|
1021
|
-
var
|
|
1180
|
+
var SESSION_STORAGE_KEY2 = "sessionData";
|
|
1022
1181
|
function getUrlParam2(name) {
|
|
1023
1182
|
const href = getBrowserWindow()?.location?.href;
|
|
1024
1183
|
if (!href) return null;
|
|
@@ -1029,7 +1188,7 @@ function getUrlParam2(name) {
|
|
|
1029
1188
|
}
|
|
1030
1189
|
}
|
|
1031
1190
|
function readStoredSession(persistence) {
|
|
1032
|
-
const rawSession = persistence.getItem(
|
|
1191
|
+
const rawSession = persistence.getItem(SESSION_STORAGE_KEY2);
|
|
1033
1192
|
if (!rawSession) return void 0;
|
|
1034
1193
|
try {
|
|
1035
1194
|
const parsed = JSON.parse(rawSession);
|
|
@@ -1040,12 +1199,12 @@ function readStoredSession(persistence) {
|
|
|
1040
1199
|
};
|
|
1041
1200
|
}
|
|
1042
1201
|
} catch {
|
|
1043
|
-
persistence.removeItem(
|
|
1202
|
+
persistence.removeItem(SESSION_STORAGE_KEY2);
|
|
1044
1203
|
}
|
|
1045
1204
|
return void 0;
|
|
1046
1205
|
}
|
|
1047
1206
|
function writeStoredSession(persistence, sessionId, timestamp) {
|
|
1048
|
-
persistence.setItem(
|
|
1207
|
+
persistence.setItem(SESSION_STORAGE_KEY2, JSON.stringify({ sessionId, timestamp }));
|
|
1049
1208
|
}
|
|
1050
1209
|
function createSessionManager(persistence, idleTimeoutSeconds = 30 * 60) {
|
|
1051
1210
|
function resolveSessionId() {
|
|
@@ -1099,11 +1258,12 @@ var DriveMetaDataSDK = class {
|
|
|
1099
1258
|
requireConfigString(config.writeKey || config.token, "writeKey or token");
|
|
1100
1259
|
this.config = config;
|
|
1101
1260
|
this.endpoint = endpointFromConfig(config);
|
|
1102
|
-
|
|
1261
|
+
const storagePersistence = createBrowserPersistence(config.persistence);
|
|
1262
|
+
this.persistence = createDmdAttributesPersistence(storagePersistence);
|
|
1103
1263
|
this.session = createSessionManager(this.persistence, config.sessionIdleTimeoutSeconds);
|
|
1104
1264
|
const deliveryConfig = {
|
|
1105
1265
|
endpoint: this.endpoint,
|
|
1106
|
-
storage:
|
|
1266
|
+
storage: storagePersistence
|
|
1107
1267
|
};
|
|
1108
1268
|
if (config.delivery?.maxQueueSize !== void 0) deliveryConfig.maxQueueSize = config.delivery.maxQueueSize;
|
|
1109
1269
|
if (config.delivery?.queueTtlMs !== void 0) deliveryConfig.queueTtlMs = config.delivery.queueTtlMs;
|
|
@@ -1348,6 +1508,7 @@ var DriveMetaDataSDK = class {
|
|
|
1348
1508
|
}
|
|
1349
1509
|
toCollectorPayload(prepared) {
|
|
1350
1510
|
const browserWindow = getBrowserWindow();
|
|
1511
|
+
const pageContext = getBrowserPageContext();
|
|
1351
1512
|
return createBackendCollectorPayload({
|
|
1352
1513
|
requestId: prepared.messageId,
|
|
1353
1514
|
timestamp: prepared.timestamp,
|
|
@@ -1359,9 +1520,13 @@ var DriveMetaDataSDK = class {
|
|
|
1359
1520
|
sessionId: prepared.sessionId,
|
|
1360
1521
|
ua: browserWindow?.navigator?.userAgent,
|
|
1361
1522
|
appId: prepared.appId,
|
|
1362
|
-
pageUrl: browserWindow?.location?.href,
|
|
1523
|
+
pageUrl: pageContext.url ?? browserWindow?.location?.href,
|
|
1363
1524
|
eventData: mergeStoredAttribution({
|
|
1364
1525
|
...prepared.properties,
|
|
1526
|
+
page: {
|
|
1527
|
+
...pageContext,
|
|
1528
|
+
...prepared.properties.page && typeof prepared.properties.page === "object" ? prepared.properties.page : {}
|
|
1529
|
+
},
|
|
1365
1530
|
anonymousId: prepared.anonymousId,
|
|
1366
1531
|
sessionId: prepared.sessionId,
|
|
1367
1532
|
timestamp: prepared.timestamp,
|