-
Notifications
You must be signed in to change notification settings - Fork 65
feat: add deep link support for Jio Hotstar platforms including new types, utilities, and demo examples. #80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…ypes, utilities, and demo examples.
📝 WalkthroughWalkthroughAdds Jio Hotstar deep-link support via a new Changes
Sequence Diagram(s)(Skipped — changes add a handler and a registry export; control flow remains straightforward.) Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In @apps/demo/index.html:
- Around line 104-112: The icon filename in the Jio Hotstar link is camelCase;
update the img src in the anchor with class "jio-hotstar-link" (the <span
class="link-icon"> image) to use the lowercase filename '/icons/jiohotstar.svg'
instead of '/icons/jioHotstar.svg' so it matches the other platform icon
filenames.
In @packages/core/README.md:
- Around line 195-201: Documentation and implementation diverge: the jioHotstar
handler (used by generateDeepLink) emits iOS links as
hotstar://content/${contentId} while README shows hotstar://${contentId}; either
update the README example to include the "content/" segment or change the
jioHotstar handler to build hotstar://${contentId} instead (modify the code path
inside the jioHotstar handler used by generateDeepLink), and add unit tests for
the jioHotstar handler/generateDeepLink to assert both iOS and Android outputs
match the chosen canonical format.
In @packages/core/src/platforms/jioHotstar.ts:
- Around line 5-8: The complex inline regex used in the match function should be
extracted to a named constant (e.g., JIO_HOTSTAR_URL_REGEX) and documented:
create a top-level constant string or RegExp with an end anchor ($), add a
comment block that explains the full URL structure, shows example URLs for each
variant (with and without the optional middle segment), and explicitly states
which capture group corresponds to contentId (group 1) vs videoId (group 2) and
when group 2 is present (e.g., nested episode/video paths like
/show/.../season/.../episodeId or /movie/.../watch/videoId). Replace the inline
literal in match with getUrlWithoutProtocol(url).match(JIO_HOTSTAR_URL_REGEX)
and ensure the regex includes the final $ to avoid matching extra trailing
segments.
In @packages/core/src/types.ts:
- Line 16: Change the platform literal 'jioHotstar' to lowercase 'jiohotstar' in
the union type declaration in types.ts and update every related reference: the
handler implementation that checks or returns this platform value, any platform
detection/comparison logic, the demo HTML class/icon names, and documentation
examples so they all use 'jiohotstar' consistently.
🧹 Nitpick comments (1)
packages/core/src/utils.ts (1)
36-37: Add input validation and documentation to the utility function.The
getUrlWithoutProtocolfunction is now shared across multiple platform handlers (twitch, jioHotstar) but lacks input validation and documentation:
Missing input validation: The function doesn't handle
null,undefined, or empty string inputs, which could cause runtime errors in consuming handlers.No documentation: Add JSDoc comments explaining:
- The function's purpose
- Expected input format
- Return value format
- Example usage
Edge case consideration: While the current implementation handles typical HTTP/HTTPS URLs well, consider whether edge cases (e.g., URLs with unusual subdomains like "www.www.example.com") need explicit handling or documentation.
🛡️ Proposed improvements
+/** + * Strips the protocol (http/https) and leading 'www.' from a URL string. + * + * @param url - The URL string to process (e.g., "https://www.example.com") + * @returns The URL without protocol and www prefix (e.g., "example.com") + * + * @example + * getUrlWithoutProtocol("https://www.example.com") // returns "example.com" + * getUrlWithoutProtocol("http://example.com") // returns "example.com" + */ -export const getUrlWithoutProtocol = (url: string) => - url.replace(/^https?:\/\//, '').replace(/^www\./, ''); +export const getUrlWithoutProtocol = (url: string): string => { + if (!url || typeof url !== 'string') { + return ''; + } + return url.replace(/^https?:\/\//, '').replace(/^www\./, ''); +};
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
apps/demo/public/icons/jioHotstar.svgis excluded by!**/*.svg
📒 Files selected for processing (8)
apps/demo/index.htmlpackages/core/README.mdpackages/core/src/index.tspackages/core/src/platforms/index.tspackages/core/src/platforms/jioHotstar.tspackages/core/src/platforms/twitch.tspackages/core/src/types.tspackages/core/src/utils.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2026-01-02T21:27:30.363Z
Learnt from: tanmoyPaul12
Repo: mdsaban/universal-app-opener PR: 0
File: :0-0
Timestamp: 2026-01-02T21:27:30.363Z
Learning: In the mdsaban/universal-app-opener repository, the Platform type in packages/core/src/types.ts already includes 'github' and 'twitch' platforms in the main branch.
Applied to files:
packages/core/src/platforms/twitch.tspackages/core/src/types.tspackages/core/src/index.tspackages/core/src/platforms/index.ts
🧬 Code graph analysis (2)
packages/core/src/platforms/jioHotstar.ts (3)
packages/core/src/platforms/index.ts (1)
jioHotstarHandler(24-24)packages/core/src/types.ts (1)
DeepLinkHandler(31-48)packages/core/src/utils.ts (1)
getUrlWithoutProtocol(36-37)
packages/core/src/platforms/index.ts (2)
packages/core/src/types.ts (1)
DeepLinkHandler(31-48)packages/core/src/platforms/jioHotstar.ts (1)
jioHotstarHandler(4-30)
🔇 Additional comments (8)
packages/core/README.md (2)
186-193: Twitch Android deep link update aligns with code changes.The removal of
browser_fallback_urlfrom the Twitch Android intent example correctly reflects the refactored implementation inpackages/core/src/platforms/twitch.ts.
203-210: Good addition of the Unknown URL section.Documenting the behavior for unrecognized URLs helps set clear expectations for library users.
packages/core/src/platforms/twitch.ts (2)
2-2: Good refactoring to use shared utility.Moving the URL protocol/www stripping logic to a shared utility function (
getUrlWithoutProtocol) eliminates code duplication and improves maintainability.
50-50: Ensure timeout-based fallback is acceptable for Android users without the Twitch app.The Android intent URL lacks the
browser_fallback_urlparameter, unlike other platforms (LinkedIn, Pinterest, Snapchat). Fallback handling is delegated toopenLink()inpackages/core/src/index.ts, which implements a JavaScript timeout-based approach: if the deep link doesn't open the app within 2500ms (default), it falls back to the web URL.This differs from OS-level immediate fallback (
browser_fallback_url). Verify that the 2500ms delay is acceptable for the user experience when the Twitch app is not installed, and consider whether platform consistency (usingbrowser_fallback_urllike other apps) would be preferable.packages/core/src/index.ts (1)
1-1: LGTM! Clean refactoring to centralize handler management.The change to import the handlers array from
./platformsinstead of constructing it locally improves maintainability and follows good separation of concerns.Also applies to: 10-10
packages/core/src/platforms/jioHotstar.ts (2)
1-2: LGTM! Imports are correct.The necessary types and utilities are properly imported and used throughout the handler.
10-29: Thehotstar://URI scheme could not be verified in public documentation and may need validation.
The iOS deep link scheme
hotstar://content/{id}has no public documentation. Sources indicate Hotstar primarily uses App Links (HTTPS URLs) for deep linking. Recommend verifying this scheme works by testing with the native app or checking Hotstar's official technical documentation.The Android package name
in.startv.hotstarand intent format are correct.The
contentId/videoIdbehavior is sound—the regex makesvideoId(match[2]) optional whilecontentId(match[1]) is always captured; the code correctly prioritizesvideoIdwhen present.Input validation: The regex character class
[a-zA-Z0-9_-]+prevents empty strings, so additional validation for captured IDs is not critical.packages/core/src/platforms/index.ts (1)
1-1: LGTM! Handler registration follows the established pattern.The changes correctly:
- Import and export the new
jioHotstarHandler- Include it in the
handlersarray at the appropriate alphabetical position- Maintain separation between the handlers array and
unknownHandler(which serves as the fallback)The implementation is consistent with the existing platform handler architecture.
Also applies to: 6-6, 19-36, 38-54
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
packages/core/src/platforms/jioHotstar.ts (2)
24-30: Consider prefixing unused variable with underscore.The
typevariable is destructured from the PATTERNS tuple but never used. If it's intentionally unused, prefix it with an underscore to indicate this:[_type, pattern].♻️ Proposed refactor
- for (const [type, pattern] of PATTERNS) { + for (const [_type, pattern] of PATTERNS) { const match = urlWithoutProtocol.match(pattern); if (match) return match; }
35-54: Consider refactoring to reduce code duplication.Both the
videoIdandcontentIdbranches construct nearly identical deep link objects. Extract the ID selection logic to reduce duplication and improve maintainability.♻️ Proposed refactor
build: (webUrl, match) => { const contentId = match[1]; const videoId = match[2]; + const id = videoId || contentId; - if (videoId) { - return { - webUrl, - ios: `hotstar://content/${videoId}`, - android: `intent://${videoId}#Intent;scheme=hotstar;package=in.startv.hotstar;end`, - platform: 'jiohotstar', - }; - } - return { webUrl, - ios: `hotstar://content/${contentId}`, - android: `intent://${contentId}#Intent;scheme=hotstar;package=in.startv.hotstar;end`, + ios: `hotstar://content/${id}`, + android: `intent://${id}#Intent;scheme=hotstar;package=in.startv.hotstar;end`, platform: 'jiohotstar', }; },
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/core/src/platforms/jioHotstar.ts
🧰 Additional context used
🧬 Code graph analysis (1)
packages/core/src/platforms/jioHotstar.ts (3)
packages/core/src/platforms/index.ts (1)
jioHotstarHandler(26-26)packages/core/src/types.ts (1)
DeepLinkHandler(33-50)packages/core/src/utils.ts (1)
getUrlWithoutProtocol(36-37)
🔇 Additional comments (2)
packages/core/src/platforms/jioHotstar.ts (2)
1-2: LGTM!The imports are appropriate and used correctly throughout the file.
4-21: LGTM!The pattern definitions are well-documented and correctly match the intended URL structures. The extraction of patterns to a named constant and the addition of comprehensive comments address the previous review feedback effectively.
Pull Request: Add JioHotstar Deep Link Support
🎯 Summary
Adds
jiohotstarHandlerto convert JioHotstar web URLs to native app deep links, following the established Spotify/Netflix pattern.📋 Changes
New Handler:
jiohotstarHandlerSupported patterns:
Closes #69
Summary by CodeRabbit
New Features
Improvements
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.