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