refactor: migrate identity module to TS#1248
Conversation
54ee61d to
6013f98
Compare
6013f98 to
1cdacb3
Compare
|
PR SummaryMedium Risk Overview Interface and wiring updates align types with runtime usage: identity request payloads use Small defensive tweaks include optional kit Reviewed by Cursor Bugbot for commit d408003. Bugbot is set up for automated code reviews on this repo. Configure here. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 8f4c21b. Configure here.
| UserIdentities, | ||
| IdentityCallback, | ||
| } from '@mparticle/web-sdk'; | ||
| import { IdentityCallback } from './identity-user-interfaces'; |
There was a problem hiding this comment.
Clean up the imports
| identityApiData: IdentityApiData, | ||
| identityMethod: string, | ||
| knownIdentities: IKnownIdentities, | ||
| knownIdentities: IKnownIdentities | UserIdentities, |
There was a problem hiding this comment.
I'm not sure if these overlap cleanly
There was a problem hiding this comment.
Good catch. IKnownIdentities | UserIdentities collapses to plain UserIdentities at the type level (since IKnownIdentities extends UserIdentities), so the union added zero safety and actually hid device_application_stamp
| environment: Environment; | ||
| request_id: string; | ||
| request_timestamp_unixtime_ms: number; | ||
| request_timestamp_ms: number; |
There was a problem hiding this comment.
Why are we renaming this?
There was a problem hiding this comment.
Yeah, it's really a typo fix on the interface. The SDK has always been sending request_timestamp_ms, the interface was just declaring the different key name
| previousIdentities: UserIdentities, | ||
| newIdentitie: UserIdentities | ||
| ): IIdentityAPIIdentityChangeData; | ||
| newIdentities: UserIdentities |
There was a problem hiding this comment.
How long has this typo been here? 😓
| ): IUserAttributeChangeEvent; | ||
| createUserIdentityChange( | ||
| identityType: SDKIdentityTypeEnum, | ||
| identityType: SDKIdentityTypeEnum | string, |
There was a problem hiding this comment.
I don't think we should use string but really limit this to known types
There was a problem hiding this comment.
Tightened to SDKIdentityTypeEnum on the interface and narrowed the loop
| aliasRequest.destinationMpid | ||
| ); | ||
| var aliasRequestMessage = mpInstance._Identity.IdentityRequest.createAliasNetworkRequest( | ||
| const aliasRequestMessage = mpInstance._Identity.IdentityRequest.createAliasNetworkRequest( |
There was a problem hiding this comment.
This cast hides a real mismatch and is worth fixing before merge.
createAliasNetworkRequest returns the network wire shape:
{ request_id, request_type: 'alias', environment, data: { destination_mpid, source_mpid, start_unixtime_ms, end_unixtime_ms, device_application_stamp } }But IAliasRequest is:
{ destinationMpid, sourceMpid, startTime, endTime, scope? }Those are completely different shapes. The as IAliasRequest cast tells the compiler "trust me, it's an IAliasRequest" and from there sendAliasRequest(aliasRequest: IAliasRequest) is happy. At runtime sendAliasRequest just does JSON.stringify(aliasRequest) (identityApiClient.ts:113) so the actual wire format is still right, but the types are lying.
There was a problem hiding this comment.
Agreed, the cast is hiding a real type drift. Already addressed in fix/SDKE-1103-alias-network-request-type branch
| callback: IdentityCallback, | ||
| method: IdentityAPIMethod | ||
| ): IdentityPreProcessResult; | ||
| createAliasNetworkRequest(aliasRequest: IAliasRequest): object; |
There was a problem hiding this comment.
Tied to the earlier comment. These three methods all return object, which is barely better than any. The migration goal is type safety, so this is a missed opportunity.
If you do above for createAliasNetworkRequest, the same pattern applies here, declare proper interfaces for the native shapes and use them. convertToNative returning object | void is especially confusing because void is meaningless as a return type union with anything else (it means "ignore the return value"), and the actual code returns undefined explicitly. IdentityNativeRequest | undefined would be clearer.
Happy to defer to a follow-up if you want to keep this PR scoped, but please file a ticket so it does not slip.
There was a problem hiding this comment.
Agreed, object is barely better than any, and object | void is genuinely confusing semantics.
Picking up the two alias-related ones on fix/SDKE-1103-alias-network-request-type:
createAliasNetworkRequest: : object → : IAliasNetworkRequest
convertAliasToNative: : object → : INativeAliasRequest (new interface — { DestinationMpid, SourceMpid, StartUnixtimeMs, EndUnixtimeMs, Scope? })
Creating a separate ticket (https://go/j/SDKE-1204) for convertToNative since it's a different code path (identity native bridge, not alias), will switch to INativeIdentityRequest | undefined per your suggestion
| ) { | ||
| if (forwarder.logOut) { | ||
| forwarder.logOut(evt); | ||
| const fwd = forwarder as unknown as Record<string, Function>; |
There was a problem hiding this comment.
Why the double-cast to Record<string, Function>? That tells the compiler "this thing is a string-keyed bag of arbitrary functions" which is the loosest possible cast and erases all type information from forwarder.
I checked ConfiguredKit in forwarders.interfaces.ts does not have a logOut method. So either:
- The old JS code (
if (forwarder.logOut)) was always-falsy defensive code that never actually fired. If that is the case, this whole block can be deleted. - There is a
logOutmethod present at runtime on some kit implementations that theConfiguredKitinterface does not describe. If that is the case, addlogOut?: (evt: SDKEvent) => voidtoConfiguredKitand the cast disappears.
There was a problem hiding this comment.
Option 2, logOut is real at runtime (MockForwarder defines it and the CBT test asserts logOutCalled === true after logout). Added logOut?: (evt: SDKEvent) => void to ConfiguredKit and dropped the cast.
|




Background
What Has Changed
Testing
Screenshots/Video
Checklist
Additional Notes
self = thispattern in the Identity constructor (~31 usages) was intentionally left as-is for a follow-up refactor to arrow functions, to keep this PR focused on the JS→TS migration only.var→const/letreplacements and removal of unnecessary type assertions were included as part of SonarCloud compliance.Reference Issue (For employees only. Ignore if you are an outside contributor)