saasco-sdk 0.1.32 → 0.1.33

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.cjs.js CHANGED
@@ -7,7 +7,7 @@ var psl = require('psl');
7
7
  var uuid$1 = require('@lukeed/uuid');
8
8
  var zod = require('zod');
9
9
 
10
- var version = "0.1.32";
10
+ var version = "0.1.33";
11
11
 
12
12
  const timezones = {
13
13
  'Asia/Barnaul': 'RU',
@@ -624,23 +624,42 @@ function createFacebookPixelIntegration(config) {
624
624
  if (properties['value'] !== undefined) fbParams['value'] = properties['value'];
625
625
  if (properties['currency'] !== undefined) fbParams['currency'] = properties['currency'];
626
626
  if (properties['predicted_ltv'] !== undefined) fbParams['predicted_ltv'] = properties['predicted_ltv'];
627
- window.fbq('track', fbEventName, fbParams);
627
+ window.fbq('track', fbEventName, Object.assign(Object.assign({}, properties), fbParams));
628
628
  } else {
629
629
  window.fbq('track', fbEventName);
630
630
  }
631
631
  },
632
- identify: (userId, properties, context) => {
633
- if (!isPixelReady || !window.fbq) return;
634
- // Facebook Pixel doesn't have explicit identify method
635
- // We can use advanced matching or track as CompleteRegistration
636
- if (userId && properties) {
637
- // Track as registration/identification event
638
- window.fbq('track', 'CompleteRegistration', properties);
632
+ identify: (userId, properties, context) => tslib.__awaiter(this, void 0, void 0, function* () {
633
+ try {
634
+ if (typeof window !== 'undefined' && window.fbq) {
635
+ const amValues = coerceMetaConversionsAmValues(Object.assign(Object.assign({}, properties || {}), userId ? {
636
+ external_id: userId
637
+ } : {}));
638
+ const am = {};
639
+ if (amValues.external_id) am['external_id'] = amValues.external_id;
640
+ if (amValues.em) am['em'] = yield sha256Hex(amValues.em);
641
+ if (amValues.fn) am['fn'] = amValues.fn;
642
+ if (amValues.ln) am['ln'] = amValues.ln;
643
+ if (amValues.ph) am['ph'] = amValues.ph;
644
+ if (amValues.ge) am['ge'] = amValues.ge;
645
+ if (amValues.db) am['db'] = amValues.db;
646
+ if (amValues.ct) am['ct'] = amValues.ct;
647
+ if (amValues.st) am['st'] = amValues.st;
648
+ if (amValues.zp) am['zp'] = amValues.zp;
649
+ if (amValues.country) am['country'] = amValues.country;
650
+ if (Object.keys(am).length > 0) {
651
+ window.fbq('init', config.pixelId, am);
652
+ }
653
+ }
654
+ } catch (error) {
655
+ console.error('Error identifying user in Meta Pixel:', error);
639
656
  }
640
- }
657
+ })
641
658
  };
642
659
  }
643
660
  function getFacebookEventName(eventName, eventMapping) {
661
+ // Convert default saasco page view event by default
662
+ if (eventName === 'Page View') return 'PageView';
644
663
  if (!eventMapping) return eventName;
645
664
  return eventMapping[eventName] || eventName;
646
665
  }
@@ -668,6 +687,146 @@ function trackFacebookEvent(eventName, properties, eventMapping) {
668
687
  window.fbq('track', fbEventName);
669
688
  }
670
689
  }
