@@ -108,11 +108,30 @@ pub fn is_hyprnote_cloud_host(base_url: &str) -> bool {
108108 host_matches ( base_url, |h| h. contains ( "hyprnote.com" ) )
109109}
110110
111- pub fn append_provider_param ( base_url : & str , provider : & str ) -> String {
112- if !is_hyprnote_cloud_host ( base_url) {
113- return base_url. to_string ( ) ;
111+ pub fn build_proxy_ws_url ( api_base : & str ) -> Option < ( url:: Url , Vec < ( String , String ) > ) > {
112+ const PROXY_PATH : & str = "/listen" ;
113+
114+ if api_base. is_empty ( ) {
115+ return None ;
114116 }
115117
118+ let parsed: url:: Url = api_base. parse ( ) . ok ( ) ?;
119+ let host = parsed. host_str ( ) ?;
120+
121+ if !host. contains ( "hyprnote.com" ) && !is_local_host ( host) {
122+ return None ;
123+ }
124+
125+ let existing_params = extract_query_params ( & parsed) ;
126+ let mut url = parsed;
127+ url. set_query ( None ) ;
128+ url. set_path ( PROXY_PATH ) ;
129+ set_scheme_from_host ( & mut url) ;
130+
131+ Some ( ( url, existing_params) )
132+ }
133+
134+ pub fn append_provider_param ( base_url : & str , provider : & str ) -> String {
116135 match url:: Url :: parse ( base_url) {
117136 Ok ( mut url) => {
118137 url. query_pairs_mut ( ) . append_pair ( "provider" , provider) ;
@@ -152,3 +171,80 @@ impl AdapterKind {
152171 }
153172 }
154173}
174+
175+ #[ cfg( test) ]
176+ mod tests {
177+ use super :: * ;
178+
179+ #[ test]
180+ fn test_build_proxy_ws_url ( ) {
181+ let cases: & [ ( & str , Option < ( & str , Vec < ( & str , & str ) > ) > ) ] = & [
182+ ( "" , None ) ,
183+ ( "https://api.deepgram.com" , None ) ,
184+ ( "https://api.soniox.com" , None ) ,
185+ ( "https://api.fireworks.ai" , None ) ,
186+ ( "https://api.assemblyai.com" , None ) ,
187+ (
188+ "https://api.hyprnote.com?provider=soniox" ,
189+ Some ( (
190+ "wss://api.hyprnote.com/listen" ,
191+ vec ! [ ( "provider" , "soniox" ) ] ,
192+ ) ) ,
193+ ) ,
194+ (
195+ "https://api.hyprnote.com/listen?provider=deepgram" ,
196+ Some ( (
197+ "wss://api.hyprnote.com/listen" ,
198+ vec ! [ ( "provider" , "deepgram" ) ] ,
199+ ) ) ,
200+ ) ,
201+ (
202+ "https://api.hyprnote.com/some/path?provider=fireworks" ,
203+ Some ( (
204+ "wss://api.hyprnote.com/listen" ,
205+ vec ! [ ( "provider" , "fireworks" ) ] ,
206+ ) ) ,
207+ ) ,
208+ (
209+ "http://localhost:8787?provider=soniox" ,
210+ Some ( ( "ws://localhost:8787/listen" , vec ! [ ( "provider" , "soniox" ) ] ) ) ,
211+ ) ,
212+ (
213+ "http://localhost:8787/listen?provider=deepgram" ,
214+ Some ( ( "ws://localhost:8787/listen" , vec ! [ ( "provider" , "deepgram" ) ] ) ) ,
215+ ) ,
216+ (
217+ "http://127.0.0.1:8787?provider=assemblyai" ,
218+ Some ( (
219+ "ws://127.0.0.1:8787/listen" ,
220+ vec ! [ ( "provider" , "assemblyai" ) ] ,
221+ ) ) ,
222+ ) ,
223+ ] ;
224+
225+ for ( input, expected) in cases {
226+ let result = build_proxy_ws_url ( input) ;
227+ match ( result, expected) {
228+ ( None , None ) => { }
229+ ( Some ( ( url, params) ) , Some ( ( expected_url, expected_params) ) ) => {
230+ assert_eq ! ( url. as_str( ) , * expected_url, "input: {}" , input) ;
231+ assert_eq ! (
232+ params,
233+ expected_params
234+ . iter( )
235+ . map( |( k, v) | ( k. to_string( ) , v. to_string( ) ) )
236+ . collect:: <Vec <_>>( ) ,
237+ "input: {}" ,
238+ input
239+ ) ;
240+ }
241+ ( result, expected) => {
242+ panic ! (
243+ "input: {}, expected: {:?}, got: {:?}" ,
244+ input, expected, result
245+ ) ;
246+ }
247+ }
248+ }
249+ }
250+ }
0 commit comments