@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.cjs
CHANGED
|
@@ -263,6 +263,15 @@ var sensitiveKeys = /* @__PURE__ */ new Set([
|
|
|
263
263
|
"session",
|
|
264
264
|
"cookie"
|
|
265
265
|
]);
|
|
266
|
+
function redactUrl(url, allowQueryKeys = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"]) {
|
|
267
|
+
const parsed = new URL(url, "https://placeholder.local");
|
|
268
|
+
for (const key of Array.from(parsed.searchParams.keys())) {
|
|
269
|
+
if (!allowQueryKeys.includes(key)) {
|
|
270
|
+
parsed.searchParams.set(key, "[REDACTED]");
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return url.startsWith("http") ? parsed.toString() : `${parsed.pathname}${parsed.search}`;
|
|
274
|
+
}
|
|
266
275
|
function sanitizeValue(value, allow, path = []) {
|
|
267
276
|
if (Array.isArray(value)) {
|
|
268
277
|
return value.map((item) => sanitizeValue(item, allow, path));
|
|
@@ -284,6 +293,127 @@ function sanitizeProperties(input, allowRawKeys = []) {
|
|
|
284
293
|
return sanitizeValue(input, allow);
|
|
285
294
|
}
|
|
286
295
|
|
|
296
|
+
// src/browser/core/attribute-persistence.ts
|
|
297
|
+
var DMD_ATTRIBUTES_STORAGE_KEY = "dmd_attributes";
|
|
298
|
+
var SESSION_STORAGE_KEY = "sessionData";
|
|
299
|
+
var SESSION_ID_KEY = "sessionId";
|
|
300
|
+
var SESSION_TIMESTAMP_KEY = "timestamp";
|
|
301
|
+
function isBlankValue(value) {
|
|
302
|
+
return value === null || value === void 0 || typeof value === "string" && value.trim() === "";
|
|
303
|
+
}
|
|
304
|
+
function readAttributes(base) {
|
|
305
|
+
const raw = base.getItem(DMD_ATTRIBUTES_STORAGE_KEY);
|
|
306
|
+
if (!raw) return {};
|
|
307
|
+
try {
|
|
308
|
+
const parsed = JSON.parse(raw);
|
|
309
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
310
|
+
} catch {
|
|
311
|
+
base.removeItem(DMD_ATTRIBUTES_STORAGE_KEY);
|
|
312
|
+
return {};
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
function sanitizeAttributes(attributes) {
|
|
316
|
+
return Object.fromEntries(Object.entries(attributes).filter(([, value]) => !isBlankValue(value)));
|
|
317
|
+
}
|
|
318
|
+
function writeAttributes(base, attributes) {
|
|
319
|
+
const sanitized = sanitizeAttributes(attributes);
|
|
320
|
+
if (Object.keys(sanitized).length === 0) {
|
|
321
|
+
base.removeItem(DMD_ATTRIBUTES_STORAGE_KEY);
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
base.setItem(DMD_ATTRIBUTES_STORAGE_KEY, JSON.stringify(sanitized));
|
|
325
|
+
}
|
|
326
|
+
function parseSessionData(value) {
|
|
327
|
+
try {
|
|
328
|
+
const parsed = JSON.parse(value);
|
|
329
|
+
const sessionData = {};
|
|
330
|
+
const sessionId = typeof parsed.sessionId === "string" && parsed.sessionId.trim() !== "" ? parsed.sessionId : void 0;
|
|
331
|
+
const timestamp = typeof parsed.timestamp === "number" ? parsed.timestamp : void 0;
|
|
332
|
+
if (sessionId !== void 0) sessionData.sessionId = sessionId;
|
|
333
|
+
if (timestamp !== void 0) sessionData.timestamp = timestamp;
|
|
334
|
+
return sessionData;
|
|
335
|
+
} catch {
|
|
336
|
+
return {};
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
function getAggregateValue(attributes, key) {
|
|
340
|
+
if (key === SESSION_STORAGE_KEY) {
|
|
341
|
+
const sessionId = attributes[SESSION_ID_KEY];
|
|
342
|
+
const timestamp = attributes[SESSION_TIMESTAMP_KEY];
|
|
343
|
+
if (typeof sessionId === "string" && !isBlankValue(sessionId) && typeof timestamp === "number") {
|
|
344
|
+
return JSON.stringify({ sessionId, timestamp });
|
|
345
|
+
}
|
|
346
|
+
return null;
|
|
347
|
+
}
|
|
348
|
+
const value = attributes[key];
|
|
349
|
+
if (isBlankValue(value)) return null;
|
|
350
|
+
return typeof value === "string" ? value : JSON.stringify(value);
|
|
351
|
+
}
|
|
352
|
+
function setAggregateValue(attributes, key, value) {
|
|
353
|
+
if (key === SESSION_STORAGE_KEY) {
|
|
354
|
+
const sessionData = parseSessionData(value);
|
|
355
|
+
if (sessionData.sessionId === void 0 || sessionData.timestamp === void 0) {
|
|
356
|
+
delete attributes[SESSION_ID_KEY];
|
|
357
|
+
delete attributes[SESSION_TIMESTAMP_KEY];
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
attributes[SESSION_ID_KEY] = sessionData.sessionId;
|
|
361
|
+
attributes[SESSION_TIMESTAMP_KEY] = sessionData.timestamp;
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
attributes[key] = value;
|
|
365
|
+
}
|
|
366
|
+
function removeAggregateValue(attributes, key) {
|
|
367
|
+
if (key === SESSION_STORAGE_KEY) {
|
|
368
|
+
delete attributes[SESSION_ID_KEY];
|
|
369
|
+
delete attributes[SESSION_TIMESTAMP_KEY];
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
delete attributes[key];
|
|
373
|
+
}
|
|
374
|
+
function createDmdAttributesPersistence(base) {
|
|
375
|
+
return {
|
|
376
|
+
getItem(key) {
|
|
377
|
+
if (key === DMD_ATTRIBUTES_STORAGE_KEY) return base.getItem(key);
|
|
378
|
+
const attributes = readAttributes(base);
|
|
379
|
+
const aggregateValue = getAggregateValue(attributes, key);
|
|
380
|
+
if (aggregateValue !== null) return aggregateValue;
|
|
381
|
+
const legacyValue = base.getItem(key);
|
|
382
|
+
if (isBlankValue(legacyValue)) return null;
|
|
383
|
+
setAggregateValue(attributes, key, String(legacyValue));
|
|
384
|
+
writeAttributes(base, attributes);
|
|
385
|
+
return legacyValue;
|
|
386
|
+
},
|
|
387
|
+
setItem(key, value) {
|
|
388
|
+
if (key === DMD_ATTRIBUTES_STORAGE_KEY) return base.setItem(key, value);
|
|
389
|
+
const attributes = readAttributes(base);
|
|
390
|
+
if (isBlankValue(value)) {
|
|
391
|
+
removeAggregateValue(attributes, key);
|
|
392
|
+
writeAttributes(base, attributes);
|
|
393
|
+
base.removeItem(key);
|
|
394
|
+
return true;
|
|
395
|
+
}
|
|
396
|
+
setAggregateValue(attributes, key, value);
|
|
397
|
+
writeAttributes(base, attributes);
|
|
398
|
+
base.setItem(key, value);
|
|
399
|
+
return true;
|
|
400
|
+
},
|
|
401
|
+
removeItem(key) {
|
|
402
|
+
if (key === DMD_ATTRIBUTES_STORAGE_KEY) {
|
|
403
|
+
base.removeItem(key);
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
const attributes = readAttributes(base);
|
|
407
|
+
removeAggregateValue(attributes, key);
|
|
408
|
+
writeAttributes(base, attributes);
|
|
409
|
+
base.removeItem(key);
|
|
410
|
+
},
|
|
411
|
+
getHealth() {
|
|
412
|
+
return base.getHealth();
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
|
|
287
417
|
// src/core/attribution.ts
|
|
288
418
|
var dmdUtmKeys = [
|
|
289
419
|
"utm_source",
|
|
@@ -320,6 +450,10 @@ function mergeAttributionRecords(explicitProperties, stored) {
|
|
|
320
450
|
}
|
|
321
451
|
|
|
322
452
|
// src/browser/core/attribution.ts
|
|
453
|
+
var DMD_CLICK_ID_QUERY_KEY = "click_id";
|
|
454
|
+
var DMD_CLICK_ID_LEGACY_QUERY_KEY = "dmd_click_id";
|
|
455
|
+
var DMD_CLICK_ID_STORAGE_KEY = "dmd_click_id";
|
|
456
|
+
var DMD_CLICK_ID_ATTRIBUTE_KEY = "click_id";
|
|
323
457
|
function getCurrentUrl() {
|
|
324
458
|
return getBrowserWindow()?.location?.href;
|
|
325
459
|
}
|
|
@@ -338,6 +472,9 @@ function setIfPresent(persistence, key, value) {
|
|
|
338
472
|
persistence.setItem(key, value);
|
|
339
473
|
}
|
|
340
474
|
}
|
|
475
|
+
function getClickIdParam(params) {
|
|
476
|
+
return params.get(DMD_CLICK_ID_LEGACY_QUERY_KEY) || params.get(DMD_CLICK_ID_QUERY_KEY);
|
|
477
|
+
}
|
|
341
478
|
function getStoredString(persistence, key) {
|
|
342
479
|
const value = persistence.getItem(key);
|
|
343
480
|
return value === null || value === "" ? void 0 : value;
|
|
@@ -357,6 +494,9 @@ function captureAttributionFromUrl(persistence, url = getCurrentUrl()) {
|
|
|
357
494
|
for (const key of dmdCampaignKeys) {
|
|
358
495
|
setIfPresent(persistence, key, params.get(key));
|
|
359
496
|
}
|
|
497
|
+
const clickId = getClickIdParam(params);
|
|
498
|
+
setIfPresent(persistence, DMD_CLICK_ID_ATTRIBUTE_KEY, clickId);
|
|
499
|
+
setIfPresent(persistence, DMD_CLICK_ID_STORAGE_KEY, clickId);
|
|
360
500
|
for (const [param, sdkPubId] of dmdClickIdSources) {
|
|
361
501
|
const value = params.get(param);
|
|
362
502
|
if (value) {
|
|
@@ -372,7 +512,8 @@ function getStoredAttributionData(persistence) {
|
|
|
372
512
|
fbc: getStoredString(persistence, "fbc") ?? getCookie("_fbc"),
|
|
373
513
|
fbp: getStoredString(persistence, "fbp") ?? getCookie("_fbp"),
|
|
374
514
|
campaign_id: getStoredString(persistence, "campaign_id"),
|
|
375
|
-
ad_id: getStoredString(persistence, "ad_id")
|
|
515
|
+
ad_id: getStoredString(persistence, "ad_id"),
|
|
516
|
+
click_id: getStoredString(persistence, DMD_CLICK_ID_STORAGE_KEY) ?? getStoredString(persistence, DMD_CLICK_ID_ATTRIBUTE_KEY)
|
|
376
517
|
});
|
|
377
518
|
}
|
|
378
519
|
function getStoredUtmParameter(persistence) {
|
|
@@ -891,6 +1032,24 @@ function resetAnonymousId(persistence) {
|
|
|
891
1032
|
return anonymousId;
|
|
892
1033
|
}
|
|
893
1034
|
|
|
1035
|
+
// src/browser/core/page-context.ts
|
|
1036
|
+
function redactSearch(search) {
|
|
1037
|
+
const redacted = redactUrl(search);
|
|
1038
|
+
return redacted.startsWith("/?") ? redacted.slice(1) : redacted;
|
|
1039
|
+
}
|
|
1040
|
+
function getBrowserPageContext() {
|
|
1041
|
+
const browserWindow = getBrowserWindow();
|
|
1042
|
+
const documentRef = browserWindow?.document ?? globalThis.document;
|
|
1043
|
+
const location = browserWindow?.location;
|
|
1044
|
+
const page2 = {};
|
|
1045
|
+
if (location?.href) page2.url = location.href;
|
|
1046
|
+
if (location?.pathname) page2.path = location.pathname;
|
|
1047
|
+
if (location?.search) page2.search = redactSearch(location.search);
|
|
1048
|
+
if (documentRef?.title) page2.title = documentRef.title;
|
|
1049
|
+
if (documentRef?.referrer) page2.referrer = redactUrl(documentRef.referrer);
|
|
1050
|
+
return page2;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
894
1053
|
// src/browser/core/persistence.ts
|
|
895
1054
|
function createPersistenceHealth(requested) {
|
|
896
1055
|
return {
|
|
@@ -1057,7 +1216,7 @@ function createBrowserPersistence(mode = "localStorage+cookie") {
|
|
|
1057
1216
|
}
|
|
1058
1217
|
|
|
1059
1218
|
// src/browser/core/session.ts
|
|
1060
|
-
var
|
|
1219
|
+
var SESSION_STORAGE_KEY2 = "sessionData";
|
|
1061
1220
|
function getUrlParam2(name) {
|
|
1062
1221
|
const href = getBrowserWindow()?.location?.href;
|
|
1063
1222
|
if (!href) return null;
|
|
@@ -1068,7 +1227,7 @@ function getUrlParam2(name) {
|
|
|
1068
1227
|
}
|
|
1069
1228
|
}
|
|
1070
1229
|
function readStoredSession(persistence) {
|
|
1071
|
-
const rawSession = persistence.getItem(
|
|
1230
|
+
const rawSession = persistence.getItem(SESSION_STORAGE_KEY2);
|
|
1072
1231
|
if (!rawSession) return void 0;
|
|
1073
1232
|
try {
|
|
1074
1233
|
const parsed = JSON.parse(rawSession);
|
|
@@ -1079,12 +1238,12 @@ function readStoredSession(persistence) {
|
|
|
1079
1238
|
};
|
|
1080
1239
|
}
|
|
1081
1240
|
} catch {
|
|
1082
|
-
persistence.removeItem(
|
|
1241
|
+
persistence.removeItem(SESSION_STORAGE_KEY2);
|
|
1083
1242
|
}
|
|
1084
1243
|
return void 0;
|
|
1085
1244
|
}
|
|
1086
1245
|
function writeStoredSession(persistence, sessionId, timestamp) {
|
|
1087
|
-
persistence.setItem(
|
|
1246
|
+
persistence.setItem(SESSION_STORAGE_KEY2, JSON.stringify({ sessionId, timestamp }));
|
|
1088
1247
|
}
|
|
1089
1248
|
function createSessionManager(persistence, idleTimeoutSeconds = 30 * 60) {
|
|
1090
1249
|
function resolveSessionId() {
|
|
@@ -1138,11 +1297,12 @@ var DriveMetaDataSDK = class {
|
|
|
1138
1297
|
requireConfigString(config.writeKey || config.token, "writeKey or token");
|
|
1139
1298
|
this.config = config;
|
|
1140
1299
|
this.endpoint = endpointFromConfig(config);
|
|
1141
|
-
|
|
1300
|
+
const storagePersistence = createBrowserPersistence(config.persistence);
|
|
1301
|
+
this.persistence = createDmdAttributesPersistence(storagePersistence);
|
|
1142
1302
|
this.session = createSessionManager(this.persistence, config.sessionIdleTimeoutSeconds);
|
|
1143
1303
|
const deliveryConfig = {
|
|
1144
1304
|
endpoint: this.endpoint,
|
|
1145
|
-
storage:
|
|
1305
|
+
storage: storagePersistence
|
|
1146
1306
|
};
|
|
1147
1307
|
if (config.delivery?.maxQueueSize !== void 0) deliveryConfig.maxQueueSize = config.delivery.maxQueueSize;
|
|
1148
1308
|
if (config.delivery?.queueTtlMs !== void 0) deliveryConfig.queueTtlMs = config.delivery.queueTtlMs;
|
|
@@ -1387,6 +1547,7 @@ var DriveMetaDataSDK = class {
|
|
|
1387
1547
|
}
|
|
1388
1548
|
toCollectorPayload(prepared) {
|
|
1389
1549
|
const browserWindow = getBrowserWindow();
|
|
1550
|
+
const pageContext = getBrowserPageContext();
|
|
1390
1551
|
return createBackendCollectorPayload({
|
|
1391
1552
|
requestId: prepared.messageId,
|
|
1392
1553
|
timestamp: prepared.timestamp,
|
|
@@ -1398,9 +1559,13 @@ var DriveMetaDataSDK = class {
|
|
|
1398
1559
|
sessionId: prepared.sessionId,
|
|
1399
1560
|
ua: browserWindow?.navigator?.userAgent,
|
|
1400
1561
|
appId: prepared.appId,
|
|
1401
|
-
pageUrl: browserWindow?.location?.href,
|
|
1562
|
+
pageUrl: pageContext.url ?? browserWindow?.location?.href,
|
|
1402
1563
|
eventData: mergeStoredAttribution({
|
|
1403
1564
|
...prepared.properties,
|
|
1565
|
+
page: {
|
|
1566
|
+
...pageContext,
|
|
1567
|
+
...prepared.properties.page && typeof prepared.properties.page === "object" ? prepared.properties.page : {}
|
|
1568
|
+
},
|
|
1404
1569
|
anonymousId: prepared.anonymousId,
|
|
1405
1570
|
sessionId: prepared.sessionId,
|
|
1406
1571
|
timestamp: prepared.timestamp,
|