690
+ function coerceMetaConversionsAmValues(properties) {
691
+ const coerce = [{
692
+ key: 'em',
693
+ coerceFrom: ['email', 'user_email', 'userEmail', 'email_address', 'emailAddress', 'e_mail', 'E_Mail', 'mail', 'Mail', 'contact_email', 'contactEmail', 'primary_email', 'primaryEmail'],
694
+ transform: value => {
695
+ if (typeof value !== 'string') return undefined;
696
+ const normalized = value.trim().toLowerCase();
697
+ return normalized || undefined;
698
+ }
699
+ }, {
700
+ key: 'fn',
701
+ coerceFrom: ['first_name', 'firstName', 'firstname', 'given_name', 'givenName', 'user_first_name', 'userFirstName', 'name_first', 'nameFirst', 'f_name', 'fName'],
702
+ transform: value => {
703
+ if (typeof value !== 'string') return undefined;
704
+ const normalized = value.trim().toLowerCase();
705
+ return normalized || undefined;
706
+ }
707
+ }, {
708
+ key: 'ln',
709
+ coerceFrom: ['last_name', 'lastName', 'lastname', 'surname', 'user_last_name', 'userLastName', 'name_last', 'nameLast', 'l_name', 'lName'],
710
+ transform: value => {
711
+ if (typeof value !== 'string') return undefined;
712
+ const normalized = value.trim().toLowerCase();
713
+ return normalized || undefined;
714
+ }
715
+ }, {
716
+ key: 'ph',
717
+ coerceFrom: ['phone', 'phone_number', 'phoneNumber', 'mobile', 'mobile_number', 'mobileNumber', 'contact_number', 'contactNumber', 'tel', 'telephone'],
718
+ transform: value => {
719
+ if (typeof value !== 'string' && typeof value !== 'number') return undefined;
720
+ const phoneStr = String(value).replace(/\D/g, '');
721
+ return phoneStr || undefined;
722
+ }
723
+ }, {
724
+ key: 'external_id',
725
+ coerceFrom: ['external_id', 'externalId', 'user_id', 'userId', 'id', 'distinctId', 'distinct_id', 'customer_id', 'customerId', 'member_id', 'memberId', 'loyalty_id', 'loyaltyId'],
726
+ transform: value => {
727
+ if (value == null) return undefined;
728
+ return String(value) || undefined;
729
+ }
730
+ }, {
731
+ key: 'ge',
732
+ coerceFrom: ['gender', 'user_gender', 'userGender', 'sex', 'user_sex', 'userSex'],
733
+ transform: value => {
734
+ if (typeof value !== 'string') return undefined;
735
+ const normalized = value.trim().toLowerCase();
736
+ if (normalized === 'female' || normalized === 'f') return 'f';
737
+ if (normalized === 'male' || normalized === 'm') return 'm';
738
+ return undefined;
739
+ }
740
+ }, {
741
+ key: 'db',
742
+ coerceFrom: ['birthday', 'birth_date', 'birthDate', 'date_of_birth', 'dateOfBirth', 'dob', 'Dob', 'birth_day', 'birthDay'],
743
+ transform: value => {
744
+ if (!value) return undefined;
745
+ let dateStr;
746
+ if (value instanceof Date) {
747
+ dateStr = value.toISOString().split('T')[0];
748
+ } else {
749
+ dateStr = String(value);
750
+ }
751
+ const dateMatch = dateStr.match(/(\d{4})-(\d{2})-(\d{2})/);
752
+ if (dateMatch) {
753
+ const [, year, month, day] = dateMatch;
754
+ return `${year}${month}${day}`;
755
+ }
756
+ const numericMatch = dateStr.replace(/\D/g, '');
757
+ if (numericMatch.length === 8) {
758
+ return numericMatch;
759
+ }
760
+ return undefined;
761
+ }
762
+ }, {
763
+ key: 'ct',
764
+ coerceFrom: ['city', 'user_city', 'userCity', 'location_city', 'locationCity', 'address_city', 'addressCity'],
765
+ transform: value => {
766
+ if (typeof value !== 'string') return undefined;
767
+ const normalized = value.trim().toLowerCase().replace(/\s+/g, '');
768
+ return normalized || undefined;
769
+ }
770
+ }, {
771
+ key: 'st',
772
+ coerceFrom: ['state', 'user_state', 'userState', 'province', 'user_province', 'userProvince', 'region', 'user_region', 'userRegion', 'location_state', 'locationState', 'address_state', 'addressState'],
773
+ transform: value => {
774
+ if (typeof value !== 'string') return undefined;
775
+ const normalized = value.trim().toLowerCase();
776
+ if (normalized.length === 2) return normalized;
777
+ return undefined;
778
+ }
779
+ }, {
780
+ key: 'zp',
781
+ coerceFrom: ['zip', 'zipcode', 'zip_code', 'postal_code', 'postalCode', 'postcode', 'user_zip', 'userZip', 'address_zip', 'addressZip'],
782
+ transform: value => {
783
+ if (typeof value !== 'string' && typeof value !== 'number') return undefined;
784
+ return String(value).trim() || undefined;
785
+ }
786
+ }, {
787
+ key: 'country',
788
+ coerceFrom: ['country', 'country_code', 'countryCode', 'user_country', 'userCountry', 'location_country', 'locationCountry', 'address_country', 'addressCountry'],
789
+ transform: value => {
790
+ if (typeof value !== 'string') return undefined;
791
+ const normalized = value.trim().toLowerCase();
792
+ if (normalized.length === 2) return normalized;
793
+ return undefined;
794
+ }
795
+ }];
796
+ const result = {};
797
+ for (const {
798
+ key,
799
+ coerceFrom,
800
+ transform
801
+ } of coerce) {
802
+ const foundValue = findFirstProperty(properties, coerceFrom);
803
+ if (foundValue !== null && transform) {
804
+ const transformedValue = transform(foundValue);
805
+ if (transformedValue) {
806
+ result[key] = transformedValue;
807
+ }
808
+ } else if (foundValue !== null && typeof foundValue === 'string') {
809
+ result[key] = foundValue;
810
+ }
811
+ }
812
+ return result;
813
+ }
814
+ function findFirstProperty(properties, keys) {
815
+ for (const key of keys) {
816
+ if (properties[key] !== undefined) {
817
+ return properties[key];
818
+ }
819
+ }
820
+ return null;
821
+ }
822
+ const toHex = buf => [...new Uint8Array(buf)].map(b => b.toString(16).padStart(2, '0')).join('');
823
+ function sha256Hex(input) {
824
+ return tslib.__awaiter(this, void 0, void 0, function* () {
825
+ const enc = new TextEncoder().encode(input);
826
+ const digest = yield crypto.subtle.digest('SHA-256', enc);
827
+ return toHex(digest);
828
+ });
829
+ }
671
830
 
