saasco-sdk 0.1.7 → 0.1.9

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/index.esm.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { __awaiter } from 'tslib';
1
2
  import { v4 } from '@lukeed/uuid';
2
3
  import { z } from 'zod';
3
4
 
@@ -429,7 +430,6 @@ const timezones = {
429
430
  'Asia/Calcutta': 'IN'
430
431
  };
431
432
 
432
- /* eslint-disable @typescript-eslint/no-explicit-any */
433
433
  const isBrowser = typeof window !== 'undefined';
434
434
  let userId = null;
435
435
  const PREF = 'saasco-sdk';
@@ -497,6 +497,36 @@ function setAnonmousId({
497
497
  storeData(`anonymous-id`, anonymousId, 1000 * 60 * 60 * 24 * 365);
498
498
  return anonymousId;
499
499
  }
500
+ function getBrowserContext() {
501
+ var _a;
502
+ if (!isBrowser) return {};
503
+ const customNavigator = navigator;
504
+ const $locale = (customNavigator === null || customNavigator === void 0 ? void 0 : customNavigator.languages) && (customNavigator === null || customNavigator === void 0 ? void 0 : customNavigator.languages.length) ? customNavigator === null || customNavigator === void 0 ? void 0 : customNavigator.languages[0] : (customNavigator === null || customNavigator === void 0 ? void 0 : customNavigator.userLanguage) || (customNavigator === null || customNavigator === void 0 ? void 0 : customNavigator.language) || (customNavigator === null || customNavigator === void 0 ? void 0 : customNavigator.browserLanguage) || 'en';
505
+ // https://caniuse.com/?search=Intl.DateTimeFormat().resolvedOptions().timeZone
506
+ // Only has 96.63% global support, so we need to check for undefined
507
+ const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
508
+ const $location = timezones[timezone] || ((_a = $locale === null || $locale === void 0 ? void 0 : $locale.split('-')) === null || _a === void 0 ? void 0 : _a[1]) || 'undefined';
509
+ const $href = window.location.href;
510
+ const $pathname = window.location.pathname;
511
+ const $referrer = document.referrer;
512
+ const $screenDPI = window.devicePixelRatio;
513
+ const $screenHeight = screen.height;
514
+ const $screenWidth = screen.width;
515
+ const $title = document.title;
516
+ const $userAgent = window.navigator.userAgent;
517
+ return {
518
+ $locale,
519
+ $location,
520
+ $href,
521
+ $pathname,
522
+ $referrer,
523
+ $screenDPI,
524
+ $screenHeight,
525
+ $screenWidth,
526
+ $title,
527
+ $userAgent
528
+ };
529
+ }
500
530
  class Saasco {
501
531
  /**
502
532
  * Creates an instance of Saasco SDK.
@@ -538,8 +568,7 @@ class Saasco {
538
568
  */
539
569
  track(name,
540
570
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
541
- properties) {
542
- var _a;
571
+ properties, context) {
543
572
  // Prevent duplicate Page View tracking
544
573
  if (name === 'Page View') {
545
574
  if (!isBrowser) {
@@ -552,20 +581,7 @@ class Saasco {
552
581
  }
553
582
  setSessionId();
554
583
  setAnonmousId();
555
- const customNavigator = isBrowser ? navigator : undefined;
556
- const $locale = isBrowser ? (customNavigator === null || customNavigator === void 0 ? void 0 : customNavigator.languages) && (customNavigator === null || customNavigator === void 0 ? void 0 : customNavigator.languages.length) ? customNavigator === null || customNavigator === void 0 ? void 0 : customNavigator.languages[0] : (customNavigator === null || customNavigator === void 0 ? void 0 : customNavigator.userLanguage) || (customNavigator === null || customNavigator === void 0 ? void 0 : customNavigator.language) || (customNavigator === null || customNavigator === void 0 ? void 0 : customNavigator.browserLanguage) || 'en' : undefined;
557
- // https://caniuse.com/?search=Intl.DateTimeFormat().resolvedOptions().timeZone
558
- // Only has 96.63% global support, so we need to check for undefined
559
- const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
560
- const $location = isBrowser ? timezones[timezone] || ((_a = $locale === null || $locale === void 0 ? void 0 : $locale.split('-')) === null || _a === void 0 ? void 0 : _a[1]) || 'undefined' : undefined;
561
- const $href = isBrowser ? window.location.href : undefined;
562
- const $pathname = isBrowser ? window.location.pathname : undefined;
563
- const $referrer = isBrowser ? document.referrer : undefined;
564
- const $screenDPI = isBrowser ? window.devicePixelRatio : undefined;
565
- const $screenHeight = isBrowser ? screen.height : undefined;
566
- const $screenWidth = isBrowser ? screen.width : undefined;
567
- const $title = isBrowser ? document.title : undefined;
568
- const $userAgent = isBrowser ? window.navigator.userAgent : undefined;
584
+ const browserContext = getBrowserContext();
569
585
  const data = {
570
586
  id: v4(),
571
587
  timestamp: new Date().toISOString(),
@@ -573,22 +589,14 @@ class Saasco {
573
589
  version: '2',
574
590
  sessionId: getSessionId(),
575
591
  anonymousId: getAnonymousId(),
592
+ distinctId: userId,
576
593
  projectId: this.config.projectId,
577
- payload: JSON.stringify({
578
- $href,
579
- $locale,
580
- $location,
581
- $pathname,
582
- $referrer,
583
- $screenDPI,
584
- $screenHeight,
585
- $screenWidth,
586
- $title,
587
- $userAgent,
594
+ payload: JSON.stringify(Object.assign(Object.assign({}, browserContext), {
588
595
  properties: properties || {}
589
- })
596
+ })),
597
+ context: JSON.stringify(context || {})
590
598
  };
591
- this.doRequest('events', data);
599
+ return this.doRequest('events', data);
592
600
  }
593
601
  /**
594
602
  * The page method lets you record page views on your website
@@ -597,13 +605,13 @@ class Saasco {
597
605
  * Before implementing this make sure you have disabled the autoPageTracking in the config or you will get duplicate page views
598
606
  */
599
607
  page() {
600
- this.track('Page View');
608
+ return this.track('Page View');
601
609
  }
602
- identify(distinctIdOrProperties, propertiesOrOptions, optionsOrNothing) {
610
+ identify(distinctIdOrProperties, propertiesOrContext, contextOrNothing) {
603
611
  const hasId = typeof distinctIdOrProperties === 'string' || typeof distinctIdOrProperties === 'number' || distinctIdOrProperties === null;
604
612
  const distinctId = hasId ? distinctIdOrProperties === null || distinctIdOrProperties === void 0 ? void 0 : distinctIdOrProperties.toString() : `soft_${v4()}`;
605
- const properties = hasId ? propertiesOrOptions : distinctIdOrProperties;
606
- const options = hasId ? optionsOrNothing : propertiesOrOptions;
613
+ const properties = hasId ? propertiesOrContext : distinctIdOrProperties;
614
+ const context = hasId ? contextOrNothing : propertiesOrContext;
607
615
  // When the user gets identified as null this will reset the users session and anonymous id
608
616
  // This should only be called when distinctId is null and there is an existing userId.
609
617
  // This means the user has logged out and we should reset the session and anonymous IDs
@@ -631,9 +639,9 @@ class Saasco {
631
639
  anonymousId,
632
640
  version: '2',
633
641
  payload: properties || {},
634
- options: options || {}
642
+ context: context || {}
635
643
  };
636
- this.doRequest('identify', data);
644
+ return this.doRequest('identify', data);
637
645
  }
638
646
  /**
639
647
  * Handles sending data to the Saasco API
@@ -642,25 +650,31 @@ class Saasco {
642
650
  * @param data
643
651
  */
644
652
  doRequest(path, data) {
645
- const base = this.config.proxy || 'https://www.saasco.com/api/';
646
- const url = `${base}${path}`;
647
- const logMessage = data.action === 'Page View' ? `Page View ${window.location.pathname}` // if its a page view, include pathname in console log
648
- : data.action || path;
649
- this.log(logMessage, data);
650
- // If analytics is disabled, don't send the request
651
- if (this.config.enabled === false) return;
652
- fetch(url, {
653
- method: 'POST',
654
- headers: {
655
- 'Content-Type': 'application/json'
656
- },
657
- body: JSON.stringify(data)
658
- }).then(response => {
659
- if (!response.ok) {
660
- throw new Error(response.status.toString());
653
+ return __awaiter(this, void 0, void 0, function* () {
654
+ const base = this.config.proxy || 'https://www.saasco.com/api/';
655
+ const url = `${base}${path}`;
656
+ const logMessage = data.action === 'Page View' ? `Page View ${window.location.pathname}` // if its a page view, include pathname in console log
657
+ : data.action || path;
658
+ this.log(logMessage, data);
659
+ // If analytics is disabled, don't send the request
660
+ if (this.config.enabled === false) return;
661
+ try {
662
+ const response = yield fetch(url, {
663
+ method: 'POST',
664
+ headers: {
665
+ 'Content-Type': 'application/json'
666
+ },
667
+ body: JSON.stringify(data)
668
+ });
669
+ if (!response.ok) {
670
+ throw new Error(response.status.toString());
671
+ }
672
+ return response;
673
+ } catch (error) {
674
+ const errorMessage = 'Error with Saasco request: ' + error.message;
675
+ console.error(errorMessage, path, data);
676
+ return errorMessage;
661
677
  }
662
- }).catch(e => {
663
- console.error('Error with Saasco request: ' + e.message, path, data);
664
678
  });
665
679
  }
666
680
  /**
@@ -669,14 +683,10 @@ class Saasco {
669
683
  log(...args) {
670
684
  if (!this.config.debug) return;
671
685
  const message = '◍ Saasco Debug';
672
- console.log(...[`\x1b[47m\x1b[30m ${message} \x1b[0m`,
686
+ console.info(...[`\x1b[47m\x1b[30m ${message} \x1b[0m`,
673
687
  // Message highlighted for easy finding
674
688
  ...args]);
675
689
  }
676
- getSearchParam(param) {
677
- if (typeof window === 'undefined') return undefined;
678
- return new URLSearchParams(window.location.search).get(param);
679
- }
680
690
  /**
681
691
  * If autoPageTracking is enabled, this will automatically track page views
682
692
  * It listens to url changes to track new pages every time the url changes
@@ -822,49 +832,88 @@ const tinyBirdBaseSchema = z.object({
822
832
  }),
823
833
  rows: z.number()
824
834
  });
835
+ const TinybirdJobResponseSchema = z.object({
836
+ id: z.string(),
837
+ job_id: z.string(),
838
+ job_url: z.string().url(),
839
+ job: z.object({
840
+ kind: z.string(),
841
+ id: z.string(),
842
+ job_id: z.string(),
843
+ status: z.string(),
844
+ created_at: z.string(),
845
+ updated_at: z.string(),
846
+ started_at: z.string().nullable(),
847
+ is_cancellable: z.boolean(),
848
+ datasource: z.object({
849
+ id: z.string(),
850
+ name: z.string()
851
+ }),
852
+ delete_condition: z.string().optional()
853
+ }),
854
+ status: z.string(),
855
+ delete_id: z.string().optional(),
856
+ import_id: z.string().optional()
857
+ });
858
+ const latestEventsRequestSchema = z.object({
859
+ projectId: z.string(),
860
+ limit: z.number().optional(),
861
+ payload: z.boolean().optional()
862
+ });
863
+ const latestEventItemSchema = z.object({
864
+ id: z.string(),
865
+ timestamp: z.string(),
866
+ action: z.string(),
867
+ location: z.string(),
868
+ referrer: z.string(),
869
+ href: z.string(),
870
+ device: z.string(),
871
+ browser: z.string(),
872
+ payload: z.string().optional()
873
+ });
874
+ const latestEventsResponseSchema = tinyBirdBaseSchema.extend({
875
+ data: z.array(latestEventItemSchema)
876
+ });
825
877
  const kpisRequestSchema = z.object({
826
878
  projectId: z.string(),
827
879
  dateTo: z.string().optional(),
828
880
  dateFrom: z.string().optional(),
829
- referringDomain: z.string().optional(),
881
+ referrer: z.string().optional(),
830
882
  location: z.string().optional()
831
883
  });
832
884
  const kpisResponseSchema = tinyBirdBaseSchema.extend({
833
885
  data: z.array(z.object({
834
886
  date: z.string(),
835
- visits: z.number(),
836
- pageviews: z.number(),
887
+ users: z.number(),
888
+ sessions: z.number(),
889
+ pageViews: z.number(),
890
+ events: z.number(),
837
891
  bounceRate: z.nullable(z.number()),
838
892
  avgSessionSec: z.number()
839
893
  }))
840
894
  });
841
- const eventsKpisResponseSchema = tinyBirdBaseSchema.extend({
842
- data: z.array(z.object({
843
- unique: z.number(),
844
- total: z.number()
845
- }))
846
- });
847
895
  const baseTopRequestSchema = z.object({
848
896
  projectId: z.string(),
849
897
  dateTo: z.string().optional(),
850
898
  dateFrom: z.string().optional(),
851
899
  limit: z.number().optional(),
852
900
  skip: z.number().optional(),
853
- referringDomain: z.string().optional(),
901
+ referrer: z.string().optional(),
854
902
  location: z.string().optional()
855
903
  });
856
904
  const topPagesResponseSchema = tinyBirdBaseSchema.extend({
857
905
  data: z.array(z.object({
858
906
  pathname: z.string(),
859
- visits: z.number(),
860
- hits: z.number()
907
+ users: z.number(),
908
+ events: z.number()
861
909
  }))
862
910
  });
863
911
  const topLocationsResponseSchema = tinyBirdBaseSchema.extend({
864
912
  data: z.array(z.object({
865
913
  location: z.string(),
866
- visits: z.number(),
867
- hits: z.number(),
914
+ users: z.number(),
915
+ sessions: z.number(),
916
+ pageViews: z.number(),
868
917
  bounceRate: z.nullable(z.number()),
869
918
  avgSessionSec: z.number()
870
919
  }))
@@ -889,8 +938,9 @@ const topBrowsersResponseSchema = tinyBirdBaseSchema.extend({
889
938
  });
890
939
  const topSourcesSchema = z.object({
891
940
  referrer: z.string(),
892
- visits: z.number(),
893
- hits: z.number(),
941
+ users: z.number(),
942
+ sessions: z.number(),
943
+ pageViews: z.number(),
894
944
  bounceRate: z.nullable(z.number()),
895
945
  avgSessionSec: z.number()
896
946
  });
@@ -900,8 +950,8 @@ const topSourcesResponseSchema = tinyBirdBaseSchema.extend({
900
950
  const topActionsResponseSchema = tinyBirdBaseSchema.extend({
901
951
  data: z.array(z.object({
902
952
  action: z.string(),
903
- unique: z.number(),
904
- total: z.number()
953
+ users: z.number(),
954
+ events: z.number()
905
955
  }))
906
956
  });
907
957
  const analyticsEventSchema = z.object({
@@ -910,6 +960,7 @@ const analyticsEventSchema = z.object({
910
960
  projectId: z.string(),
911
961
  anonymousId: z.string(),
912
962
  sessionId: z.string(),
963
+ distinctId: z.string().optional(),
913
964
  version: z.string(),
914
965
  action: z.string(),
915
966
  payload: z.string()
@@ -920,7 +971,7 @@ const userEventsResponseSchema = tinyBirdBaseSchema.extend({
920
971
  const currentUsersRequestSchema = z.object({
921
972
  projectId: z.string(),
922
973
  minutes: z.number().optional(),
923
- referringDomain: z.string().optional(),
974
+ referrer: z.string().optional(),
924
975
  location: z.string().optional()
925
976
  });
926
977
  const currentUsersResponseSchema = tinyBirdBaseSchema.extend({
@@ -929,7 +980,7 @@ const currentUsersResponseSchema = tinyBirdBaseSchema.extend({
929
980
  }))
930
981
  });
931
982
  const reservedPropertiesSchema = z.object({
932
- age: z.number().nullish(),
983
+ age: z.number().or(z.string()).nullish(),
933
984
  avatar: z.string().url().nullish(),
934
985
  birthday: z.string().nullish(),
935
986
  createdAt: z.string().nullish(),
@@ -943,9 +994,11 @@ const reservedPropertiesSchema = z.object({
943
994
  phone: z.string().nullish(),
944
995
  title: z.string().nullish(),
945
996
  username: z.string().nullish(),
946
- website: z.string().nullish()
997
+ website: z.string().nullish(),
998
+ $id: z.string().nullish(),
999
+ $lastSeen: z.string().nullish()
947
1000
  });
948
- const userPropertiesSchema = reservedPropertiesSchema.and(z.record(z.union([z.string(), z.number(), z.boolean(), z.date(), z.null(), z.array(z.union([z.string(), z.number(), z.boolean(), z.date(), z.null()]))])));
1001
+ const contactPropertiesSchema = reservedPropertiesSchema.optional().and(z.record(z.union([z.string(), z.number(), z.boolean(), z.date(), z.null(), z.array(z.union([z.string(), z.number(), z.boolean(), z.date(), z.null()]))])));
949
1002
  const analyticsUserRawSchema = z.object({
950
1003
  timestamp: z.string(),
951
1004
  distinctId: z.string(),
@@ -955,7 +1008,7 @@ const analyticsUserRawSchema = z.object({
955
1008
  const analyticsUserSchema = analyticsUserRawSchema.omit({
956
1009
  payload: true
957
1010
  }).and(z.object({
958
- properties: userPropertiesSchema
1011
+ properties: contactPropertiesSchema
959
1012
  }));
960
1013
  const listUsersParamsSchema = z.object({
961
1014
  projectId: z.string(),
@@ -972,10 +1025,20 @@ const idenfitySchema = z.object({
972
1025
  distinctId: z.string(),
973
1026
  anonymousId: z.string(),
974
1027
  version: z.string(),
975
- payload: userPropertiesSchema,
976
- options: z.object({
1028
+ payload: contactPropertiesSchema,
1029
+ context: z.object({
977
1030
  active: z.boolean().optional()
978
1031
  }).optional()
979
1032
  });
1033
+ const latestIdentifiesRequestSchema = z.object({
1034
+ projectId: z.string(),
1035
+ limit: z.number().optional(),
1036
+ fields: z.array(z.string()).optional()
1037
+ });
1038
+ const latestIdentifiesResponseSchema = tinyBirdBaseSchema.extend({
1039
+ data: z.array(z.object({
1040
+ properties: contactPropertiesSchema
1041
+ }))
1042
+ });
980
1043
 
981
- export { Saasco, analyticsEventSchema, analyticsUserRawSchema, analyticsUserSchema, baseTopRequestSchema, coerceReservedProperties, currentUsersRequestSchema, currentUsersResponseSchema, eventsKpisResponseSchema, getAnalyticsUserParamsSchema, idenfitySchema, kpisRequestSchema, kpisResponseSchema, listUsersParamsSchema, reservedPropertiesSchema, tbAny, tinyBirdBaseSchema, topActionsResponseSchema, topBrowsersResponseSchema, topDevicesResponseSchema, topLocationsResponseSchema, topPagesResponseSchema, topSourcesResponseSchema, topSourcesSchema, userEventsResponseSchema, userPropertiesSchema };
1044
+ export { Saasco, TinybirdJobResponseSchema, analyticsEventSchema, analyticsUserRawSchema, analyticsUserSchema, baseTopRequestSchema, coerceReservedProperties, contactPropertiesSchema, currentUsersRequestSchema, currentUsersResponseSchema, getAnalyticsUserParamsSchema, idenfitySchema, kpisRequestSchema, kpisResponseSchema, latestEventItemSchema, latestEventsRequestSchema, latestEventsResponseSchema, latestIdentifiesRequestSchema, latestIdentifiesResponseSchema, listUsersParamsSchema, reservedPropertiesSchema, tbAny, timezones, tinyBirdBaseSchema, topActionsResponseSchema, topBrowsersResponseSchema, topDevicesResponseSchema, topLocationsResponseSchema, topPagesResponseSchema, topSourcesResponseSchema, topSourcesSchema, userEventsResponseSchema };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "saasco-sdk",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "dependencies": {
5
5
  "tslib": "^2.3.0",
6
6
  "@lukeed/uuid": "^2.0.1",
package/src/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './lib/analytics';
2
2
  export * from './lib/coerceReservedProperties';
3
+ export * from './lib/timezones';
3
4
  export * from './lib/types';
@@ -34,14 +34,16 @@ export declare class Saasco {
34
34
  * @param name The name of the event eg "Song Played"
35
35
  * @param properties The properties of the event eg { genre: "Classics", song: "Never Gonna Give You Up" }
36
36
  */
37
- track(name: string, properties?: Record<string, any>): void;
37
+ track(name: string, properties?: Record<string, any>, context?: {
38
+ active?: boolean;
39
+ }): Promise<string | Response | undefined> | undefined;
38
40
  /**
39
41
  * The page method lets you record page views on your website
40
42
  * This records the page title and path and names the event useing the reserved property "Page Viewed"
41
43
  *
42
44
  * Before implementing this make sure you have disabled the autoPageTracking in the config or you will get duplicate page views
43
45
  */
44
- page(): void;
46
+ page(): Promise<string | Response | undefined> | undefined;
45
47
  /**
46
48
  * The identify method lets you tie a user to their actions and record traits about them.
47
49
  * We recommend you call this when the user logs in and when any traits get updated.
@@ -49,12 +51,12 @@ export declare class Saasco {
49
51
  *
50
52
  * @param distinctId The user's id. This should be the user id from your database. This is optional and can be skipped, but you must provide an email address on the user properties.
51
53
  * @param properties A dictionary of traits you know about the user like their email, name, plan etc.
52
- * @param options Options for the identify call such as whether the user is active.
54
+ * @param context Context for the identify call such as whether the user is active.
53
55
  */
54
- identify(properties: Record<string, any>, options?: {
56
+ identify(properties: Record<string, any>, context?: {
55
57
  active?: boolean;
56
58
  }): void;
57
- identify(distinctId: string | number | null, properties?: Record<string, any>, options?: {
59
+ identify(distinctId: string | number | null, properties?: Record<string, any>, context?: {
58
60
  active?: boolean;
59
61
  }): void;
60
62
  /**
@@ -68,7 +70,6 @@ export declare class Saasco {
68
70
  * @param args Arguments to be logged
69
71
  */
70
72
  private log;
71
- private getSearchParam;
72
73
  /**
73
74
  * If autoPageTracking is enabled, this will automatically track page views
74
75
  * It listens to url changes to track new pages every time the url changes