@@ -43,6 +43,82 @@ function buildCurlCommand(method, url, headers, body, isWindows) {
4343 return curlCmd ;
4444}
4545
46+ function showCopiedTooltip ( btn ) {
47+ const tooltip = document . createElement ( "div" ) ;
48+ tooltip . className = "copied-tooltip" ;
49+ tooltip . textContent = "Copied!" ;
50+ document . body . appendChild ( tooltip ) ;
51+
52+ const rect = btn . getBoundingClientRect ( ) ;
53+ tooltip . style . left = ( rect . left + window . scrollX + rect . width / 2 ) + "px" ;
54+ tooltip . style . top = ( rect . top + window . scrollY ) + "px" ;
55+
56+ setTimeout ( ( ) => {
57+ tooltip . remove ( ) ;
58+ } , 1500 ) ;
59+ }
60+
61+ function escapeCSharpString ( str ) {
62+ if ( ! str ) return "" ;
63+ return str
64+ . replace ( / \\ / g, "\\\\" )
65+ . replace ( / " / g, '\\"' )
66+ . replace ( / \r / g, '\\r' )
67+ . replace ( / \n / g, '\\n' ) ;
68+ }
69+
70+ function buildCSharpSnippet ( method , url , headers , body ) {
71+ const escapedUrl = escapeCSharpString ( url ) ;
72+ const methodFormatted = method . charAt ( 0 ) . toUpperCase ( ) + method . slice ( 1 ) . toLowerCase ( ) ;
73+ let snippet = `var request = new HttpRequestMessage(HttpMethod.${ methodFormatted } , "${ escapedUrl } ");\n` ;
74+
75+ for ( const [ key , value ] of Object . entries ( headers ) ) {
76+ if ( ! key || ! value ) continue ;
77+ const trimmedVal = value . trim ( ) ;
78+ if ( trimmedVal === "[REDACTED]" || trimmedVal === "" ) continue ;
79+
80+ snippet += `request.Headers.Add("${ escapeCSharpString ( key ) } ", "${ escapeCSharpString ( value ) } ");\n` ;
81+ }
82+
83+ if ( body && body . trim ( ) !== "" && body !== "[Body too large]" ) {
84+ let contentType = "application/json" ;
85+ for ( const [ key , value ] of Object . entries ( headers ) ) {
86+ if ( key . toLowerCase ( ) === "content-type" && value && value . trim ( ) !== "" && value . trim ( ) !== "[REDACTED]" ) {
87+ contentType = value . split ( ";" ) [ 0 ] . trim ( ) ;
88+ break ;
89+ }
90+ }
91+ snippet += `request.Content = new StringContent("${ escapeCSharpString ( body ) } ", Encoding.UTF8, "${ escapeCSharpString ( contentType ) } ");\n` ;
92+ }
93+
94+ snippet += `var response = await httpClient.SendAsync(request);` ;
95+ return snippet ;
96+ }
97+
98+ function copyAsCSharp ( btn ) {
99+ const card = btn . closest ( ".trace-card" ) ;
100+ if ( ! card ) return ;
101+
102+ const method = card . dataset . method ;
103+ const url = card . dataset . url ;
104+ if ( ! method || ! url ) return ;
105+
106+ let headers = { } ;
107+ try {
108+ headers = JSON . parse ( card . dataset . headers || '{}' ) ;
109+ } catch ( e ) {
110+ // Fallback or ignore
111+ }
112+
113+ const body = card . dataset . body ;
114+
115+ const snippet = buildCSharpSnippet ( method , url , headers , body ) ;
116+
117+ navigator . clipboard . writeText ( snippet ) ;
118+
119+ showCopiedTooltip ( btn ) ;
120+ }
121+
46122function copyAsCurl ( btn ) {
47123 const card = btn . closest ( ".trace-card" ) ;
48124 if ( ! card ) return ;
@@ -67,19 +143,7 @@ function copyAsCurl(btn) {
67143
68144 navigator . clipboard . writeText ( curlCmd ) ;
69145
70- // Show temporary "Copied!" tooltip
71- const tooltip = document . createElement ( "div" ) ;
72- tooltip . className = "copied-tooltip" ;
73- tooltip . textContent = "Copied!" ;
74- document . body . appendChild ( tooltip ) ;
75-
76- const rect = btn . getBoundingClientRect ( ) ;
77- tooltip . style . left = ( rect . left + window . scrollX + rect . width / 2 ) + "px" ;
78- tooltip . style . top = ( rect . top + window . scrollY ) + "px" ;
79-
80- setTimeout ( ( ) => {
81- tooltip . remove ( ) ;
82- } , 1500 ) ;
146+ showCopiedTooltip ( btn ) ;
83147}
84148
85149
0 commit comments