@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
@@ -13,53 +13,62 @@ var __decorateParam = (index, decorator) => (target, key) => decorator(target, k
13
13
  // src/angular/dmd-analytics.service.ts
14
14
  import { Inject, Injectable, Optional } from "@angular/core";
15
15
 
16
- // src/core/config.ts
17
- function requireString(value, field) {
18
- if (typeof value !== "string" || value.trim() === "") {
19
- throw new Error(`DMD SDK config ${field} is required`);
16
+ // src/core/backend-payload.ts
17
+ function formatUtcTimestamp(value) {
18
+ if (typeof value !== "string") return (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
19
+ const date = new Date(value);
20
+ if (Number.isNaN(date.getTime())) return value;
21
+ return date.toISOString().replace("T", " ").slice(0, 19);
22
+ }
23
+ function cleanObject(value) {
24
+ if (Array.isArray(value)) {
25
+ const cleaned = value.map((item) => cleanObject(item)).filter((item) => item !== null && item !== void 0 && item !== "");
26
+ return cleaned.length > 0 ? cleaned : void 0;
27
+ }
28
+ if (value && typeof value === "object") {
29
+ const cleaned = Object.fromEntries(
30
+ Object.entries(value).map(([key, item]) => [key, cleanObject(item)]).filter(([, item]) => {
31
+ if (item === null || item === void 0 || item === "") return false;
32
+ if (typeof item === "object" && !Array.isArray(item) && Object.keys(item).length === 0) return false;
33
+ return true;
34
+ })
35
+ );
36
+ return Object.keys(cleaned).length > 0 ? cleaned : void 0;
20
37
  }
21
38
  return value;
22
39
  }
23
- function normalizeBrowserConfig(config) {
24
- const writeKey = config.writeKey || config.token;
25
- const legacyConfig = {
26
- client_id: requireString(config.clientId, "clientId"),
27
- workspace_id: requireString(config.workspaceId, "workspaceId"),
28
- app_id: requireString(config.appId, "appId"),
29
- token: requireString(writeKey, "writeKey")
40
+ function createBackendCollectorPayload(input) {
41
+ const eventData = input.eventData && typeof input.eventData === "object" ? input.eventData : {};
42
+ const page2 = eventData.page && typeof eventData.page === "object" ? eventData.page : {};
43
+ const timestamp = formatUtcTimestamp(eventData.timestamp ?? input.timestamp);
44
+ const normalizedEventData = {
45
+ ...eventData,
46
+ timestamp,
47
+ requestSentAt: formatUtcTimestamp(eventData.requestSentAt ?? input.requestSentAt ?? timestamp),
48
+ requestReceivedAt: formatUtcTimestamp(eventData.requestReceivedAt ?? input.requestReceivedAt ?? timestamp)
49
+ };
50
+ const metaData = {
51
+ ...normalizedEventData,
52
+ requestId: input.requestId,
53
+ timestamp,
54
+ eventType: input.eventType,
55
+ requestFrom: input.requestFrom ?? "3",
56
+ clientId: input.clientId,
57
+ workspaceId: input.workspaceId,
58
+ token: input.token,
59
+ anonymousId: eventData.anonymousId ?? input.anonymousId,
60
+ sessionId: eventData.sessionId ?? input.sessionId,
61
+ ua: input.ua,
62
+ appDetails: { app_id: input.appId },
63
+ page: { ...page2, url: page2.url ?? input.pageUrl },
64
+ requestSentAt: normalizedEventData.requestSentAt,
65
+ requestReceivedAt: normalizedEventData.requestReceivedAt
30
66
  };
31
- if (config.apiHost !== void 0) legacyConfig.api_host = config.apiHost;
32
- if (config.uiHost !== void 0) legacyConfig.ui_host = config.uiHost;
33
- if (config.deeplink !== void 0) legacyConfig.deeplink = config.deeplink;
34
- if (config.debug !== void 0) legacyConfig.debug = config.debug;
35
- if (config.consent !== void 0) legacyConfig.consent = config.consent;
36
- if (config.gdprConsent !== void 0) legacyConfig.gdprConsent = config.gdprConsent;
37
- if (config.autocapture !== void 0) legacyConfig.autocapture = config.autocapture;
38
- if (config.capturePageview !== void 0) legacyConfig.capture_pageview = config.capturePageview;
39
- if (config.capturePageleave !== void 0) legacyConfig.capture_pageleave = config.capturePageleave;
40
- if (config.captureDeadClicks !== void 0) legacyConfig.capture_dead_clicks = config.captureDeadClicks;
41
- if (config.crossSubdomainCookie !== void 0) legacyConfig.cross_subdomain_cookie = config.crossSubdomainCookie;
42
- if (config.disablePersistence !== void 0) legacyConfig.disable_persistence = config.disablePersistence;
43
- if (config.disableSurveys !== void 0) legacyConfig.disable_surveys = config.disableSurveys;
44
- if (config.disableSessionRecording !== void 0) legacyConfig.disable_session_recording = config.disableSessionRecording;
45
- if (config.enableHeatmaps !== void 0) legacyConfig.enable_heatmaps = config.enableHeatmaps;
46
- if (config.maskAllText !== void 0) legacyConfig.mask_all_text = config.maskAllText;
47
- if (config.maskAllElementAttributes !== void 0) {
48
- legacyConfig.mask_all_element_attributes = config.maskAllElementAttributes;
49
- }
50
- if (config.persistence !== void 0) legacyConfig.persistence = config.persistence;
51
- if (config.propertyDenylist !== void 0) legacyConfig.property_denylist = config.propertyDenylist;
52
- if (config.sessionIdleTimeoutSeconds !== void 0) {
53
- legacyConfig.session_idle_timeout_seconds = config.sessionIdleTimeoutSeconds;
54
- }
55
- if (config.beforeSend !== void 0) legacyConfig.before_send = config.beforeSend;
56
- return legacyConfig;
67
+ const payload = { metaData };
68
+ return cleanObject(payload);
57
69
  }
58
70
 
59
71
  // src/core/environment.ts
60
- function isBrowserRuntime() {
61
- return typeof window !== "undefined" && typeof document !== "undefined";
62
- }
63
72
  function getBrowserWindow() {
64
73
  return typeof window === "undefined" ? void 0 : window;
65
74
  }
@@ -119,8 +128,9 @@ function stableStringify(value) {
119
128
  );
120
129
  }
121
130
  function createIdempotencyKey(payload, messageId) {
122
- const event = String(payload.event ?? payload.type ?? "event");
123
- const properties = payload.properties;
131
+ const metaData = payload.metaData;
132
+ const event = String(metaData?.eventType ?? payload.event ?? payload.type ?? "event");
133
+ const properties = metaData ?? payload.properties;
124
134
  const orderId = properties?.orderId ?? properties?.order_id ?? properties?.transaction_id;
125
135
  if (orderId !== void 0) return `${event}:${String(orderId)}`;
126
136
  return `${event}:${stableStringify(properties ?? {}) || messageId}`;
@@ -221,7 +231,17 @@ function createDeliveryManager(config) {
221
231
  persistQueue();
222
232
  }
223
233
  function withEnvelope(payload) {
224
- const messageId = String(payload.messageId ?? createId("msg"));
234
+ const metaData = payload.metaData;
235
+ const messageId = String(metaData?.requestId ?? payload.messageId ?? createId("msg"));
236
+ if (metaData) {
237
+ return {
238
+ ...payload,
239
+ metaData: {
240
+ ...metaData,
241
+ requestId: messageId
242
+ }
243
+ };
244
+ }
225
245
  return {
226
246
  ...payload,
227
247
  messageId,
@@ -247,7 +267,7 @@ function createDeliveryManager(config) {
247
267
  const body = withEnvelope(payload);
248
268
  if (payloadByteLength(body) > maxPayloadBytes) {
249
269
  recordDrop({
250
- messageId: String(body.messageId),
270
+ messageId: String(body.metaData?.requestId ?? body.messageId),
251
271
  reason: "payload_too_large",
252
272
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
253
273
  });
@@ -260,7 +280,7 @@ function createDeliveryManager(config) {
260
280
  const deliveryError = error instanceof Error ? error : new Error(String(error));
261
281
  recordError(deliveryError);
262
282
  enqueue({
263
- messageId: String(body.messageId),
283
+ messageId: String(body.metaData?.requestId ?? body.messageId),
264
284
  savedAt: Date.now(),
265
285
  attempts: 1,
266
286
  lastError: deliveryError.message,
@@ -435,6 +455,12 @@ function endpointFromConfig(config) {
435
455
  const host = config.apiHost ?? "https://sdk.drivemetadata.com/v2";
436
456
  return `${host.replace(/\/$/, "")}/data-collector`;
437
457
  }
458
+ function requireConfigString(value, field) {
459
+ if (typeof value !== "string" || value.trim() === "") {
460
+ throw new Error(`DMD SDK config ${field} is required`);
461
+ }
462
+ return value;
463
+ }
438
464
  function getBrowserStorage() {
439
465
  const browserWindow = getBrowserWindow();
440
466
  try {
@@ -449,6 +475,10 @@ var DriveMetaDataSDK = class {
449
475
  this.queue = [];
450
476
  this.offline = false;
451
477
  this.droppedEvents = 0;
478
+ requireConfigString(config.clientId, "clientId");
479
+ requireConfigString(config.workspaceId, "workspaceId");
480
+ requireConfigString(config.appId, "appId");
481
+ requireConfigString(config.writeKey || config.token, "writeKey or token");
452
482
  this.config = config;
453
483
  this.endpoint = endpointFromConfig(config);
454
484
  const storage = getBrowserStorage();
@@ -472,6 +502,7 @@ var DriveMetaDataSDK = class {
472
502
  this.maxRetryDelayMs = config.delivery?.maxRetryDelayMs ?? 3e4;
473
503
  this.writeKey = config.writeKey || config.token || "";
474
504
  this.identity = { anonymousId: createId2("anon") };
505
+ this.sessionId = createId2("session");
475
506
  this.consentState = normalizeConsent(config.gdprConsent ?? config.consent);
476
507
  this.gdprConsent = this.consentState.analytics;
477
508
  if (!config.delivery?.disableLifecycleFlush) {
@@ -617,7 +648,8 @@ var DriveMetaDataSDK = class {
617
648
  workspaceId: this.config.workspaceId,
618
649
  appId: this.config.appId,
619
650
  writeKey: this.writeKey,
620
- consent: this.consentState
651
+ consent: this.consentState,
652
+ sessionId: this.sessionId
621
653
  };
622
654
  if (this.identity.userId !== void 0) prepared.userId = this.identity.userId;
623
655
  if (this.identity.groupId !== void 0) prepared.groupId = this.identity.groupId;
@@ -641,7 +673,31 @@ var DriveMetaDataSDK = class {
641
673
  if (!validation.ok) {
642
674
  this.lastError = `DMD SDK schema warning: ${validation.errors.join(", ")}`;
643
675
  }
644
- this.sendEvent(prepared);
676
+ this.sendEvent(this.toCollectorPayload(prepared));
677
+ }
678
+ toCollectorPayload(prepared) {
679
+ const browserWindow = getBrowserWindow();
680
+ return createBackendCollectorPayload({
681
+ requestId: prepared.messageId,
682
+ timestamp: prepared.timestamp,
683
+ eventType: prepared.event,
684
+ clientId: prepared.clientId,
685
+ workspaceId: prepared.workspaceId,
686
+ token: prepared.writeKey,
687
+ anonymousId: prepared.anonymousId,
688
+ sessionId: prepared.sessionId,
689
+ ua: browserWindow?.navigator?.userAgent,
690
+ appId: prepared.appId,
691
+ pageUrl: browserWindow?.location?.href,
692
+ eventData: {
693
+ ...prepared.properties,
694
+ anonymousId: prepared.anonymousId,
695
+ sessionId: prepared.sessionId,
696
+ timestamp: prepared.timestamp,
697
+ requestSentAt: prepared.timestamp,
698
+ requestReceivedAt: prepared.timestamp
699
+ }
700
+ });
645
701
  }
646
702
  recordDrop(type, reason, event) {
647
703
  this.droppedEvents += 1;
@@ -655,22 +711,6 @@ var DriveMetaDataSDK = class {
655
711
  }
656
712
  };
657
713
 
658
- // src/browser/legacy-loader.ts
659
- function getLegacySdkInstanceFromWindow() {
660
- const browserWindow = getBrowserWindow();
661
- return browserWindow?.__DriveMetaDataSDKInstance;
662
- }
663
- function ensureLegacySdkLoaded() {
664
- if (!isBrowserRuntime()) {
665
- throw new Error("DMD legacy SDK is only available in a browser runtime");
666
- }
667
- const browserWindow = getBrowserWindow();
668
- if (!browserWindow?.DriveMetaDataSDK) {
669
- throw new Error("DMD legacy SDK constructor is missing from window.DriveMetaDataSDK");
670
- }
671
- return browserWindow.DriveMetaDataSDK;
672
- }
673
-
674
714
  // src/browser/client.ts
675
715
  var singleton;
676
716
  var publicSingleton;
@@ -679,56 +719,34 @@ var lastError;
679
719
  var lastDroppedEvent;
680
720
  function createPublicClient(instance) {
681
721
  return {
682
- __legacy: instance,
683
722
  track(event, properties, options) {
684
- if (instance.trackEvent) {
685
- instance.trackEvent(event, properties, options);
686
- return;
687
- }
688
- instance.sendEvent?.({ eventName: event, event, properties, options });
723
+ instance.trackEvent(event, properties, options);
689
724
  },
690
725
  identify(userId, traits, options) {
691
- if (instance.identify) {
692
- instance.identify(userId, traits, options);
693
- return;
694
- }
695
- instance.identifyUser?.(userId, traits);
726
+ instance.identify(userId, traits, options);
696
727
  },
697
728
  page(name, properties, options) {
698
- if (instance.page) {
699
- instance.page(name, properties, options);
700
- return;
701
- }
702
- instance.trackPageview?.();
729
+ instance.page(name, properties, options);
703
730
  },
704
731
  group(groupId, traits, options) {
705
- instance.group?.(groupId, traits, options);
732
+ instance.group(groupId, traits, options);
706
733
  },
707
734
  alias(previousId, userId, options) {
708
- instance.alias?.(previousId, userId, options);
735
+ instance.alias(previousId, userId, options);
709
736
  },
710
737
  async flush() {
711
- await instance.flush?.();
738
+ await instance.flush();
712
739
  },
713
740
  reset() {
714
- instance.reset?.();
741
+ instance.reset();
715
742
  singleton = void 0;
716
743
  publicSingleton = void 0;
717
744
  },
718
745
  setConsent(consent) {
719
- if (instance.setConsent) {
720
- instance.setConsent(consent);
721
- return;
722
- }
723
- if (typeof consent === "string") {
724
- instance.gdprConsent = consent;
725
- }
746
+ instance.setConsent(consent);
726
747
  },
727
748
  getHealth() {
728
- if (instance.getHealth) {
729
- return instance.getHealth();
730
- }
731
- return getDmdHealth();
749
+ return instance.getHealth();
732
750
  }
733
751
  };
734
752
  }
@@ -753,23 +771,8 @@ function initDmdSDK(config) {
753
771
  if (publicSingleton) {
754
772
  return publicSingleton;
755
773
  }
756
- const legacyConfig = normalizeBrowserConfig(config);
757
- const existingInstance = getLegacySdkInstanceFromWindow();
758
- if (existingInstance) {
759
- return setSingleton(existingInstance);
760
- }
761
774
  try {
762
- let instance;
763
- try {
764
- const LegacySdk = ensureLegacySdkLoaded();
765
- instance = new LegacySdk(legacyConfig);
766
- } catch (error) {
767
- if (error instanceof Error && error.message.includes("constructor is missing")) {
768
- instance = new DriveMetaDataSDK(config);
769
- } else {
770
- throw error;
771
- }
772
- }
775
+ const instance = new DriveMetaDataSDK(config);
773
776
  return setSingleton(instance);
774
777
  } catch (error) {
775
778
  lastError = error instanceof Error ? error.message : String(error);
@@ -836,14 +839,14 @@ function setConsent(consent) {
836
839
  getDmdSDK()?.setConsent(consent);
837
840
  }
838
841
  function getDmdHealth() {
839
- if (singleton?.getHealth) {
842
+ if (singleton) {
840
843
  return singleton.getHealth();
841
844
  }
842
845
  const health = {
843
- initialized: Boolean(singleton?.initialized ?? singleton),
844
- consent: singleton?.gdprConsent ?? "pending",
845
- queueSize: singleton?.queue?.length ?? 0,
846
- offline: Boolean(singleton?.offline),
846
+ initialized: false,
847
+ consent: "pending",
848
+ queueSize: 0,
849
+ offline: false,
847
850
  droppedEvents
848
851
  };
849
852
  if (lastError !== void 0) {