Skip to content

[SDK-484] Remove legacy code#868

Open
lposen wants to merge 2 commits into
update/SDK-483-0-85from
upgrade/SDK-484-remove-legacy-architecture-code
Open

[SDK-484] Remove legacy code#868
lposen wants to merge 2 commits into
update/SDK-483-0-85from
upgrade/SDK-484-remove-legacy-architecture-code

Conversation

@lposen
Copy link
Copy Markdown
Contributor

@lposen lposen commented May 20, 2026

🔹 JIRA Ticket(s) if any

✏️ Description

Please provide a brief description of what this pull request does.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 20, 2026

Lines Statements Branches Functions
Coverage: 63%
63.88% (414/648) 43.86% (118/269) 62.17% (143/230)

@qltysh
Copy link
Copy Markdown

qltysh Bot commented May 20, 2026

Qlty


Coverage Impact

⬆️ Merging this pull request will increase total coverage on update/SDK-483-0-85 by 0.84%.

Modified Files with Diff Coverage (5)

RatingFile% DiffUncovered Line #s
Coverage rating: A Coverage rating: F
src/api/index.ts0.0%5
Coverage rating: A Coverage rating: A
src/core/classes/IterableApi.ts100.0%
Coverage rating: A Coverage rating: A
src/core/classes/Iterable.ts100.0%
Coverage rating: A Coverage rating: A
src/core/classes/IterableAttributionInfo.ts94.1%78
New Coverage rating: A
src/api/bridge.ts100.0%
Total95.1%
🤖 Increase coverage with AI coding...
In the `upgrade/SDK-484-remove-legacy-architecture-code` branch, add test coverage for this new code:

- `src/api/index.ts` -- Line 5
- `src/core/classes/IterableAttributionInfo.ts` -- Line 78

🚦 See full report on Qlty Cloud »

🛟 Help
  • Diff Coverage: Coverage for added or modified lines of code (excludes deleted files). Learn more.

  • Total Coverage: Coverage for the whole repository, calculated as the sum of all File Coverage. Learn more.

  • File Coverage: Covered Lines divided by Covered Lines plus Missed Lines. (Excludes non-executable lines including blank lines and comments.)

    • Indirect Changes: Changes to File Coverage for files that were not modified in this PR. Learn more.

@qltysh
Copy link
Copy Markdown

qltysh Bot commented May 20, 2026

6 new issues

Tool Category Rule Count
qlty Structure Function with many parameters (count = 4): initializeWithApiKey 5
qlty Structure Function with many returns (count = 4): parseToBridge 1

campaignId: Number(campaignId),
templateId: Number(templateId),
messageId: String(messageId),
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function with many returns (count = 4): parseToBridge [qlty:return-statements]

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes Legacy Architecture support across the React Native SDK, standardizing on the New Architecture (TurboModules) and updating JS/native boundaries, tests, and documentation accordingly.

Changes:

  • Remove legacy/native-module fallbacks and old-arch Android/iOS implementations; require TurboModules.
  • Introduce bridge-casting helpers and expand attribution info normalization/serialization for native calls.
  • Update Jest setup/mocks and adjust tests + docs/changelog to reflect the breaking change.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/core/classes/IterableAttributionInfo.ts Adds bridge serialization/coercion helpers for attribution info.
