@@ -6,17 +6,16 @@ const log = logger.scope("deep-link-service");
66
77const PROTOCOL = "array" ;
88
9- export type DeepLinkHandler = ( url : URL ) => boolean ;
9+ export type DeepLinkHandler = (
10+ path : string ,
11+ searchParams : URLSearchParams ,
12+ ) => boolean ;
1013
1114@injectable ( )
1215export class DeepLinkService {
1316 private protocolRegistered = false ;
1417 private handlers = new Map < string , DeepLinkHandler > ( ) ;
1518
16- /**
17- * Register the app as the default handler for the 'array' protocol.
18- * Should be called once during app initialization (in whenReady).
19- */
2019 public registerProtocol ( ) : void {
2120 if ( this . protocolRegistered ) {
2221 return ;
@@ -39,30 +38,22 @@ export class DeepLinkService {
3938 log . info ( `Registered '${ PROTOCOL } ' protocol handler` ) ;
4039 }
4140
42- /**
43- * Register a handler for a specific deep link path.
44- * @param path The path to handle (e.g., "callback", "task", "settings")
45- * @param handler Function that receives the parsed URL and returns true if handled
46- */
47- public registerHandler ( path : string , handler : DeepLinkHandler ) : void {
48- if ( this . handlers . has ( path ) ) {
49- log . warn ( `Overwriting existing handler for path: ${ path } ` ) ;
41+ public registerHandler ( key : string , handler : DeepLinkHandler ) : void {
42+ if ( this . handlers . has ( key ) ) {
43+ log . warn ( `Overwriting existing handler for key: ${ key } ` ) ;
5044 }
51- this . handlers . set ( path , handler ) ;
52- log . info ( `Registered deep link handler for path : ${ path } ` ) ;
45+ this . handlers . set ( key , handler ) ;
46+ log . info ( `Registered deep link handler for key : ${ key } ` ) ;
5347 }
5448
55- /**
56- * Unregister a handler for a specific path.
57- */
58- public unregisterHandler ( path : string ) : void {
59- this . handlers . delete ( path ) ;
49+ public unregisterHandler ( key : string ) : void {
50+ this . handlers . delete ( key ) ;
6051 }
6152
6253 /**
63- * Handle an incoming deep link URL.
64- * Routes to the appropriate registered handler based on the URL path.
65- * @returns true if the URL was handled, false otherwise
54+ * Handle an incoming deep link URL
55+ *
56+ * NOTE: Strips the protocol and main key, passing only dynamic segments to handlers.
6657 */
6758 public handleUrl ( url : string ) : boolean {
6859 log . info ( "Received deep link:" , url ) ;
@@ -75,36 +66,33 @@ export class DeepLinkService {
7566 try {
7667 const parsedUrl = new URL ( url ) ;
7768
78- // The "path" can be the hostname (array://callback) or pathname (array://foo/callback)
79- // For simple paths like array://callback, hostname is "callback" and pathname is "/"
80- // For paths like array://oauth/callback, hostname is "oauth" and pathname is "/callback"
81- const path = parsedUrl . hostname || parsedUrl . pathname . slice ( 1 ) ;
69+ // The hostname is the main key (e.g., "task" in array://task/...)
70+ const mainKey = parsedUrl . hostname ;
8271
83- const handler = this . handlers . get ( path ) ;
84- if ( handler ) {
85- return handler ( parsedUrl ) ;
72+ if ( ! mainKey ) {
73+ log . warn ( "Deep link has no main key:" , url ) ;
74+ return false ;
8675 }
8776
88- // Try matching with pathname for nested paths like array://oauth/callback
89- if ( parsedUrl . pathname !== "/" ) {
90- const fullPath = `${ parsedUrl . hostname } ${ parsedUrl . pathname } ` ;
91- const nestedHandler = this . handlers . get ( fullPath ) ;
92- if ( nestedHandler ) {
93- return nestedHandler ( parsedUrl ) ;
94- }
77+ const handler = this . handlers . get ( mainKey ) ;
78+ if ( ! handler ) {
79+ log . warn ( "No handler registered for deep link key:" , mainKey ) ;
80+ return false ;
9581 }
9682
97- log . warn ( "No handler registered for deep link path:" , path ) ;
98- return false ;
83+ // Extract path segments after the main key (strip leading slash)
84+ const pathSegments = parsedUrl . pathname . slice ( 1 ) ;
85+
86+ log . info (
87+ `Routing deep link to '${ mainKey } ' handler with path: ${ pathSegments || "(empty)" } ` ,
88+ ) ;
89+ return handler ( pathSegments , parsedUrl . searchParams ) ;
9990 } catch ( error ) {
10091 log . error ( "Failed to parse deep link URL:" , error ) ;
10192 return false ;
10293 }
10394 }
10495
105- /**
106- * Get the protocol name.
107- */
10896 public getProtocol ( ) : string {
10997 return PROTOCOL ;
11098 }
0 commit comments