672
831
  /* eslint-disable @typescript-eslint/no-explicit-any */
673
832
  class AnalyticsLogger {
@@ -847,21 +1006,23 @@ class IntegrationManager {
847
1006
  this.deliver(envelope);
848
1007
  }
849
1008
  deliver(evt) {
850
- for (const {
851
- integration,
852
- status
853
- } of this.integrations.values()) {
854
- if (status !== 'ready') continue;
855
- try {
856
- if (evt.type === 'track' && integration.track && evt.name) {
857
- integration.track(evt.name, evt.properties, evt.context);
858
- } else if (evt.type === 'identify' && integration.identify) {
859
- integration.identify(evt.context.distinctId, evt.properties, evt.context);
1009
+ return tslib.__awaiter(this, void 0, void 0, function* () {
1010
+ for (const {
1011
+ integration,
1012
+ status
1013
+ } of this.integrations.values()) {
1014
+ if (status !== 'ready') continue;
1015
+ try {
1016
+ if (evt.type === 'track' && integration.track && evt.name) {
1017
+ yield integration.track(evt.name, evt.properties, evt.context);
1018
+ } else if (evt.type === 'identify' && integration.identify) {
1019
+ yield integration.identify(evt.context.distinctId, evt.properties, evt.context);
1020
+ }
1021
+ } catch (e) {
1022
+ this.logger.error(`deliver error in ${integration.name} (${evt.type})`, e);
860
1023
  }
861
- } catch (e) {
862
- this.logger.error(`deliver error in ${integration.name}`, e);
863
1024
  }
864
- }
1025
+ });
865
1026
  }
866
1027
  /**
867
1028
  * Flush queued events FIFO once at least one integration is ready.
@@ -1458,41 +1619,10 @@ const browserContextSchema = zod.z.object({
1458
1619
  $utmAdId: zod.z.string().nullable()
1459
1620
  });
1460
1621
 
1461
- /**
1462
- * Example integration that works on both client and server
1463
- * Simply logs events to console
1464
- */
1465
- function createConsoleIntegration(config = {}) {
1466
- const prefix = config.prefix || '[Analytics]';
1467
- return {
1468
- name: 'console',
1469
- environments: ['client', 'server'],
1470
- // This integration works on both client and server
1471
- init: () => {
1472
- console.log(`${prefix} Console integration initialized`);
1473
- },
1474
- track: (eventName, properties, context) => {
1475
- console.log(`${prefix} Track:`, {
1476
- event: eventName,
1477
- properties,
1478
- context
1479
- });
1480
- },
1481
- identify: (userId, properties, context) => {
1482
- console.log(`${prefix} Identify:`, {
1483
- userId,
1484
- properties,
1485
- context
1486
- });
1487
- }
1488
- };
1489
- }
1490
-
1491
1622
  exports.IntegrationManager = IntegrationManager;
1492
1623
  exports.Logger = Logger;
1493
1624
  exports.Saasco = Saasco;
1494
1625
  exports.browserContextSchema = browserContextSchema;
1495
- exports.createConsoleIntegration = createConsoleIntegration;
1496
1626
  exports.createFacebookPixelIntegration = createFacebookPixelIntegration;
1497
1627
  exports.getBrowserContext = getBrowserContext;
1498
1628
  exports.initializeFacebookPixel = initializeFacebookPixel;
package/index.esm.js CHANGED
@@ -3,7 +3,7 @@ import { isValid, parse } from 'psl';
3
3
  import { v4 } from '@lukeed/uuid';
4
4
  import { z } from 'zod';
5
5
 
6
- var version = "0.1.32";
6
+ var version = "0.1.33";
7
7
 
8
8
  const timezones = {
9
9
  'Asia/Barnaul': 'RU',
@@ -620,23 +620,42 @@ function createFacebookPixelIntegration(config) {
620
620
  if (properties['value'] !== undefined) fbParams['value'] = properties['value'];
621
621
  if (properties['currency'] !== undefined) fbParams['currency'] = properties['currency'];
622
622
  if (properties['predicted_ltv'] !== undefined) fbParams['predicted_ltv'] = properties['predicted_ltv'];
623
- window.fbq('track', fbEventName, fbParams);
623
+ window.fbq('track', fbEventName, Object.assign(Object.assign({}, properties), fbParams));
624
624
  } else {
625
625
  window.fbq('track', fbEventName);
626
626
  }
627
627
  },
628
- identify: (userId, properties, context) => {
629
- if (!isPixelReady || !window.fbq) return;
630
- // Facebook Pixel doesn't have explicit identify method
631
- // We can use advanced matching or track as CompleteRegistration
632
- if (userId && properties) {
633
- // Track as registration/identification event
634
- window.fbq('track', 'CompleteRegistration', properties);
628
+ identify: (userId, properties, context) => __awaiter(this, void 0, void 0, function* () {
629
+ try {
630
+ if (typeof window !== 'undefined' && window.fbq) {
631
+ const amValues = coerceMetaConversionsAmValues(Object.assign(Object.assign({}, properties || {}), userId ? {
632
+ external_id: userId
633
+ } : {}));
634
+ const am = {};
635
+ if (amValues.external_id) am['external_id'] = amValues.external_id;
636
+ if (amValues.em) am['em'] = yield sha256Hex(amValues.em);
637
+ if (amValues.fn) am['fn'] = amValues.fn;
638
+ if (amValues.ln) am['ln'] = amValues.ln;
639
+ if (amValues.ph) am['ph'] = amValues.ph;
640
+ if (amValues.ge) am['ge'] = amValues.ge;
641
+ if (amValues.db) am['db'] = amValues.db;
642
+ if (amValues.ct) am['ct'] = amValues.ct;
643
+ if (amValues.st) am['st'] = amValues.st;
644
+ if (amValues.zp) am['zp'] = amValues.zp;
645
+ if (amValues.country) am['country'] = amValues.country;
646
+ if (Object.keys(am).length > 0) {
647
+ window.fbq('init', config.pixelId, am);
648
+ }
649
+ }
650
+ } catch (error) {
651
+ console.error('Error identifying user in Meta Pixel:', error);
635
652
  }
636
- }
653
+ })
637
654
  };
638
655
  }
639
656
  function getFacebookEventName(eventName, eventMapping) {
657
+ // Convert default saasco page view event by default
658
+ if (eventName === 'Page View') return 'PageView';
640
659
  if (!eventMapping) return eventName;
641
660
  return eventMapping[eventName] || eventName;
642
661
  }
@@ -664,6 +683,146 @@ function trackFacebookEvent(eventName, properties, eventMapping) {
664
683
  window.fbq('track', fbEventName);
665
684
  }
666
685
  }
686
+ function coerceMetaConversionsAmValues(properties) {
687
+ const coerce = [{
688
+ key: 'em',
689
+ coerceFrom: ['email', 'user_email', 'userEmail', 'email_address', 'emailAddress', 'e_mail', 'E_Mail', 'mail', 'Mail', 'contact_email', 'contactEmail', 'primary_email', 'primaryEmail'],
690
+ transform: value => {
691
+ if (typeof value !== 'string') return undefined;
692
+ const normalized = value.trim().toLowerCase();
693
+ return normalized || undefined;
694
+ }
695
+ }, {
696
+ key: 'fn',
697
+ coerceFrom: ['first_name', 'firstName', 'firstname', 'given_name', 'givenName', 'user_first_name', 'userFirstName', 'name_first', 'nameFirst', 'f_name', 'fName'],
698
+ transform: value => {
699
+ if (typeof value !== 'string') return undefined;
700
+ const normalized = value.trim().toLowerCase();
701
+ return normalized || undefined;
702
+ }
703
+ }, {
704
+ key: 'ln',
705
+ coerceFrom: ['last_name', 'lastName', 'lastname', 'surname', 'user_last_name', 'userLastName', 'name_last', 'nameLast', 'l_name', 'lName'],
706
+ transform: value => {
707
+ if (typeof value !== 'string') return undefined;
708
+ const normalized = value.trim().toLowerCase();
709
+ return normalized || undefined;
710
+ }
711
+ }, {
712
+ key: 'ph',
713
+ coerceFrom: ['phone', 'phone_number', 'phoneNumber', 'mobile', 'mobile_number', 'mobileNumber', 'contact_number', 'contactNumber', 'tel', 'telephone'],
714
+ transform: value => {
715
+ if (typeof value !== 'string' && typeof value !== 'number') return undefined;
716
+ const phoneStr = String(value).replace(/\D/g, '');
717
+ return phoneStr || undefined;
718
+ }
719
+ }, {
720
+ key: 'external_id',
721
+ coerceFrom: ['external_id', 'externalId', 'user_id', 'userId', 'id', 'distinctId', 'distinct_id', 'customer_id', 'customerId', 'member_id', 'memberId', 'loyalty_id', 'loyaltyId'],
722
+ transform: value => {
723
+ if (value == null) return undefined;
724
+ return String(value) || undefined;
725
+ }
726
+ }, {
727
+ key: 'ge',
728
+ coerceFrom: ['gender', 'user_gender', 'userGender', 'sex', 'user_sex', 'userSex'],
729
+ transform: value => {
730
+ if (typeof value !== 'string') return undefined;
731
+ const normalized = value.trim().toLowerCase();
732
+ if (normalized === 'female' || normalized === 'f') return 'f';
733
+ if (normalized === 'male' || normalized === 'm') return 'm';
734
+ return undefined;
735
+ }
736
+ }, {
737
+ key: 'db',
738
+ coerceFrom: ['birthday', 'birth_date', 'birthDate', 'date_of_birth', 'dateOfBirth', 'dob', 'Dob', 'birth_day', 'birthDay'],
739
+ transform: value => {
740
+ if (!value) return undefined;
741
+ let dateStr;
742
+ if (value instanceof Date) {
743
+ dateStr = value.toISOString().split('T')[0];
744
+ } else {
745
+ dateStr = String(value);
746
+ }
747
+ const dateMatch = dateStr.match(/(\d{4})-(\d{2})-(\d{2})/);
748
+ if (dateMatch) {
749
+ const [, year, month, day] = dateMatch;
750
+ return `${year}${month}${day}`;
751
+ }
752
+ const numericMatch = dateStr.replace(/\D/g, '');
753
+ if (numericMatch.length === 8) {
754
+ return numericMatch;
755
+ }
756
+ return undefined;
757
+ }
758
+ }, {
759
+ key: 'ct',
760
+ coerceFrom: ['city', 'user_city', 'userCity', 'location_city', 'locationCity', 'address_city', 'addressCity'],
761
+ transform: value => {
762
+ if (typeof value !== 'string') return undefined;
763
+ const normalized = value.trim().toLowerCase().replace(/\s+/g, '');
764
+ return normalized || undefined;
765
+ }
766
+ }, {
767
+ key: 'st',
768
+ coerceFrom: ['state', 'user_state', 'userState', 'province', 'user_province', 'userProvince', 'region', 'user_region', 'userRegion', 'location_state', 'locationState', 'address_state', 'addressState'],
769
+ transform: value => {
770
+ if (typeof value !== 'string') return undefined;
771
+ const normalized = value.trim().toLowerCase();
772
+ if (normalized.length === 2) return normalized;
773
+ return undefined;
774
+ }
775
+ }, {
776
+ key: 'zp',
777
+ coerceFrom: ['zip', 'zipcode', 'zip_code', 'postal_code', 'postalCode', 'postcode', 'user_zip', 'userZip', 'address_zip', 'addressZip'],
778
+ transform: value => {
779
+ if (typeof value !== 'string' && typeof value !== 'number') return undefined;
780
+ return String(value).trim() || undefined;
781
+ }
782
+ }, {
783
+ key: 'country',
784
+ coerceFrom: ['country', 'country_code', 'countryCode', 'user_country', 'userCountry', 'location_country', 'locationCountry', 'address_country', 'addressCountry'],
785
+ transform: value => {
786
+ if (typeof value !== 'string') return undefined;
787
+ const normalized = value.trim().toLowerCase();
788
+ if (normalized.length === 2) return normalized;
789
+ return undefined;
790
+ }
791
+ }];
792
+ const result = {};
793
+ for (const {
794
+ key,
795
+ coerceFrom,
796
+ transform
797
+ } of coerce) {
798
+ const foundValue = findFirstProperty(properties, coerceFrom);
799
+ if (foundValue !== null && transform) {
800
+ const transformedValue = transform(foundValue);
801
+ if (transformedValue) {
802
+ result[key] = transformedValue;
803
+ }
804
+ } else if (foundValue !== null && typeof foundValue === 'string') {
805
+ result[key] = foundValue;
806
+ }
807
+ }
808
+ return result;
809
+ }
810
+ function findFirstProperty(properties, keys) {
811
+ for (const key of keys) {
812
+ if (properties[key] !== undefined) {
813
+ return properties[key];
814
+ }
815
+ }
816
+ return null;
817
+ }
818
+ const toHex = buf => [...new Uint8Array(buf)].map(b => b.toString(16).padStart(2, '0')).join('');
819
+ function sha256Hex(input) {
820
+ return __awaiter(this, void 0, void 0, function* () {
821
+ const enc = new TextEncoder().encode(input);
822
+ const digest = yield crypto.subtle.digest('SHA-256', enc);
823
+ return toHex(digest);
824
+ });
825
+ }
667
826
 
668
827
  /* eslint-disable @typescript-eslint/no-explicit-any */
669
828
  class AnalyticsLogger {
@@ -843,21 +1002,23 @@ class IntegrationManager {
843
1002
  this.deliver(envelope);
844
1003
  }
845
1004
  deliver(evt) {
846
- for (const {
847
- integration,
848
- status
849
- } of this.integrations.values()) {
850
- if (status !== 'ready') continue;
851
- try {
852
- if (evt.type === 'track' && integration.track && evt.name) {
853
- integration.track(evt.name, evt.properties, evt.context);
854
- } else if (evt.type === 'identify' && integration.identify) {
855
- integration.identify(evt.context.distinctId, evt.properties, evt.context);
1005
+ return __awaiter(this, void 0, void 0, function* () {
1006
+ for (const {
1007
+ integration,
1008
+ status
1009
+ } of this.integrations.values()) {
1010
+ if (status !== 'ready') continue;
1011
+ try {
1012
+ if (evt.type === 'track' && integration.track && evt.name) {
1013
+ yield integration.track(evt.name, evt.properties, evt.context);
1014
+ } else if (evt.type === 'identify' && integration.identify) {
1015
+ yield integration.identify(evt.context.distinctId, evt.properties, evt.context);
1016
+ }
1017
+ } catch (e) {
1018
+ this.logger.error(`deliver error in ${integration.name} (${evt.type})`, e);
856
1019
  }
857
- } catch (e) {
858
- this.logger.error(`deliver error in ${integration.name}`, e);
859
1020
  }
860
- }
1021
+ });
861
1022
  }
862
1023
  /**
863
1024
  * Flush queued events FIFO once at least one integration is ready.
@@ -1454,34 +1615,4 @@ const browserContextSchema = z.object({
1454
1615
  $utmAdId: z.string().nullable()
1455
1616
  });
1456
1617
 
1457
- /**
1458
- * Example integration that works on both client and server
1459
- * Simply logs events to console
1460
- */
1461
- function createConsoleIntegration(config = {}) {
1462
- const prefix = config.prefix || '[Analytics]';
1463
- return {
1464
- name: 'console',
1465
- environments: ['client', 'server'],
1466
- // This integration works on both client and server
1467
- init: () => {
1468
- console.log(`${prefix} Console integration initialized`);
1469
- },
1470
- track: (eventName, properties, context) => {
1471
- console.log(`${prefix} Track:`, {
1472
- event: eventName,
1473
- properties,
1474
- context
1475
- });
1476
- },
1477
- identify: (userId, properties, context) => {
1478
- console.log(`${prefix} Identify:`, {
1479
- userId,
1480
- properties,
1481
- context
1482
- });
1483
- }
1484
- };
1485
- }
1486
-
1487
- export { IntegrationManager, Logger, Saasco, browserContextSchema, createConsoleIntegration, createFacebookPixelIntegration, getBrowserContext, initializeFacebookPixel, timezones, trackFacebookEvent };
1618
+ export { IntegrationManager, Logger, Saasco, browserContextSchema, createFacebookPixelIntegration, getBrowserContext, initializeFacebookPixel, timezones, trackFacebookEvent };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "saasco-sdk",
3
- "version": "0.1.32",
3
+ "version": "0.1.33",
4
4
  "dependencies": {
5
5
  "tslib": "^2.3.0",
6
6
  "@lukeed/uuid": "^2.0.1",
@@ -25,8 +25,9 @@ type DoRequestResponse = {
25
25
  success: boolean;
26
26
  message: string;
27
27
  };
28
- export type IntegrationConfig = {
28
+ export type IntegrationConfigBase = {
29
29
  type: string;
30
+ config: Record<string, any>;
30
31
  };
31
32
  export type IntegrationsConfig = FacebookPixelIntegrationConfig[];
32
33
  export declare class Saasco {
@@ -1,4 +1,4 @@
1
- import { IntegrationConfig } from '../analytics';
1
+ import { IntegrationConfigBase } from '../analytics';
2
2
  import { Integration } from './integration-manager';
3
3
  declare global {
4
4
  interface Window {
@@ -9,7 +9,7 @@ declare global {
9
9
  export type FacebookEventMapping = {
10
10
  [key: string]: StandardFacebookEvent;
11
11
  };
12
- export type FacebookPixelIntegrationConfig = IntegrationConfig & {
12
+ export type FacebookPixelIntegrationConfig = IntegrationConfigBase & {
13
13
  type: 'facebook-pixel';
14
14
  config: FacebookPixelConfig;
15
15
  };
@@ -1,3 +1,2 @@
1
1
  export * from './integration-manager';
2
2
  export * from './facebook-pixel';
3
- export * from './console-integration';
@@ -34,7 +34,7 @@ export type Integration = {
34
34
  /**
35
35
  * The function to identify a user
36
36
  */
37
- identify?: (userId?: string | null, properties?: Record<string, unknown>, context?: AnalyticsContext) => void;
37
+ identify?: (userId?: string | null, properties?: Record<string, unknown>, context?: AnalyticsContext) => void | Promise<void>;
38
38
  };
39
39
  export type IntegrationStatus = 'idle' | 'loading' | 'ready' | 'error';
40
40
  export type IntegrationState = {
@@ -1,9 +0,0 @@
1
- import { Integration } from './integration-manager';
2
- export type ConsoleIntegrationConfig = {
3
- prefix?: string;
4
- };
5
- /**
6
- * Example integration that works on both client and server
7
- * Simply logs events to console
8
- */
9
- export declare function createConsoleIntegration(config?: ConsoleIntegrationConfig): Integration;