@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.js
CHANGED
|
@@ -227,6 +227,15 @@ var sensitiveKeys = /* @__PURE__ */ new Set([
|
|
|
227
227
|
"session",
|
|
228
228
|
"cookie"
|
|
229
229
|
]);
|
|
230
|
+
function redactUrl(url, allowQueryKeys = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"]) {
|
|
231
|
+
const parsed = new URL(url, "https://placeholder.local");
|
|
232
|
+
for (const key of Array.from(parsed.searchParams.keys())) {
|
|
233
|
+
if (!allowQueryKeys.includes(key)) {
|
|
234
|
+
parsed.searchParams.set(key, "[REDACTED]");
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return url.startsWith("http") ? parsed.toString() : `${parsed.pathname}${parsed.search}`;
|
|
238
|
+
}
|
|
230
239
|
function sanitizeValue(value, allow, path = []) {
|
|
231
240
|
if (Array.isArray(value)) {
|
|
232
241
|
return value.map((item) => sanitizeValue(item, allow, path));
|
|
@@ -248,6 +257,127 @@ function sanitizeProperties(input, allowRawKeys = []) {
|
|
|
248
257
|
return sanitizeValue(input, allow);
|
|
249
258
|
}
|
|
250
259
|
|
|
260
|
+
// src/browser/core/attribute-persistence.ts
|
|
261
|
+
var DMD_ATTRIBUTES_STORAGE_KEY = "dmd_attributes";
|
|
262
|
+
var SESSION_STORAGE_KEY = "sessionData";
|
|
263
|
+
var SESSION_ID_KEY = "sessionId";
|
|
264
|
+
var SESSION_TIMESTAMP_KEY = "timestamp";
|
|
265
|
+
function isBlankValue(value) {
|
|
266
|
+
return value === null || value === void 0 || typeof value === "string" && value.trim() === "";
|
|
267
|
+
}
|
|
268
|
+
function readAttributes(base) {
|
|
269
|
+
const raw = base.getItem(DMD_ATTRIBUTES_STORAGE_KEY);
|
|
270
|
+
if (!raw) return {};
|
|
271
|
+
try {
|
|
272
|
+
const parsed = JSON.parse(raw);
|
|
273
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
274
|
+
} catch {
|
|
275
|
+
base.removeItem(DMD_ATTRIBUTES_STORAGE_KEY);
|
|
276
|
+
return {};
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
function sanitizeAttributes(attributes) {
|
|
280
|
+
return Object.fromEntries(Object.entries(attributes).filter(([, value]) => !isBlankValue(value)));
|
|
281
|
+
}
|
|
282
|
+
function writeAttributes(base, attributes) {
|
|
283
|
+
const sanitized = sanitizeAttributes(attributes);
|
|
284
|
+
if (Object.keys(sanitized).length === 0) {
|
|
285
|
+
base.removeItem(DMD_ATTRIBUTES_STORAGE_KEY);
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
base.setItem(DMD_ATTRIBUTES_STORAGE_KEY, JSON.stringify(sanitized));
|
|
289
|
+
}
|
|
290
|
+
function parseSessionData(value) {
|
|
291
|
+
try {
|
|
292
|
+
const parsed = JSON.parse(value);
|
|
293
|
+
const sessionData = {};
|
|
294
|
+
const sessionId = typeof parsed.sessionId === "string" && parsed.sessionId.trim() !== "" ? parsed.sessionId : void 0;
|
|
295
|
+
const timestamp = typeof parsed.timestamp === "number" ? parsed.timestamp : void 0;
|
|
296
|
+
if (sessionId !== void 0) sessionData.sessionId = sessionId;
|
|
297
|
+
if (timestamp !== void 0) sessionData.timestamp = timestamp;
|
|
298
|
+
return sessionData;
|
|
299
|
+
} catch {
|
|
300
|
+
return {};
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
function getAggregateValue(attributes, key) {
|
|
304
|
+
if (key === SESSION_STORAGE_KEY) {
|
|
305
|
+
const sessionId = attributes[SESSION_ID_KEY];
|
|
306
|
+
const timestamp = attributes[SESSION_TIMESTAMP_KEY];
|
|
307
|
+
if (typeof sessionId === "string" && !isBlankValue(sessionId) && typeof timestamp === "number") {
|
|
308
|
+
return JSON.stringify({ sessionId, timestamp });
|
|
309
|
+
}
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
const value = attributes[key];
|
|
313
|
+
if (isBlankValue(value)) return null;
|
|
314
|
+
return typeof value === "string" ? value : JSON.stringify(value);
|
|
315
|
+
}
|
|
316
|
+
function setAggregateValue(attributes, key, value) {
|
|
317
|
+
if (key === SESSION_STORAGE_KEY) {
|
|
318
|
+
const sessionData = parseSessionData(value);
|
|
319
|
+
if (sessionData.sessionId === void 0 || sessionData.timestamp === void 0) {
|
|
320
|
+
delete attributes[SESSION_ID_KEY];
|
|
321
|
+
delete attributes[SESSION_TIMESTAMP_KEY];
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
attributes[SESSION_ID_KEY] = sessionData.sessionId;
|
|
325
|
+
attributes[SESSION_TIMESTAMP_KEY] = sessionData.timestamp;
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
attributes[key] = value;
|
|
329
|
+
}
|
|
330
|
+
function removeAggregateValue(attributes, key) {
|
|
331
|
+
if (key === SESSION_STORAGE_KEY) {
|
|
332
|
+
delete attributes[SESSION_ID_KEY];
|
|
333
|
+
delete attributes[SESSION_TIMESTAMP_KEY];
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
delete attributes[key];
|
|
337
|
+
}
|
|
338
|
+
function createDmdAttributesPersistence(base) {
|
|
339
|
+
return {
|
|
340
|
+
getItem(key) {
|
|
341
|
+
if (key === DMD_ATTRIBUTES_STORAGE_KEY) return base.getItem(key);
|
|
342
|
+
const attributes = readAttributes(base);
|
|
343
|
+
const aggregateValue = getAggregateValue(attributes, key);
|
|
344
|
+
if (aggregateValue !== null) return aggregateValue;
|
|
345
|
+
const legacyValue = base.getItem(key);
|
|
346
|
+
if (isBlankValue(legacyValue)) return null;
|
|
347
|
+
setAggregateValue(attributes, key, String(legacyValue));
|
|
348
|
+
writeAttributes(base, attributes);
|
|
349
|
+
return legacyValue;
|
|
350
|
+
},
|
|
351
|
+
setItem(key, value) {
|
|
352
|
+
if (key === DMD_ATTRIBUTES_STORAGE_KEY) return base.setItem(key, value);
|
|
353
|
+
const attributes = readAttributes(base);
|
|
354
|
+
if (isBlankValue(value)) {
|
|
355
|
+
removeAggregateValue(attributes, key);
|
|
356
|
+
writeAttributes(base, attributes);
|
|
357
|
+
base.removeItem(key);
|
|
358
|
+
return true;
|
|
359
|
+
}
|
|
360
|
+
setAggregateValue(attributes, key, value);
|
|
361
|
+
writeAttributes(base, attributes);
|
|
362
|
+
base.setItem(key, value);
|
|
363
|
+
return true;
|
|
364
|
+
},
|
|
365
|
+
removeItem(key) {
|
|
366
|
+
if (key === DMD_ATTRIBUTES_STORAGE_KEY) {
|
|
367
|
+
base.removeItem(key);
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
const attributes = readAttributes(base);
|
|
371
|
+
removeAggregateValue(attributes, key);
|
|
372
|
+
writeAttributes(base, attributes);
|
|
373
|
+
base.removeItem(key);
|
|
374
|
+
},
|
|
375
|
+
getHealth() {
|
|
376
|
+
return base.getHealth();
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
|
|
251
381
|
// src/core/attribution.ts
|
|
252
382
|
var dmdUtmKeys = [
|
|
253
383
|
"utm_source",
|
|
@@ -284,6 +414,10 @@ function mergeAttributionRecords(explicitProperties, stored) {
|
|
|
284
414
|
}
|
|
285
415
|
|
|
286
416
|
// src/browser/core/attribution.ts
|
|
417
|
+
var DMD_CLICK_ID_QUERY_KEY = "click_id";
|
|
418
|
+
var DMD_CLICK_ID_LEGACY_QUERY_KEY = "dmd_click_id";
|
|
419
|
+
var DMD_CLICK_ID_STORAGE_KEY = "dmd_click_id";
|
|
420
|
+
var DMD_CLICK_ID_ATTRIBUTE_KEY = "click_id";
|
|
287
421
|
function getCurrentUrl() {
|
|
288
422
|
return getBrowserWindow()?.location?.href;
|
|
289
423
|
}
|
|
@@ -302,6 +436,9 @@ function setIfPresent(persistence, key, value) {
|
|
|
302
436
|
persistence.setItem(key, value);
|
|
303
437
|
}
|
|
304
438
|
}
|
|
439
|
+
function getClickIdParam(params) {
|
|
440
|
+
return params.get(DMD_CLICK_ID_LEGACY_QUERY_KEY) || params.get(DMD_CLICK_ID_QUERY_KEY);
|
|
441
|
+
}
|
|
305
442
|
function getStoredString(persistence, key) {
|
|
306
443
|
const value = persistence.getItem(key);
|
|
307
444
|
return value === null || value === "" ? void 0 : value;
|
|
@@ -321,6 +458,9 @@ function captureAttributionFromUrl(persistence, url = getCurrentUrl()) {
|
|
|
321
458
|
for (const key of dmdCampaignKeys) {
|
|
322
459
|
setIfPresent(persistence, key, params.get(key));
|
|
323
460
|
}
|
|
461
|
+
const clickId = getClickIdParam(params);
|
|
462
|
+
setIfPresent(persistence, DMD_CLICK_ID_ATTRIBUTE_KEY, clickId);
|
|
463
|
+
setIfPresent(persistence, DMD_CLICK_ID_STORAGE_KEY, clickId);
|
|
324
464
|
for (const [param, sdkPubId] of dmdClickIdSources) {
|
|
325
465
|
const value = params.get(param);
|
|
326
466
|
if (value) {
|
|
@@ -336,7 +476,8 @@ function getStoredAttributionData(persistence) {
|
|
|
336
476
|
fbc: getStoredString(persistence, "fbc") ?? getCookie("_fbc"),
|
|
337
477
|
fbp: getStoredString(persistence, "fbp") ?? getCookie("_fbp"),
|
|
338
478
|
campaign_id: getStoredString(persistence, "campaign_id"),
|
|
339
|
-
ad_id: getStoredString(persistence, "ad_id")
|
|
479
|
+
ad_id: getStoredString(persistence, "ad_id"),
|
|
480
|
+
click_id: getStoredString(persistence, DMD_CLICK_ID_STORAGE_KEY) ?? getStoredString(persistence, DMD_CLICK_ID_ATTRIBUTE_KEY)
|
|
340
481
|
});
|
|
341
482
|
}
|
|
342
483
|
function getStoredUtmParameter(persistence) {
|
|
@@ -855,6 +996,24 @@ function resetAnonymousId(persistence) {
|
|
|
855
996
|
return anonymousId;
|
|
856
997
|
}
|
|
857
998
|
|
|
999
|
+
// src/browser/core/page-context.ts
|
|
1000
|
+
function redactSearch(search) {
|
|
1001
|
+
const redacted = redactUrl(search);
|
|
1002
|
+
return redacted.startsWith("/?") ? redacted.slice(1) : redacted;
|
|
1003
|
+
}
|
|
1004
|
+
function getBrowserPageContext() {
|
|
1005
|
+
const browserWindow = getBrowserWindow();
|
|
1006
|
+
const documentRef = browserWindow?.document ?? globalThis.document;
|
|
1007
|
+
const location = browserWindow?.location;
|
|
1008
|
+
const page2 = {};
|
|
1009
|
+
if (location?.href) page2.url = location.href;
|
|
1010
|
+
if (location?.pathname) page2.path = location.pathname;
|
|
1011
|
+
if (location?.search) page2.search = redactSearch(location.search);
|
|
1012
|
+
if (documentRef?.title) page2.title = documentRef.title;
|
|
1013
|
+
if (documentRef?.referrer) page2.referrer = redactUrl(documentRef.referrer);
|
|
1014
|
+
return page2;
|
|
1015
|
+
}
|
|
1016
|
+
|
|
858
1017
|
// src/browser/core/persistence.ts
|
|
859
1018
|
function createPersistenceHealth(requested) {
|
|
860
1019
|
return {
|
|
@@ -1021,7 +1180,7 @@ function createBrowserPersistence(mode = "localStorage+cookie") {
|
|
|
1021
1180
|
}
|
|
1022
1181
|
|
|
1023
1182
|
// src/browser/core/session.ts
|
|
1024
|
-
var
|
|
1183
|
+
var SESSION_STORAGE_KEY2 = "sessionData";
|
|
1025
1184
|
function getUrlParam2(name) {
|
|
1026
1185
|
const href = getBrowserWindow()?.location?.href;
|
|
1027
1186
|
if (!href) return null;
|
|
@@ -1032,7 +1191,7 @@ function getUrlParam2(name) {
|
|
|
1032
1191
|
}
|
|
1033
1192
|
}
|
|
1034
1193
|
function readStoredSession(persistence) {
|
|
1035
|
-
const rawSession = persistence.getItem(
|
|
1194
|
+
const rawSession = persistence.getItem(SESSION_STORAGE_KEY2);
|
|
1036
1195
|
if (!rawSession) return void 0;
|
|
1037
1196
|
try {
|
|
1038
1197
|
const parsed = JSON.parse(rawSession);
|
|
@@ -1043,12 +1202,12 @@ function readStoredSession(persistence) {
|
|
|
1043
1202
|
};
|
|
1044
1203
|
}
|
|
1045
1204
|
} catch {
|
|
1046
|
-
persistence.removeItem(
|
|
1205
|
+
persistence.removeItem(SESSION_STORAGE_KEY2);
|
|
1047
1206
|
}
|
|
1048
1207
|
return void 0;
|
|
1049
1208
|
}
|
|
1050
1209
|
function writeStoredSession(persistence, sessionId, timestamp) {
|
|
1051
|
-
persistence.setItem(
|
|
1210
|
+
persistence.setItem(SESSION_STORAGE_KEY2, JSON.stringify({ sessionId, timestamp }));
|
|
1052
1211
|
}
|
|
1053
1212
|
function createSessionManager(persistence, idleTimeoutSeconds = 30 * 60) {
|
|
1054
1213
|
function resolveSessionId() {
|
|
@@ -1102,11 +1261,12 @@ var DriveMetaDataSDK = class {
|
|
|
1102
1261
|
requireConfigString(config.writeKey || config.token, "writeKey or token");
|
|
1103
1262
|
this.config = config;
|
|
1104
1263
|
this.endpoint = endpointFromConfig(config);
|
|
1105
|
-
|
|
1264
|
+
const storagePersistence = createBrowserPersistence(config.persistence);
|
|
1265
|
+
this.persistence = createDmdAttributesPersistence(storagePersistence);
|
|
1106
1266
|
this.session = createSessionManager(this.persistence, config.sessionIdleTimeoutSeconds);
|
|
1107
1267
|
const deliveryConfig = {
|
|
1108
1268
|
endpoint: this.endpoint,
|
|
1109
|
-
storage:
|
|
1269
|
+
storage: storagePersistence
|
|
1110
1270
|
};
|
|
1111
1271
|
if (config.delivery?.maxQueueSize !== void 0) deliveryConfig.maxQueueSize = config.delivery.maxQueueSize;
|
|
1112
1272
|
if (config.delivery?.queueTtlMs !== void 0) deliveryConfig.queueTtlMs = config.delivery.queueTtlMs;
|
|
@@ -1351,6 +1511,7 @@ var DriveMetaDataSDK = class {
|
|
|
1351
1511
|
}
|
|
1352
1512
|
toCollectorPayload(prepared) {
|
|
1353
1513
|
const browserWindow = getBrowserWindow();
|
|
1514
|
+
const pageContext = getBrowserPageContext();
|
|
1354
1515
|
return createBackendCollectorPayload({
|
|
1355
1516
|
requestId: prepared.messageId,
|
|
1356
1517
|
timestamp: prepared.timestamp,
|
|
@@ -1362,9 +1523,13 @@ var DriveMetaDataSDK = class {
|
|
|
1362
1523
|
sessionId: prepared.sessionId,
|
|
1363
1524
|
ua: browserWindow?.navigator?.userAgent,
|
|
1364
1525
|
appId: prepared.appId,
|
|
1365
|
-
pageUrl: browserWindow?.location?.href,
|
|
1526
|
+
pageUrl: pageContext.url ?? browserWindow?.location?.href,
|
|
1366
1527
|
eventData: mergeStoredAttribution({
|
|
1367
1528
|
...prepared.properties,
|
|
1529
|
+
page: {
|
|
1530
|
+
...pageContext,
|
|
1531
|
+
...prepared.properties.page && typeof prepared.properties.page === "object" ? prepared.properties.page : {}
|
|
1532
|
+
},
|
|
1368
1533
|
anonymousId: prepared.anonymousId,
|
|
1369
1534
|
sessionId: prepared.sessionId,
|
|
1370
1535
|
timestamp: prepared.timestamp,
|