@drivemetadata-ai/sdk 0.1.1-beta.1 → 0.1.1-beta.2

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.
Files changed (42) hide show
  1. package/README.md +18 -15
  2. package/dist/angular/index.cjs +118 -115
  3. package/dist/angular/index.cjs.map +1 -1
  4. package/dist/angular/index.d.cts +2 -2
  5. package/dist/angular/index.d.ts +2 -2
  6. package/dist/angular/index.js +118 -115
  7. package/dist/angular/index.js.map +1 -1
  8. package/dist/browser/index.cjs +119 -116
  9. package/dist/browser/index.cjs.map +1 -1
  10. package/dist/browser/index.d.cts +5 -68
  11. package/dist/browser/index.d.ts +5 -68
  12. package/dist/browser/index.js +119 -116
  13. package/dist/browser/index.js.map +1 -1
  14. package/dist/next/index.cjs +119 -115
  15. package/dist/next/index.cjs.map +1 -1
  16. package/dist/next/index.d.cts +1 -1
  17. package/dist/next/index.d.ts +1 -1
  18. package/dist/next/index.js +119 -115
  19. package/dist/next/index.js.map +1 -1
  20. package/dist/node/index.cjs +80 -7
  21. package/dist/node/index.cjs.map +1 -1
  22. package/dist/node/index.d.cts +7 -1
  23. package/dist/node/index.d.ts +7 -1
  24. package/dist/node/index.js +80 -7
  25. package/dist/node/index.js.map +1 -1
  26. package/dist/react/index.cjs +119 -115
  27. package/dist/react/index.cjs.map +1 -1
  28. package/dist/react/index.d.cts +2 -2
  29. package/dist/react/index.d.ts +2 -2
  30. package/dist/react/index.js +119 -115
  31. package/dist/react/index.js.map +1 -1
  32. package/dist/{types-BwtS0ZDu.d.cts → types--V8TVIqT.d.cts} +7 -3
  33. package/dist/{types-BwtS0ZDu.d.ts → types--V8TVIqT.d.ts} +7 -3
  34. package/docs/angular-integration.md +6 -6
  35. package/docs/index.md +4 -6
  36. package/docs/integration.md +322 -0
  37. package/docs/node-server-integration.md +16 -7
  38. package/docs/npm-browser-sdk.md +4 -8
  39. package/docs/react-next-integration.md +9 -9
  40. package/docs/security-privacy.md +11 -11
  41. package/package.json +4 -5
  42. package/docs/migration-cdn-to-npm.md +0 -99
@@ -3,53 +3,62 @@
3
3
  // src/react/DmdProvider.tsx
4
4
  import React from "react";
5
5
 
