@@ -4,12 +4,14 @@ import { ID, User } from '../user'
44import {
55 Integrations ,
66 EventProperties ,
7- Traits ,
7+ CoreAnalyticsTraits ,
88 CoreSegmentEvent ,
99 CoreOptions ,
10+ CoreExtraContext ,
1011} from './interfaces'
1112import { pickBy } from '../utils/pick'
1213import { validateEvent } from '../validation/assertions'
14+ import type { RemoveIndexSignature } from '../utils/ts-helpers'
1315
1416interface EventFactorySettings {
1517 createMessageId : ( ) => string
@@ -101,7 +103,7 @@ export class EventFactory {
101103
102104 identify (
103105 userId : ID ,
104- traits ?: Traits ,
106+ traits ?: CoreAnalyticsTraits ,
105107 options ?: CoreOptions ,
106108 globalIntegrations ?: Integrations
107109 ) : CoreSegmentEvent {
@@ -117,7 +119,7 @@ export class EventFactory {
117119
118120 group (
119121 groupId : ID ,
120- traits ?: Traits ,
122+ traits ?: CoreAnalyticsTraits ,
121123 options ?: CoreOptions ,
122124 globalIntegrations ?: Integrations
123125 ) : CoreSegmentEvent {
@@ -186,30 +188,42 @@ export class EventFactory {
186188 * Builds the context part of an event based on "foreign" keys that
187189 * are provided in the `Options` parameter for an Event
188190 */
189- private context ( event : CoreSegmentEvent ) : [ object , object ] {
190- const options = event . options ?? { }
191- delete options [ 'integrations' ]
191+ private context (
192+ options : CoreOptions
193+ ) : [ CoreExtraContext , Partial < CoreSegmentEvent > ] {
194+ type CoreOptionKeys = keyof RemoveIndexSignature < CoreOptions >
195+ /**
196+ * If the event options are known keys from this list, we move them to the top level of the event.
197+ * Any other options are moved to context.
198+ */
199+ const eventOverrideKeys : CoreOptionKeys [ ] = [
200+ 'userId' ,
201+ 'anonymousId' ,
202+ 'timestamp' ,
203+ ]
192204
193- const providedOptionsKeys = Object . keys ( options )
205+ delete options [ 'integrations' ]
206+ const providedOptionsKeys = Object . keys ( options ) as Exclude <
207+ CoreOptionKeys ,
208+ 'integrations'
209+ > [ ]
194210
195- const context = event . options ? .context ?? { }
196- const overrides = { }
211+ const context = options . context ?? { }
212+ const eventOverrides = { }
197213
198214 providedOptionsKeys . forEach ( ( key ) => {
199215 if ( key === 'context' ) {
200216 return
201217 }
202218
203- if (
204- [ 'integrations' , 'anonymousId' , 'timestamp' , 'userId' ] . includes ( key )
205- ) {
206- dset ( overrides , key , options [ key ] )
219+ if ( eventOverrideKeys . includes ( key ) ) {
220+ dset ( eventOverrides , key , options [ key ] )
207221 } else {
208222 dset ( context , key , options [ key ] )
209223 }
210224 } )
211225
212- return [ context , overrides ]
226+ return [ context , eventOverrides ]
213227 }
214228
215229 public normalize ( event : CoreSegmentEvent ) : CoreSegmentEvent {
@@ -240,14 +254,17 @@ export class EventFactory {
240254 ...event . options ?. integrations ,
241255 }
242256
243- const [ context , overrides ] = this . context ( event )
257+ const [ context , overrides ] = event . options
258+ ? this . context ( event . options )
259+ : [ ]
260+
244261 const { options, ...rest } = event
245262
246263 const body = {
247264 timestamp : new Date ( ) ,
248265 ...rest ,
249- context,
250266 integrations : allIntegrations ,
267+ context,
251268 ...overrides ,
252269 }
253270
0 commit comments