refactor: migrate identity module to TS#1248
Conversation
54ee61d to
6013f98
Compare
6013f98 to
1cdacb3
Compare
|
PR SummaryMedium Risk Overview Adjusts several public/internal type contracts to match runtime behavior, including identity request shapes ( Reviewed by Cursor Bugbot for commit 85a0f3c. 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.
| const aliasRequestMessage = mpInstance._Identity.IdentityRequest.createAliasNetworkRequest( | ||
| aliasRequest | ||
| ); | ||
| ) as IAliasRequest; |
There was a problem hiding this comment.
Incorrect type cast masks alias network request shape
Medium Severity
The return value of createAliasNetworkRequest (which has fields like request_id, request_type, api_key, data) is cast as IAliasRequest, but IAliasRequest has a completely different shape (destinationMpid, sourceMpid, startTime, endTime). This incorrect assertion propagates through sendAliasRequest, whose parameter is also typed as IAliasRequest. While no runtime breakage occurs today because the object is only JSON-stringified, the misleading type could cause silent undefined values if anyone later accesses aliasRequest.destinationMpid inside sendAliasRequest trusting the declared type.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 8f4c21b. Configure here.
There was a problem hiding this comment.
Will address this in follow-up branch fix/SDKE-1103-alias-network-request-type by introducing IAliasNetworkRequest interface and updates sendAliasRequest + tests to use it.
|
| 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
| 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?
| 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
| 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.
| 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.
| ) { | ||
| 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.





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)