6
- // src/core/config.ts
7
- function requireString(value, field) {
8
- if (typeof value !== "string" || value.trim() === "") {
9
- throw new Error(`DMD SDK config ${field} is required`);
6
+ // src/core/backend-payload.ts
7
+ function formatUtcTimestamp(value) {
8
+ if (typeof value !== "string") return (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
9
+ const date = new Date(value);
10
+ if (Number.isNaN(date.getTime())) return value;
11
+ return date.toISOString().replace("T", " ").slice(0, 19);
12
+ }
13
+ function cleanObject(value) {
14
+ if (Array.isArray(value)) {
15
+ const cleaned = value.map((item) => cleanObject(item)).filter((item) => item !== null && item !== void 0 && item !== "");
16
+ return cleaned.length > 0 ? cleaned : void 0;
17
+ }
18
+ if (value && typeof value === "object") {
19
+ const cleaned = Object.fromEntries(
20
+ Object.entries(value).map(([key, item]) => [key, cleanObject(item)]).filter(([, item]) => {
21
+ if (item === null || item === void 0 || item === "") return false;
22
+ if (typeof item === "object" && !Array.isArray(item) && Object.keys(item).length === 0) return false;
23
+ return true;
24
+ })
25
+ );
26
+ return Object.keys(cleaned).length > 0 ? cleaned : void 0;
10
27
  }
11
28
  return value;
12
29
  }
13
- function normalizeBrowserConfig(config) {
14
- const writeKey = config.writeKey || config.token;
15
- const legacyConfig = {
16
- client_id: requireString(config.clientId, "clientId"),
17
- workspace_id: requireString(config.workspaceId, "workspaceId"),
18
- app_id: requireString(config.appId, "appId"),
19
- token: requireString(writeKey, "writeKey")
30
+ function createBackendCollectorPayload(input) {
31
+ const eventData = input.eventData && typeof input.eventData === "object" ? input.eventData : {};
32
+ const page2 = eventData.page && typeof eventData.page === "object" ? eventData.page : {};
33
+ const timestamp = formatUtcTimestamp(eventData.timestamp ?? input.timestamp);
34
+ const normalizedEventData = {
35
+ ...eventData,
36
+ timestamp,
37
+ requestSentAt: formatUtcTimestamp(eventData.requestSentAt ?? input.requestSentAt ?? timestamp),
38
+ requestReceivedAt: formatUtcTimestamp(eventData.requestReceivedAt ?? input.requestReceivedAt ?? timestamp)
39
+ };
40
+ const metaData = {
41
+ ...normalizedEventData,
42
+ requestId: input.requestId,
43
+ timestamp,
44
+ eventType: input.eventType,
45
+ requestFrom: input.requestFrom ?? "3",
46
+ clientId: input.clientId,
47
+ workspaceId: input.workspaceId,
48
+ token: input.token,
49
+ anonymousId: eventData.anonymousId ?? input.anonymousId,
50
+ sessionId: eventData.sessionId ?? input.sessionId,
51
+ ua: input.ua,
52
+ appDetails: { app_id: input.appId },
53
+ page: { ...page2, url: page2.url ?? input.pageUrl },
54
+ requestSentAt: normalizedEventData.requestSentAt,
55
+ requestReceivedAt: normalizedEventData.requestReceivedAt
20
56
  };
21
- if (config.apiHost !== void 0) legacyConfig.api_host = config.apiHost;
22
- if (config.uiHost !== void 0) legacyConfig.ui_host = config.uiHost;
23
- if (config.deeplink !== void 0) legacyConfig.deeplink = config.deeplink;
24
- if (config.debug !== void 0) legacyConfig.debug = config.debug;
25
- if (config.consent !== void 0) legacyConfig.consent = config.consent;
26
- if (config.gdprConsent !== void 0) legacyConfig.gdprConsent = config.gdprConsent;
27
- if (config.autocapture !== void 0) legacyConfig.autocapture = config.autocapture;
28
- if (config.capturePageview !== void 0) legacyConfig.capture_pageview = config.capturePageview;
29
- if (config.capturePageleave !== void 0) legacyConfig.capture_pageleave = config.capturePageleave;
30
- if (config.captureDeadClicks !== void 0) legacyConfig.capture_dead_clicks = config.captureDeadClicks;
31
- if (config.crossSubdomainCookie !== void 0) legacyConfig.cross_subdomain_cookie = config.crossSubdomainCookie;
32
- if (config.disablePersistence !== void 0) legacyConfig.disable_persistence = config.disablePersistence;
33
- if (config.disableSurveys !== void 0) legacyConfig.disable_surveys = config.disableSurveys;
34
- if (config.disableSessionRecording !== void 0) legacyConfig.disable_session_recording = config.disableSessionRecording;
35
- if (config.enableHeatmaps !== void 0) legacyConfig.enable_heatmaps = config.enableHeatmaps;
36
- if (config.maskAllText !== void 0) legacyConfig.mask_all_text = config.maskAllText;
37
- if (config.maskAllElementAttributes !== void 0) {
38
- legacyConfig.mask_all_element_attributes = config.maskAllElementAttributes;
39
- }
40
- if (config.persistence !== void 0) legacyConfig.persistence = config.persistence;
41
- if (config.propertyDenylist !== void 0) legacyConfig.property_denylist = config.propertyDenylist;
42
- if (config.sessionIdleTimeoutSeconds !== void 0) {
43
- legacyConfig.session_idle_timeout_seconds = config.sessionIdleTimeoutSeconds;
44
- }
45
- if (config.beforeSend !== void 0) legacyConfig.before_send = config.beforeSend;
46
- return legacyConfig;
57
+ const payload = { metaData };
58
+ return cleanObject(payload);
47
59
  }
48
60
 
49
61
  // src/core/environment.ts
50
- function isBrowserRuntime() {
51
- return typeof window !== "undefined" && typeof document !== "undefined";
52
- }
53
62
  function getBrowserWindow() {
54
63
  return typeof window === "undefined" ? void 0 : window;
55
64
  }
@@ -109,8 +118,9 @@ function stableStringify(value) {
109
118
  );
110
119
  }
111
120
  function createIdempotencyKey(payload, messageId) {
112
- const event = String(payload.event ?? payload.type ?? "event");
113
- const properties = payload.properties;
121
+ const metaData = payload.metaData;
122
+ const event = String(metaData?.eventType ?? payload.event ?? payload.type ?? "event");
123
+ const properties = metaData ?? payload.properties;
114
124
  const orderId = properties?.orderId ?? properties?.order_id ?? properties?.transaction_id;
115
125
  if (orderId !== void 0) return `${event}:${String(orderId)}`;
116
126
  return `${event}:${stableStringify(properties ?? {}) || messageId}`;
@@ -211,7 +221,17 @@ function createDeliveryManager(config) {
211
221
  persistQueue();
212
222
  }
213
223
  function withEnvelope(payload) {
214
- const messageId = String(payload.messageId ?? createId("msg"));
224
+ const metaData = payload.metaData;
225
+ const messageId = String(metaData?.requestId ?? payload.messageId ?? createId("msg"));
226
+ if (metaData) {
227
+ return {
228
+ ...payload,
229
+ metaData: {
230
+ ...metaData,
231
+ requestId: messageId
232
+ }
233
+ };
234
+ }
215
235
  return {
216
236
  ...payload,
217
237
  messageId,
@@ -237,7 +257,7 @@ function createDeliveryManager(config) {
237
257
  const body = withEnvelope(payload);
238
258
  if (payloadByteLength(body) > maxPayloadBytes) {
239
259
  recordDrop({
240
- messageId: String(body.messageId),
260
+ messageId: String(body.metaData?.requestId ?? body.messageId),
241
261
  reason: "payload_too_large",
242
262
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
243
263
  });
@@ -250,7 +270,7 @@ function createDeliveryManager(config) {
250
270
  const deliveryError = error instanceof Error ? error : new Error(String(error));
251
271
  recordError(deliveryError);
252
272
  enqueue({
253
- messageId: String(body.messageId),
273
+ messageId: String(body.metaData?.requestId ?? body.messageId),
254
274
  savedAt: Date.now(),
255
275
  attempts: 1,
256
276
  lastError: deliveryError.message,
@@ -425,6 +445,12 @@ function endpointFromConfig(config) {
425
445
  const host = config.apiHost ?? "https://sdk.drivemetadata.com/v2";
426
446
  return `${host.replace(/\/$/, "")}/data-collector`;
427
447
  }
448
+ function requireConfigString(value, field) {
449
+ if (typeof value !== "string" || value.trim() === "") {
450
+ throw new Error(`DMD SDK config ${field} is required`);
451
+ }
452
+ return value;
453
+ }
428
454
  function getBrowserStorage() {
429
455
  const browserWindow = getBrowserWindow();
430
456
  try {
@@ -439,6 +465,10 @@ var DriveMetaDataSDK = class {
439
465
  this.queue = [];
440
466
  this.offline = false;
441
467
  this.droppedEvents = 0;
468
+ requireConfigString(config.clientId, "clientId");
469
+ requireConfigString(config.workspaceId, "workspaceId");
470
+ requireConfigString(config.appId, "appId");
471
+ requireConfigString(config.writeKey || config.token, "writeKey or token");
442
472
  this.config = config;
443
473
  this.endpoint = endpointFromConfig(config);
444
474
  const storage = getBrowserStorage();
@@ -462,6 +492,7 @@ var DriveMetaDataSDK = class {
462
492
  this.maxRetryDelayMs = config.delivery?.maxRetryDelayMs ?? 3e4;
463
493
  this.writeKey = config.writeKey || config.token || "";
464
494
  this.identity = { anonymousId: createId2("anon") };
495
+ this.sessionId = createId2("session");
465
496
  this.consentState = normalizeConsent(config.gdprConsent ?? config.consent);
466
497
  this.gdprConsent = this.consentState.analytics;
467
498
  if (!config.delivery?.disableLifecycleFlush) {
@@ -607,7 +638,8 @@ var DriveMetaDataSDK = class {
607
638
  workspaceId: this.config.workspaceId,
608
639
  appId: this.config.appId,
609
640
  writeKey: this.writeKey,
610
- consent: this.consentState
641
+ consent: this.consentState,
642
+ sessionId: this.sessionId
611
643
  };
612
644
  if (this.identity.userId !== void 0) prepared.userId = this.identity.userId;
613
645
  if (this.identity.groupId !== void 0) prepared.groupId = this.identity.groupId;
@@ -631,7 +663,31 @@ var DriveMetaDataSDK = class {
631
663
  if (!validation.ok) {
632
664
  this.lastError = `DMD SDK schema warning: ${validation.errors.join(", ")}`;
633
665
  }
634
- this.sendEvent(prepared);
666
+ this.sendEvent(this.toCollectorPayload(prepared));
667
+ }
668
+ toCollectorPayload(prepared) {
669
+ const browserWindow = getBrowserWindow();
670
+ return createBackendCollectorPayload({
671
+ requestId: prepared.messageId,
672
+ timestamp: prepared.timestamp,
673
+ eventType: prepared.event,
674
+ clientId: prepared.clientId,
675
+ workspaceId: prepared.workspaceId,
676
+ token: prepared.writeKey,
677
+ anonymousId: prepared.anonymousId,
678
+ sessionId: prepared.sessionId,
679
+ ua: browserWindow?.navigator?.userAgent,
680
+ appId: prepared.appId,
681
+ pageUrl: browserWindow?.location?.href,
682
+ eventData: {
683
+ ...prepared.properties,
684
+ anonymousId: prepared.anonymousId,
685
+ sessionId: prepared.sessionId,
686
+ timestamp: prepared.timestamp,
687
+ requestSentAt: prepared.timestamp,
688
+ requestReceivedAt: prepared.timestamp
689
+ }
690
+ });
635
691
  }
636
692
  recordDrop(type, reason, event) {
637
693
  this.droppedEvents += 1;
@@ -645,22 +701,6 @@ var DriveMetaDataSDK = class {
645
701
  }
646
702
  };
647
703
 
648
- // src/browser/legacy-loader.ts
649
- function getLegacySdkInstanceFromWindow() {
650
- const browserWindow = getBrowserWindow();
651
- return browserWindow?.__DriveMetaDataSDKInstance;
652
- }
653
- function ensureLegacySdkLoaded() {
654
- if (!isBrowserRuntime()) {
655
- throw new Error("DMD legacy SDK is only available in a browser runtime");
656
- }
657
- const browserWindow = getBrowserWindow();
658
- if (!browserWindow?.DriveMetaDataSDK) {
659
- throw new Error("DMD legacy SDK constructor is missing from window.DriveMetaDataSDK");
660
- }
661
- return browserWindow.DriveMetaDataSDK;
662
- }
663
-
664
704
  // src/browser/client.ts
665
705
  var singleton;
666
706
  var publicSingleton;
@@ -669,56 +709,34 @@ var lastError;
669
709
  var lastDroppedEvent;
670
710
  function createPublicClient(instance) {
671
711
  return {
672
- __legacy: instance,
673
712
  track(event, properties, options) {
674
- if (instance.trackEvent) {
675
- instance.trackEvent(event, properties, options);
676
- return;
677
- }
678
- instance.sendEvent?.({ eventName: event, event, properties, options });
713
+ instance.trackEvent(event, properties, options);
679
714
  },
680
715
  identify(userId, traits, options) {
681
- if (instance.identify) {
682
- instance.identify(userId, traits, options);
683
- return;
684
- }
685
- instance.identifyUser?.(userId, traits);
716
+ instance.identify(userId, traits, options);
686
717
  },
687
718
  page(name, properties, options) {
688
- if (instance.page) {
689
- instance.page(name, properties, options);
690
- return;
691
- }
692
- instance.trackPageview?.();
719
+ instance.page(name, properties, options);
693
720
  },
694
721
  group(groupId, traits, options) {
695
- instance.group?.(groupId, traits, options);
722
+ instance.group(groupId, traits, options);
696
723
  },
697
724
  alias(previousId, userId, options) {
698
- instance.alias?.(previousId, userId, options);
725
+ instance.alias(previousId, userId, options);
699
726
  },
700
727
  async flush() {
701
- await instance.flush?.();
728
+ await instance.flush();
702
729
  },
703
730
  reset() {
704
- instance.reset?.();
731
+ instance.reset();
705
732
  singleton = void 0;
706
733
  publicSingleton = void 0;
707
734
  },
708
735
  setConsent(consent) {
709
- if (instance.setConsent) {
710
- instance.setConsent(consent);
711
- return;
712
- }
713
- if (typeof consent === "string") {
714
- instance.gdprConsent = consent;
715
- }
736
+ instance.setConsent(consent);
716
737
  },
717
738
  getHealth() {
718
- if (instance.getHealth) {
719
- return instance.getHealth();
720
- }
721
- return getDmdHealth();
739
+ return instance.getHealth();
722
740
  }
723
741
  };
724
742
  }
@@ -743,23 +761,8 @@ function initDmdSDK(config) {
743
761
  if (publicSingleton) {
744
762
  return publicSingleton;
745
763
  }
746
- const legacyConfig = normalizeBrowserConfig(config);
747
- const existingInstance = getLegacySdkInstanceFromWindow();
748
- if (existingInstance) {
749
- return setSingleton(existingInstance);
750
- }
751
764
  try {
752
- let instance;
753
- try {
754
- const LegacySdk = ensureLegacySdkLoaded();
755
- instance = new LegacySdk(legacyConfig);
756
- } catch (error) {
757
- if (error instanceof Error && error.message.includes("constructor is missing")) {
758
- instance = new DriveMetaDataSDK(config);
759
- } else {
760
- throw error;
761
- }
762
- }
765
+ const instance = new DriveMetaDataSDK(config);
763
766
  return setSingleton(instance);
764
767
  } catch (error) {
765
768
  lastError = error instanceof Error ? error.message : String(error);
@@ -797,14 +800,14 @@ function setConsent(consent) {
797
800
  getDmdSDK()?.setConsent(consent);
798
801
  }
799
802
  function getDmdHealth() {
800
- if (singleton?.getHealth) {
803
+ if (singleton) {
801
804
  return singleton.getHealth();
802
805
  }
803
806
  const health = {
804
- initialized: Boolean(singleton?.initialized ?? singleton),
805
- consent: singleton?.gdprConsent ?? "pending",
806
- queueSize: singleton?.queue?.length ?? 0,
807
- offline: Boolean(singleton?.offline),
807
+ initialized: false,
808
+ consent: "pending",
809
+ queueSize: 0,
810
+ offline: false,
808
811
  droppedEvents
809
812
  };
810
813
  if (lastError !== void 0) {
@@ -847,6 +850,7 @@ function DmdProvider({
847
850
  config.workspaceId,
848
851
  config.appId,
849
852
  config.writeKey,
853
+ config.token,
850
854
  config.apiHost,
851
855
  config.consent,
852
856
  config.gdprConsent,