src/core/classes/IterableApi.ts Routes calls through TurboModule-friendly shapes/casts; updates attribution and bridge payload handling.
src/core/classes/IterableApi.test.ts Adds/updates tests for attribution bridge coercion + serialization expectations.
src/core/classes/Iterable.ts Aligns public API attribution methods with the updated IterableApi layer.
src/api/NativeRNIterableAPI.ts Removes test-environment bypass; always enforces TurboModule presence.
src/api/index.ts Drops NativeModules fallback; exports a typed TurboModule instance.
src/api/bridge.ts Adds shared “bridge record” cast helpers for TurboModule calls.
src/mocks/jest.setup.ts Switches to mocking the SDK’s src/api module instead of NativeModules.RNIterableAPI.
README.md Updates architecture support section to require New Architecture.
package.json Updates library template type to module (non-legacy).
ios/RNIterableAPI/RNIterableAPI.mm Removes legacy bridge module exports; keeps TurboModule implementation unconditionally.
ios/RNIterableAPI/RNIterableAPI.h Removes legacy interface conditional; always conforms to NativeRNIterableAPISpec.
example/src/NativeJwtTokenModule.ts Removes old-arch NativeModules fallback; uses TurboModuleRegistry only.
CHANGELOG.md Adds 3.0.0 breaking-change note for legacy architecture removal.
android/src/oldarch/java/com/RNIterableAPIModule.java Deletes old architecture module implementation.
android/src/main/java/com/iterable/reactnative/RNIterableAPIPackage.java Marks module as TurboModule unconditionally.
android/src/main/java/com/iterable/reactnative/RNIterableAPIModule.java Cleans imports; continues TurboModule-based module class.
android/build.gradle Always applies React plugin; removes old/new arch source set switching and related BuildConfig flag.
Comments suppressed due to low confidence (4)

src/core/classes/IterableApi.ts:218

  • trackPushOpenWithCampaignId is being invoked via a type-cast that allows messageId to be null | undefined, but both the TurboModule spec (src/api/NativeRNIterableAPI.ts) and the native implementations require a non-null string messageId. Passing null/undefined here is likely to cause a TurboModule argument validation error or a native crash. Align the JS signature with native (require messageId: string), or explicitly handle the nullable case before calling into the native module (and update the native spec/implementations if null must be supported).
    return (RNIterableAPI.trackPushOpenWithCampaignId as (
      campaignId: number,
      templateId: number,
      messageId: string | null | undefined,
      appAlreadyRunning: boolean,

src/core/classes/IterableApi.ts:382

  • passAlongAuthToken is typed/implemented as returning a Promise<IterableAuthResponse | string | undefined>, but the TurboModule spec and native implementations are void (they signal auth via events). As written, this will always resolve undefined in production, which is a misleading public API and can hide integration bugs. Either update the native method to actually return a promise, or change this wrapper (and IterableAuthManager) to return void/Promise<void> and remove the runtime "then" detection.
  static passAlongAuthToken(
    authToken: string | null | undefined
  ): Promise<IterableAuthResponse | string | undefined> {
    IterableLogger.log('passAlongAuthToken: ', authToken);
    const result = RNIterableAPI.passAlongAuthToken(authToken) as unknown;

src/core/classes/IterableApi.ts:504

  • getHtmlInAppContentForMessage is returning the native payload with a double-cast to Promise<IterableHtmlInAppContent>, but the TurboModule spec returns a plain object and other call sites (e.g. inbox data model) treat it as a raw dictionary to be parsed via IterableHtmlInAppContent.fromDict. This cast makes the method’s return type inaccurate and can introduce type errors under strict. Prefer either: (1) parse here and return a real IterableHtmlInAppContent instance, or (2) change the return type to the raw bridge type and let callers parse.
  static getHtmlInAppContentForMessage(
    messageId: string
  ): Promise<IterableHtmlInAppContent> {
    IterableLogger.log('getHtmlInAppContentForMessage: ', messageId);
    return RNIterableAPI.getHtmlInAppContentForMessage(messageId) as unknown as Promise<IterableHtmlInAppContent>;

src/core/classes/IterableApi.ts:602

  • getEmbeddedMessages casts placementIds from number[] | null to number[] and forwards it to the TurboModule. If null is passed at runtime, this defeats the non-nullable TurboModule signature and may fail argument validation. Since the native implementations treat nil/null or an empty list as “all placements”, normalize here (e.g. convert null to []) instead of casting.
  ): Promise<IterableEmbeddedMessage[]> {
    IterableLogger.log('getEmbeddedMessages: ', placementIds);
    return RNIterableAPI.getEmbeddedMessages(
      placementIds as number[]
    ) as Promise<IterableEmbeddedMessage[]>;

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +171 to +174
return (RNIterableAPI.updateEmail as (
email: string,
authToken?: string | null
) => void)(email, authToken);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants