@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/react/index.cjs
CHANGED
|
@@ -273,6 +273,15 @@ var sensitiveKeys = /* @__PURE__ */ new Set([
|
|
|
273
273
|
"session",
|
|
274
274
|
"cookie"
|
|
275
275
|
]);
|
|
276
|
+
function redactUrl(url, allowQueryKeys = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"]) {
|
|
277
|
+
const parsed = new URL(url, "https://placeholder.local");
|
|
278
|
+
for (const key of Array.from(parsed.searchParams.keys())) {
|
|
279
|
+
if (!allowQueryKeys.includes(key)) {
|
|
280
|
+
parsed.searchParams.set(key, "[REDACTED]");
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return url.startsWith("http") ? parsed.toString() : `${parsed.pathname}${parsed.search}`;
|
|
284
|
+
}
|
|
276
285
|
function sanitizeValue(value, allow, path = []) {
|
|
277
286
|
if (Array.isArray(value)) {
|
|
278
287
|
return value.map((item) => sanitizeValue(item, allow, path));
|
|
@@ -294,6 +303,127 @@ function sanitizeProperties(input, allowRawKeys = []) {
|
|
|
294
303
|
return sanitizeValue(input, allow);
|
|
295
304
|
}
|
|
296
305
|
|
|
306
|
+
// src/browser/core/attribute-persistence.ts
|
|
307
|
+
var DMD_ATTRIBUTES_STORAGE_KEY = "dmd_attributes";
|
|
308
|
+
var SESSION_STORAGE_KEY = "sessionData";
|
|
309
|
+
var SESSION_ID_KEY = "sessionId";
|
|
310
|
+
var SESSION_TIMESTAMP_KEY = "timestamp";
|
|
311
|
+
function isBlankValue(value) {
|
|
312
|
+
return value === null || value === void 0 || typeof value === "string" && value.trim() === "";
|
|
313
|
+
}
|
|
314
|
+
function readAttributes(base) {
|
|
315
|
+
const raw = base.getItem(DMD_ATTRIBUTES_STORAGE_KEY);
|
|
316
|
+
if (!raw) return {};
|
|
317
|
+
try {
|
|
318
|
+
const parsed = JSON.parse(raw);
|
|
319
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
320
|
+
} catch {
|
|
321
|
+
base.removeItem(DMD_ATTRIBUTES_STORAGE_KEY);
|
|
322
|
+
return {};
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
function sanitizeAttributes(attributes) {
|
|
326
|
+
return Object.fromEntries(Object.entries(attributes).filter(([, value]) => !isBlankValue(value)));
|
|
327
|
+
}
|
|
328
|
+
function writeAttributes(base, attributes) {
|
|
329
|
+
const sanitized = sanitizeAttributes(attributes);
|
|
330
|
+
if (Object.keys(sanitized).length === 0) {
|
|
331
|
+
base.removeItem(DMD_ATTRIBUTES_STORAGE_KEY);
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
base.setItem(DMD_ATTRIBUTES_STORAGE_KEY, JSON.stringify(sanitized));
|
|
335
|
+
}
|
|
336
|
+
function parseSessionData(value) {
|
|
337
|
+
try {
|
|
338
|
+
const parsed = JSON.parse(value);
|
|
339
|
+
const sessionData = {};
|
|
340
|
+
const sessionId = typeof parsed.sessionId === "string" && parsed.sessionId.trim() !== "" ? parsed.sessionId : void 0;
|
|
341
|
+
const timestamp = typeof parsed.timestamp === "number" ? parsed.timestamp : void 0;
|
|
342
|
+
if (sessionId !== void 0) sessionData.sessionId = sessionId;
|
|
343
|
+
if (timestamp !== void 0) sessionData.timestamp = timestamp;
|
|
344
|
+
return sessionData;
|
|
345
|
+
} catch {
|
|
346
|
+
return {};
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
function getAggregateValue(attributes, key) {
|
|
350
|
+
if (key === SESSION_STORAGE_KEY) {
|
|
351
|
+
const sessionId = attributes[SESSION_ID_KEY];
|
|
352
|
+
const timestamp = attributes[SESSION_TIMESTAMP_KEY];
|
|
353
|
+
if (typeof sessionId === "string" && !isBlankValue(sessionId) && typeof timestamp === "number") {
|
|
354
|
+
return JSON.stringify({ sessionId, timestamp });
|
|
355
|
+
}
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
358
|
+
const value = attributes[key];
|
|
359
|
+
if (isBlankValue(value)) return null;
|
|
360
|
+
return typeof value === "string" ? value : JSON.stringify(value);
|
|
361
|
+
}
|
|
362
|
+
function setAggregateValue(attributes, key, value) {
|
|
363
|
+
if (key === SESSION_STORAGE_KEY) {
|
|
364
|
+
const sessionData = parseSessionData(value);
|
|
365
|
+
if (sessionData.sessionId === void 0 || sessionData.timestamp === void 0) {
|
|
366
|
+
delete attributes[SESSION_ID_KEY];
|
|
367
|
+
delete attributes[SESSION_TIMESTAMP_KEY];
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
attributes[SESSION_ID_KEY] = sessionData.sessionId;
|
|
371
|
+
attributes[SESSION_TIMESTAMP_KEY] = sessionData.timestamp;
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
attributes[key] = value;
|
|
375
|
+
}
|
|
376
|
+
function removeAggregateValue(attributes, key) {
|
|
377
|
+
if (key === SESSION_STORAGE_KEY) {
|
|
378
|
+
delete attributes[SESSION_ID_KEY];
|
|
379
|
+
delete attributes[SESSION_TIMESTAMP_KEY];
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
delete attributes[key];
|
|
383
|
+
}
|
|
384
|
+
function createDmdAttributesPersistence(base) {
|
|
385
|
+
return {
|
|
386
|
+
getItem(key) {
|
|
387
|
+
if (key === DMD_ATTRIBUTES_STORAGE_KEY) return base.getItem(key);
|
|
388
|
+
const attributes = readAttributes(base);
|
|
389
|
+
const aggregateValue = getAggregateValue(attributes, key);
|
|
390
|
+
if (aggregateValue !== null) return aggregateValue;
|
|
391
|
+
const legacyValue = base.getItem(key);
|
|
392
|
+
if (isBlankValue(legacyValue)) return null;
|
|
393
|
+
setAggregateValue(attributes, key, String(legacyValue));
|
|
394
|
+
writeAttributes(base, attributes);
|
|
395
|
+
return legacyValue;
|
|
396
|
+
},
|
|
397
|
+
setItem(key, value) {
|
|
398
|
+
if (key === DMD_ATTRIBUTES_STORAGE_KEY) return base.setItem(key, value);
|
|
399
|
+
const attributes = readAttributes(base);
|
|
400
|
+
if (isBlankValue(value)) {
|
|
401
|
+
removeAggregateValue(attributes, key);
|
|
402
|
+
writeAttributes(base, attributes);
|
|
403
|
+
base.removeItem(key);
|
|
404
|
+
return true;
|
|
405
|
+
}
|
|
406
|
+
setAggregateValue(attributes, key, value);
|
|
407
|
+
writeAttributes(base, attributes);
|
|
408
|
+
base.setItem(key, value);
|
|
409
|
+
return true;
|
|
410
|
+
},
|
|
411
|
+
removeItem(key) {
|
|
412
|
+
if (key === DMD_ATTRIBUTES_STORAGE_KEY) {
|
|
413
|
+
base.removeItem(key);
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
const attributes = readAttributes(base);
|
|
417
|
+
removeAggregateValue(attributes, key);
|
|
418
|
+
writeAttributes(base, attributes);
|
|
419
|
+
base.removeItem(key);
|
|
420
|
+
},
|
|
421
|
+
getHealth() {
|
|
422
|
+
return base.getHealth();
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
|
|
297
427
|
// src/core/attribution.ts
|
|
298
428
|
var dmdUtmKeys = [
|
|
299
429
|
"utm_source",
|
|
@@ -330,6 +460,10 @@ function mergeAttributionRecords(explicitProperties, stored) {
|
|
|
330
460
|
}
|
|
331
461
|
|
|
332
462
|
// src/browser/core/attribution.ts
|
|
463
|
+
var DMD_CLICK_ID_QUERY_KEY = "click_id";
|
|
464
|
+
var DMD_CLICK_ID_LEGACY_QUERY_KEY = "dmd_click_id";
|
|
465
|
+
var DMD_CLICK_ID_STORAGE_KEY = "dmd_click_id";
|
|
466
|
+
var DMD_CLICK_ID_ATTRIBUTE_KEY = "click_id";
|
|
333
467
|
function getCurrentUrl() {
|
|
334
468
|
return getBrowserWindow()?.location?.href;
|
|
335
469
|
}
|
|
@@ -348,6 +482,9 @@ function setIfPresent(persistence, key, value) {
|
|
|
348
482
|
persistence.setItem(key, value);
|
|
349
483
|
}
|
|
350
484
|
}
|
|
485
|
+
function getClickIdParam(params) {
|
|
486
|
+
return params.get(DMD_CLICK_ID_LEGACY_QUERY_KEY) || params.get(DMD_CLICK_ID_QUERY_KEY);
|
|
487
|
+
}
|
|
351
488
|
function getStoredString(persistence, key) {
|
|
352
489
|
const value = persistence.getItem(key);
|
|
353
490
|
return value === null || value === "" ? void 0 : value;
|
|
@@ -367,6 +504,9 @@ function captureAttributionFromUrl(persistence, url = getCurrentUrl()) {
|
|
|
367
504
|
for (const key of dmdCampaignKeys) {
|
|
368
505
|
setIfPresent(persistence, key, params.get(key));
|
|
369
506
|
}
|
|
507
|
+
const clickId = getClickIdParam(params);
|
|
508
|
+
setIfPresent(persistence, DMD_CLICK_ID_ATTRIBUTE_KEY, clickId);
|
|
509
|
+
setIfPresent(persistence, DMD_CLICK_ID_STORAGE_KEY, clickId);
|
|
370
510
|
for (const [param, sdkPubId] of dmdClickIdSources) {
|
|
371
511
|
const value = params.get(param);
|
|
372
512
|
if (value) {
|
|
@@ -382,7 +522,8 @@ function getStoredAttributionData(persistence) {
|
|
|
382
522
|
fbc: getStoredString(persistence, "fbc") ?? getCookie("_fbc"),
|
|
383
523
|
fbp: getStoredString(persistence, "fbp") ?? getCookie("_fbp"),
|
|
384
524
|
campaign_id: getStoredString(persistence, "campaign_id"),
|
|
385
|
-
ad_id: getStoredString(persistence, "ad_id")
|
|
525
|
+
ad_id: getStoredString(persistence, "ad_id"),
|
|
526
|
+
click_id: getStoredString(persistence, DMD_CLICK_ID_STORAGE_KEY) ?? getStoredString(persistence, DMD_CLICK_ID_ATTRIBUTE_KEY)
|
|
386
527
|
});
|
|
387
528
|
}
|
|
388
529
|
function getStoredUtmParameter(persistence) {
|
|
@@ -901,6 +1042,24 @@ function resetAnonymousId(persistence) {
|
|
|
901
1042
|
return anonymousId;
|
|
902
1043
|
}
|
|
903
1044
|
|
|
1045
|
+
// src/browser/core/page-context.ts
|
|
1046
|
+
function redactSearch(search) {
|
|
1047
|
+
const redacted = redactUrl(search);
|
|
1048
|
+
return redacted.startsWith("/?") ? redacted.slice(1) : redacted;
|
|
1049
|
+
}
|
|
1050
|
+
function getBrowserPageContext() {
|
|
1051
|
+
const browserWindow = getBrowserWindow();
|
|
1052
|
+
const documentRef = browserWindow?.document ?? globalThis.document;
|
|
1053
|
+
const location = browserWindow?.location;
|
|
1054
|
+
const page2 = {};
|
|
1055
|
+
if (location?.href) page2.url = location.href;
|
|
1056
|
+
if (location?.pathname) page2.path = location.pathname;
|
|
1057
|
+
if (location?.search) page2.search = redactSearch(location.search);
|
|
1058
|
+
if (documentRef?.title) page2.title = documentRef.title;
|
|
1059
|
+
if (documentRef?.referrer) page2.referrer = redactUrl(documentRef.referrer);
|
|
1060
|
+
return page2;
|
|
1061
|
+
}
|
|
1062
|
+
|
|
904
1063
|
// src/browser/core/persistence.ts
|
|
905
1064
|
function createPersistenceHealth(requested) {
|
|
906
1065
|
return {
|
|
@@ -1067,7 +1226,7 @@ function createBrowserPersistence(mode = "localStorage+cookie") {
|
|
|
1067
1226
|
}
|
|
1068
1227
|
|
|
1069
1228
|
// src/browser/core/session.ts
|
|
1070
|
-
var
|
|
1229
|
+
var SESSION_STORAGE_KEY2 = "sessionData";
|
|
1071
1230
|
function getUrlParam2(name) {
|
|
1072
1231
|
const href = getBrowserWindow()?.location?.href;
|
|
1073
1232
|
if (!href) return null;
|
|
@@ -1078,7 +1237,7 @@ function getUrlParam2(name) {
|
|
|
1078
1237
|
}
|
|
1079
1238
|
}
|
|
1080
1239
|
function readStoredSession(persistence) {
|
|
1081
|
-
const rawSession = persistence.getItem(
|
|
1240
|
+
const rawSession = persistence.getItem(SESSION_STORAGE_KEY2);
|
|
1082
1241
|
if (!rawSession) return void 0;
|
|
1083
1242
|
try {
|
|
1084
1243
|
const parsed = JSON.parse(rawSession);
|
|
@@ -1089,12 +1248,12 @@ function readStoredSession(persistence) {
|
|
|
1089
1248
|
};
|
|
1090
1249
|
}
|
|
1091
1250
|
} catch {
|
|
1092
|
-
persistence.removeItem(
|
|
1251
|
+
persistence.removeItem(SESSION_STORAGE_KEY2);
|
|
1093
1252
|
}
|
|
1094
1253
|
return void 0;
|
|
1095
1254
|
}
|
|
1096
1255
|
function writeStoredSession(persistence, sessionId, timestamp) {
|
|
1097
|
-
persistence.setItem(
|
|
1256
|
+
persistence.setItem(SESSION_STORAGE_KEY2, JSON.stringify({ sessionId, timestamp }));
|
|
1098
1257
|
}
|
|
1099
1258
|
function createSessionManager(persistence, idleTimeoutSeconds = 30 * 60) {
|
|
1100
1259
|
function resolveSessionId() {
|
|
@@ -1148,11 +1307,12 @@ var DriveMetaDataSDK = class {
|
|
|
1148
1307
|
requireConfigString(config.writeKey || config.token, "writeKey or token");
|
|
1149
1308
|
this.config = config;
|
|
1150
1309
|
this.endpoint = endpointFromConfig(config);
|
|
1151
|
-
|
|
1310
|
+
const storagePersistence = createBrowserPersistence(config.persistence);
|
|
1311
|
+
this.persistence = createDmdAttributesPersistence(storagePersistence);
|
|
1152
1312
|
this.session = createSessionManager(this.persistence, config.sessionIdleTimeoutSeconds);
|
|
1153
1313
|
const deliveryConfig = {
|
|
1154
1314
|
endpoint: this.endpoint,
|
|
1155
|
-
storage:
|
|
1315
|
+
storage: storagePersistence
|
|
1156
1316
|
};
|
|
1157
1317
|
if (config.delivery?.maxQueueSize !== void 0) deliveryConfig.maxQueueSize = config.delivery.maxQueueSize;
|
|
1158
1318
|
if (config.delivery?.queueTtlMs !== void 0) deliveryConfig.queueTtlMs = config.delivery.queueTtlMs;
|
|
@@ -1397,6 +1557,7 @@ var DriveMetaDataSDK = class {
|
|
|
1397
1557
|
}
|
|
1398
1558
|
toCollectorPayload(prepared) {
|
|
1399
1559
|
const browserWindow = getBrowserWindow();
|
|
1560
|
+
const pageContext = getBrowserPageContext();
|
|
1400
1561
|
return createBackendCollectorPayload({
|
|
1401
1562
|
requestId: prepared.messageId,
|
|
1402
1563
|
timestamp: prepared.timestamp,
|
|
@@ -1408,9 +1569,13 @@ var DriveMetaDataSDK = class {
|
|
|
1408
1569
|
sessionId: prepared.sessionId,
|
|
1409
1570
|
ua: browserWindow?.navigator?.userAgent,
|
|
1410
1571
|
appId: prepared.appId,
|
|
1411
|
-
pageUrl: browserWindow?.location?.href,
|
|
1572
|
+
pageUrl: pageContext.url ?? browserWindow?.location?.href,
|
|
1412
1573
|
eventData: mergeStoredAttribution({
|
|
1413
1574
|
...prepared.properties,
|
|
1575
|
+
page: {
|
|
1576
|
+
...pageContext,
|
|
1577
|
+
...prepared.properties.page && typeof prepared.properties.page === "object" ? prepared.properties.page : {}
|
|
1578
|
+
},
|
|
1414
1579
|
anonymousId: prepared.anonymousId,
|
|
1415
1580
|
sessionId: prepared.sessionId,
|
|
1416
1581
|
timestamp: prepared.timestamp,
|