55 InitOptions ,
66 SegmentAnalytics ,
77 SegmentOpts ,
8- SegmentIntegration
8+ SegmentIntegration ,
9+ PageDefaults , Message
910} from './types' ;
1011
1112import cloneDeep from 'lodash.clonedeep'
@@ -323,8 +324,13 @@ Analytics.prototype.identify = function(
323324 } ) ;
324325
325326 // Add the initialize integrations so the server-side ones can be disabled too
327+ // NOTE: We need to merge integrations, not override them with assign
328+ // since it is possible to change the initialized integrations at runtime.
326329 if ( this . options . integrations ) {
327- defaults ( msg . integrations , this . options . integrations ) ;
330+ msg . integrations = {
331+ ...this . options . integrations ,
332+ ...msg . integrations
333+ }
328334 }
329335
330336 this . _invoke ( 'identify' , new Identify ( msg ) ) ;
@@ -379,8 +385,13 @@ Analytics.prototype.group = function(
379385 } ) ;
380386
381387 // Add the initialize integrations so the server-side ones can be disabled too
388+ // NOTE: We need to merge integrations, not override them with assign
389+ // since it is possible to change the initialized integrations at runtime.
382390 if ( this . options . integrations ) {
383- defaults ( msg . integrations , this . options . integrations ) ;
391+ msg . integrations = {
392+ ...this . options . integrations ,
393+ ...msg . integrations
394+ }
384395 }
385396
386397 this . _invoke ( 'group' , new Group ( msg ) ) ;
@@ -444,10 +455,12 @@ Analytics.prototype.track = function(
444455 }
445456
446457 // Add the initialize integrations so the server-side ones can be disabled too
447- defaults (
448- msg . integrations ,
449- this . _mergeInitializeAndPlanIntegrations ( planIntegrationOptions )
450- ) ;
458+ // NOTE: We need to merge integrations, not override them with assign
459+ // since it is possible to change the initialized integrations at runtime.
460+ msg . integrations = {
461+ ...this . _mergeInitializeAndPlanIntegrations ( planIntegrationOptions ) ,
462+ ...msg . integrations
463+ }
451464
452465 this . _invoke ( 'track' , new Track ( msg ) ) ;
453466
@@ -600,8 +613,15 @@ Analytics.prototype.page = function(
600613
601614 // Ensure properties has baseline spec properties.
602615 // TODO: Eventually move these entirely to `options.context.page`
603- const defs = pageDefaults ( ) ;
604- defaults ( properties , defs ) ;
616+ // FIXME: This is purposely not overriding `defs`. There was a bug in the logic implemented by `@ndhoule/defaults`.
617+ // This bug made it so we only would overwrite values in `defs` that were set to `undefined`.
618+ // In some cases, though, pageDefaults will return defaults with values set to "" (such as `window.location.search` defaulting to "").
619+ // The decision to not fix this bus was made to preserve backwards compatibility.
620+ const defs = pageDefaults ( )
621+ properties = {
622+ ...properties ,
623+ ...defs
624+ }
605625
606626 // Mirror user overrides to `options.context.page` (but exclude custom properties)
607627 // (Any page defaults get applied in `this.normalize` for consistency.)
@@ -621,8 +641,13 @@ Analytics.prototype.page = function(
621641 } ) ;
622642
623643 // Add the initialize integrations so the server-side ones can be disabled too
644+ // NOTE: We need to merge integrations, not override them with assign
645+ // since it is possible to change the initialized integrations at runtime.
624646 if ( this . options . integrations ) {
625- defaults ( msg . integrations , this . options . integrations ) ;
647+ msg . integrations = {
648+ ...this . options . integrations ,
649+ ...msg . integrations
650+ }
626651 }
627652
628653 this . _invoke ( 'page' , new Page ( msg ) ) ;
@@ -674,8 +699,13 @@ Analytics.prototype.alias = function(
674699 } ) ;
675700
676701 // Add the initialize integrations so the server-side ones can be disabled too
702+ // NOTE: We need to merge integrations, not override them with assign
703+ // since it is possible to change the initialized integrations at runtime.
677704 if ( this . options . integrations ) {
678- defaults ( msg . integrations , this . options . integrations ) ;
705+ msg . integrations = {
706+ ...this . options . integrations ,
707+ ...msg . integrations
708+ }
679709 }
680710
681711 this . _invoke ( 'alias' , new Alias ( msg ) ) ;
@@ -967,15 +997,19 @@ Analytics.prototype._parseQuery = function(query: string): SegmentAnalytics {
967997 */
968998
969999Analytics . prototype . normalize = function ( msg : {
970- context : { page } ;
1000+ options : { [ key : string ] : unknown }
1001+ context : { page : Partial < PageDefaults > } ;
9711002 anonymousId : string ;
9721003} ) : object {
9731004 msg = normalize ( msg , Object . keys ( this . _integrations ) ) ;
9741005 if ( msg . anonymousId ) user . anonymousId ( msg . anonymousId ) ;
9751006 msg . anonymousId = user . anonymousId ( ) ;
9761007
9771008 // Ensure all outgoing requests include page data in their contexts.
978- msg . context . page = defaults ( msg . context . page || { } , pageDefaults ( ) ) ;
1009+ msg . context . page = {
1010+ ...pageDefaults ( ) ,
1011+ ...msg . context . page
1012+ } ;
9791013
9801014 return msg ;
9811015} ;
0 commit comments