@rekog/mcp-nest 1.5.0 → 1.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/.github/workflows/pipeline.yml +11 -1
  2. package/README.md +28 -42
  3. package/coverage/clover.xml +324 -325
  4. package/coverage/coverage-final.json +20 -20
  5. package/coverage/lcov-report/decorators/constants.ts.html +4 -4
  6. package/coverage/lcov-report/decorators/index.html +1 -1
  7. package/coverage/lcov-report/decorators/index.ts.html +5 -5
  8. package/coverage/lcov-report/decorators/prompt.decorator.ts.html +4 -4
  9. package/coverage/lcov-report/decorators/resource.decorator.ts.html +4 -4
  10. package/coverage/lcov-report/decorators/tool.decorator.ts.html +5 -5
  11. package/coverage/lcov-report/index.html +37 -37
  12. package/coverage/lcov-report/services/index.html +9 -39
  13. package/coverage/lcov-report/services/mcp-registry.service.ts.html +6 -6
  14. package/coverage/lcov-report/tests/index.html +21 -21
  15. package/coverage/lcov-report/tests/utils.ts.html +45 -45
  16. package/coverage/lcov.info +446 -449
  17. package/dist/interfaces/mcp-tool.interface.d.ts +7 -1
  18. package/dist/interfaces/mcp-tool.interface.d.ts.map +1 -1
  19. package/dist/services/handlers/mcp-handler.base.d.ts +3 -5
  20. package/dist/services/handlers/mcp-handler.base.d.ts.map +1 -1
  21. package/dist/services/handlers/mcp-handler.base.js +6 -2
  22. package/dist/services/handlers/mcp-handler.base.js.map +1 -1
  23. package/dist/transport/streamable-http.controller.factory.js +2 -2
  24. package/dist/transport/streamable-http.controller.factory.js.map +1 -1
  25. package/package.json +5 -3
  26. package/playground/resources/greeting.tool.ts +4 -3
  27. package/tests/mcp-tool.e2e.spec.ts +74 -10
  28. package/tsconfig.build.tsbuildinfo +1 -1
  29. package/coverage/lcov-report/services/handlers/index.html +0 -161
  30. package/coverage/lcov-report/services/handlers/mcp-handler.base.ts.html +0 -421
  31. package/coverage/lcov-report/services/handlers/mcp-prompts.handler.ts.html +0 -385
  32. package/coverage/lcov-report/services/handlers/mcp-resources.handler.ts.html +0 -361
  33. package/coverage/lcov-report/services/handlers/mcp-tools.handler.ts.html +0 -355
  34. package/coverage/lcov-report/services/mcp-executor.service.ts.html +0 -199
  35. package/coverage/lcov-report/services/sse-ping.service.ts.html +0 -499
  36. package/coverage/lcov-report/transport/index.html +0 -131
  37. package/coverage/lcov-report/transport/sse.controller.factory.ts.html +0 -532
  38. package/coverage/lcov-report/transport/streamable-http.controller.factory.ts.html +0 -1258
@@ -1,1258 +0,0 @@
1
-
2
- <!doctype html>
3
- <html lang="en">
4
-
5
- <head>
6
- <title>Code coverage report for transport/streamable-http.controller.factory.ts</title>
7
- <meta charset="utf-8" />
8
- <link rel="stylesheet" href="../prettify.css" />
9
- <link rel="stylesheet" href="../base.css" />
10
- <link rel="shortcut icon" type="image/x-icon" href="../favicon.png" />
11
- <meta name="viewport" content="width=device-width, initial-scale=1" />
12
- <style type='text/css'>
13
- .coverage-summary .sorter {
14
- background-image: url(../sort-arrow-sprite.png);
15
- }
16
- </style>
17
- </head>
18
-
19
- <body>
20
- <div class='wrapper'>
21
- <div class='pad1'>
22
- <h1><a href="../index.html">All files</a> / <a href="index.html">transport</a> streamable-http.controller.factory.ts</h1>
23
- <div class='clearfix'>
24
-
25
- <div class='fl pad1y space-right2'>
26
- <span class="strong">11.96% </span>
27
- <span class="quiet">Statements</span>
28
- <span class='fraction'>14/117</span>
29
- </div>
30
-
31
-
32
- <div class='fl pad1y space-right2'>
33
- <span class="strong">3.33% </span>
34
- <span class="quiet">Branches</span>
35
- <span class='fraction'>2/60</span>
36
- </div>
37
-
38
-
39
- <div class='fl pad1y space-right2'>
40
- <span class="strong">5.88% </span>
41
- <span class="quiet">Functions</span>
42
- <span class='fraction'>1/17</span>
43
- </div>
44
-
45
-
46
- <div class='fl pad1y space-right2'>
47
- <span class="strong">11.2% </span>
48
- <span class="quiet">Lines</span>
49
- <span class='fraction'>13/116</span>
50
- </div>
51
-
52
-
53
- </div>
54
- <p class="quiet">
55
- Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
- </p>
57
- <template id="filterTemplate">
58
- <div class="quiet">
59
- Filter:
60
- <input type="search" id="fileSearch">
61
- </div>
62
- </template>
63
- </div>
64
- <div class='status-line low'></div>
65
- <pre><table class="coverage">
66
- <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
- <a name='L2'></a><a href='#L2'>2</a>
68
- <a name='L3'></a><a href='#L3'>3</a>
69
- <a name='L4'></a><a href='#L4'>4</a>
70
- <a name='L5'></a><a href='#L5'>5</a>
71
- <a name='L6'></a><a href='#L6'>6</a>
72
- <a name='L7'></a><a href='#L7'>7</a>
73
- <a name='L8'></a><a href='#L8'>8</a>
74
- <a name='L9'></a><a href='#L9'>9</a>
75
- <a name='L10'></a><a href='#L10'>10</a>
76
- <a name='L11'></a><a href='#L11'>11</a>
77
- <a name='L12'></a><a href='#L12'>12</a>
78
- <a name='L13'></a><a href='#L13'>13</a>
79
- <a name='L14'></a><a href='#L14'>14</a>
80
- <a name='L15'></a><a href='#L15'>15</a>
81
- <a name='L16'></a><a href='#L16'>16</a>
82
- <a name='L17'></a><a href='#L17'>17</a>
83
- <a name='L18'></a><a href='#L18'>18</a>
84
- <a name='L19'></a><a href='#L19'>19</a>
85
- <a name='L20'></a><a href='#L20'>20</a>
86
- <a name='L21'></a><a href='#L21'>21</a>
87
- <a name='L22'></a><a href='#L22'>22</a>
88
- <a name='L23'></a><a href='#L23'>23</a>
89
- <a name='L24'></a><a href='#L24'>24</a>
90
- <a name='L25'></a><a href='#L25'>25</a>
91
- <a name='L26'></a><a href='#L26'>26</a>
92
- <a name='L27'></a><a href='#L27'>27</a>
93
- <a name='L28'></a><a href='#L28'>28</a>
94
- <a name='L29'></a><a href='#L29'>29</a>
95
- <a name='L30'></a><a href='#L30'>30</a>
96
- <a name='L31'></a><a href='#L31'>31</a>
97
- <a name='L32'></a><a href='#L32'>32</a>
98
- <a name='L33'></a><a href='#L33'>33</a>
99
- <a name='L34'></a><a href='#L34'>34</a>
100
- <a name='L35'></a><a href='#L35'>35</a>
101
- <a name='L36'></a><a href='#L36'>36</a>
102
- <a name='L37'></a><a href='#L37'>37</a>
103
- <a name='L38'></a><a href='#L38'>38</a>
104
- <a name='L39'></a><a href='#L39'>39</a>
105
- <a name='L40'></a><a href='#L40'>40</a>
106
- <a name='L41'></a><a href='#L41'>41</a>
107
- <a name='L42'></a><a href='#L42'>42</a>
108
- <a name='L43'></a><a href='#L43'>43</a>
109
- <a name='L44'></a><a href='#L44'>44</a>
110
- <a name='L45'></a><a href='#L45'>45</a>
111
- <a name='L46'></a><a href='#L46'>46</a>
112
- <a name='L47'></a><a href='#L47'>47</a>
113
- <a name='L48'></a><a href='#L48'>48</a>
114
- <a name='L49'></a><a href='#L49'>49</a>
115
- <a name='L50'></a><a href='#L50'>50</a>
116
- <a name='L51'></a><a href='#L51'>51</a>
117
- <a name='L52'></a><a href='#L52'>52</a>
118
- <a name='L53'></a><a href='#L53'>53</a>
119
- <a name='L54'></a><a href='#L54'>54</a>
120
- <a name='L55'></a><a href='#L55'>55</a>
121
- <a name='L56'></a><a href='#L56'>56</a>
122
- <a name='L57'></a><a href='#L57'>57</a>
123
- <a name='L58'></a><a href='#L58'>58</a>
124
- <a name='L59'></a><a href='#L59'>59</a>
125
- <a name='L60'></a><a href='#L60'>60</a>
126
- <a name='L61'></a><a href='#L61'>61</a>
127
- <a name='L62'></a><a href='#L62'>62</a>
128
- <a name='L63'></a><a href='#L63'>63</a>
129
- <a name='L64'></a><a href='#L64'>64</a>
130
- <a name='L65'></a><a href='#L65'>65</a>
131
- <a name='L66'></a><a href='#L66'>66</a>
132
- <a name='L67'></a><a href='#L67'>67</a>
133
- <a name='L68'></a><a href='#L68'>68</a>
134
- <a name='L69'></a><a href='#L69'>69</a>
135
- <a name='L70'></a><a href='#L70'>70</a>
136
- <a name='L71'></a><a href='#L71'>71</a>
137
- <a name='L72'></a><a href='#L72'>72</a>
138
- <a name='L73'></a><a href='#L73'>73</a>
139
- <a name='L74'></a><a href='#L74'>74</a>
140
- <a name='L75'></a><a href='#L75'>75</a>
141
- <a name='L76'></a><a href='#L76'>76</a>
142
- <a name='L77'></a><a href='#L77'>77</a>
143
- <a name='L78'></a><a href='#L78'>78</a>
144
- <a name='L79'></a><a href='#L79'>79</a>
145
- <a name='L80'></a><a href='#L80'>80</a>
146
- <a name='L81'></a><a href='#L81'>81</a>
147
- <a name='L82'></a><a href='#L82'>82</a>
148
- <a name='L83'></a><a href='#L83'>83</a>
149
- <a name='L84'></a><a href='#L84'>84</a>
150
- <a name='L85'></a><a href='#L85'>85</a>
151
- <a name='L86'></a><a href='#L86'>86</a>
152
- <a name='L87'></a><a href='#L87'>87</a>
153
- <a name='L88'></a><a href='#L88'>88</a>
154
- <a name='L89'></a><a href='#L89'>89</a>
155
- <a name='L90'></a><a href='#L90'>90</a>
156
- <a name='L91'></a><a href='#L91'>91</a>
157
- <a name='L92'></a><a href='#L92'>92</a>
158
- <a name='L93'></a><a href='#L93'>93</a>
159
- <a name='L94'></a><a href='#L94'>94</a>
160
- <a name='L95'></a><a href='#L95'>95</a>
161
- <a name='L96'></a><a href='#L96'>96</a>
162
- <a name='L97'></a><a href='#L97'>97</a>
163
- <a name='L98'></a><a href='#L98'>98</a>
164
- <a name='L99'></a><a href='#L99'>99</a>
165
- <a name='L100'></a><a href='#L100'>100</a>
166
- <a name='L101'></a><a href='#L101'>101</a>
167
- <a name='L102'></a><a href='#L102'>102</a>
168
- <a name='L103'></a><a href='#L103'>103</a>
169
- <a name='L104'></a><a href='#L104'>104</a>
170
- <a name='L105'></a><a href='#L105'>105</a>
171
- <a name='L106'></a><a href='#L106'>106</a>
172
- <a name='L107'></a><a href='#L107'>107</a>
173
- <a name='L108'></a><a href='#L108'>108</a>
174
- <a name='L109'></a><a href='#L109'>109</a>
175
- <a name='L110'></a><a href='#L110'>110</a>
176
- <a name='L111'></a><a href='#L111'>111</a>
177
- <a name='L112'></a><a href='#L112'>112</a>
178
- <a name='L113'></a><a href='#L113'>113</a>
179
- <a name='L114'></a><a href='#L114'>114</a>
180
- <a name='L115'></a><a href='#L115'>115</a>
181
- <a name='L116'></a><a href='#L116'>116</a>
182
- <a name='L117'></a><a href='#L117'>117</a>
183
- <a name='L118'></a><a href='#L118'>118</a>
184
- <a name='L119'></a><a href='#L119'>119</a>
185
- <a name='L120'></a><a href='#L120'>120</a>
186
- <a name='L121'></a><a href='#L121'>121</a>
187
- <a name='L122'></a><a href='#L122'>122</a>
188
- <a name='L123'></a><a href='#L123'>123</a>
189
- <a name='L124'></a><a href='#L124'>124</a>
190
- <a name='L125'></a><a href='#L125'>125</a>
191
- <a name='L126'></a><a href='#L126'>126</a>
192
- <a name='L127'></a><a href='#L127'>127</a>
193
- <a name='L128'></a><a href='#L128'>128</a>
194
- <a name='L129'></a><a href='#L129'>129</a>
195
- <a name='L130'></a><a href='#L130'>130</a>
196
- <a name='L131'></a><a href='#L131'>131</a>
197
- <a name='L132'></a><a href='#L132'>132</a>
198
- <a name='L133'></a><a href='#L133'>133</a>
199
- <a name='L134'></a><a href='#L134'>134</a>
200
- <a name='L135'></a><a href='#L135'>135</a>
201
- <a name='L136'></a><a href='#L136'>136</a>
202
- <a name='L137'></a><a href='#L137'>137</a>
203
- <a name='L138'></a><a href='#L138'>138</a>
204
- <a name='L139'></a><a href='#L139'>139</a>
205
- <a name='L140'></a><a href='#L140'>140</a>
206
- <a name='L141'></a><a href='#L141'>141</a>
207
- <a name='L142'></a><a href='#L142'>142</a>
208
- <a name='L143'></a><a href='#L143'>143</a>
209
- <a name='L144'></a><a href='#L144'>144</a>
210
- <a name='L145'></a><a href='#L145'>145</a>
211
- <a name='L146'></a><a href='#L146'>146</a>
212
- <a name='L147'></a><a href='#L147'>147</a>
213
- <a name='L148'></a><a href='#L148'>148</a>
214
- <a name='L149'></a><a href='#L149'>149</a>
215
- <a name='L150'></a><a href='#L150'>150</a>
216
- <a name='L151'></a><a href='#L151'>151</a>
217
- <a name='L152'></a><a href='#L152'>152</a>
218
- <a name='L153'></a><a href='#L153'>153</a>
219
- <a name='L154'></a><a href='#L154'>154</a>
220
- <a name='L155'></a><a href='#L155'>155</a>
221
- <a name='L156'></a><a href='#L156'>156</a>
222
- <a name='L157'></a><a href='#L157'>157</a>
223
- <a name='L158'></a><a href='#L158'>158</a>
224
- <a name='L159'></a><a href='#L159'>159</a>
225
- <a name='L160'></a><a href='#L160'>160</a>
226
- <a name='L161'></a><a href='#L161'>161</a>
227
- <a name='L162'></a><a href='#L162'>162</a>
228
- <a name='L163'></a><a href='#L163'>163</a>
229
- <a name='L164'></a><a href='#L164'>164</a>
230
- <a name='L165'></a><a href='#L165'>165</a>
231
- <a name='L166'></a><a href='#L166'>166</a>
232
- <a name='L167'></a><a href='#L167'>167</a>
233
- <a name='L168'></a><a href='#L168'>168</a>
234
- <a name='L169'></a><a href='#L169'>169</a>
235
- <a name='L170'></a><a href='#L170'>170</a>
236
- <a name='L171'></a><a href='#L171'>171</a>
237
- <a name='L172'></a><a href='#L172'>172</a>
238
- <a name='L173'></a><a href='#L173'>173</a>
239
- <a name='L174'></a><a href='#L174'>174</a>
240
- <a name='L175'></a><a href='#L175'>175</a>
241
- <a name='L176'></a><a href='#L176'>176</a>
242
- <a name='L177'></a><a href='#L177'>177</a>
243
- <a name='L178'></a><a href='#L178'>178</a>
244
- <a name='L179'></a><a href='#L179'>179</a>
245
- <a name='L180'></a><a href='#L180'>180</a>
246
- <a name='L181'></a><a href='#L181'>181</a>
247
- <a name='L182'></a><a href='#L182'>182</a>
248
- <a name='L183'></a><a href='#L183'>183</a>
249
- <a name='L184'></a><a href='#L184'>184</a>
250
- <a name='L185'></a><a href='#L185'>185</a>
251
- <a name='L186'></a><a href='#L186'>186</a>
252
- <a name='L187'></a><a href='#L187'>187</a>
253
- <a name='L188'></a><a href='#L188'>188</a>
254
- <a name='L189'></a><a href='#L189'>189</a>
255
- <a name='L190'></a><a href='#L190'>190</a>
256
- <a name='L191'></a><a href='#L191'>191</a>
257
- <a name='L192'></a><a href='#L192'>192</a>
258
- <a name='L193'></a><a href='#L193'>193</a>
259
- <a name='L194'></a><a href='#L194'>194</a>
260
- <a name='L195'></a><a href='#L195'>195</a>
261
- <a name='L196'></a><a href='#L196'>196</a>
262
- <a name='L197'></a><a href='#L197'>197</a>
263
- <a name='L198'></a><a href='#L198'>198</a>
264
- <a name='L199'></a><a href='#L199'>199</a>
265
- <a name='L200'></a><a href='#L200'>200</a>
266
- <a name='L201'></a><a href='#L201'>201</a>
267
- <a name='L202'></a><a href='#L202'>202</a>
268
- <a name='L203'></a><a href='#L203'>203</a>
269
- <a name='L204'></a><a href='#L204'>204</a>
270
- <a name='L205'></a><a href='#L205'>205</a>
271
- <a name='L206'></a><a href='#L206'>206</a>
272
- <a name='L207'></a><a href='#L207'>207</a>
273
- <a name='L208'></a><a href='#L208'>208</a>
274
- <a name='L209'></a><a href='#L209'>209</a>
275
- <a name='L210'></a><a href='#L210'>210</a>
276
- <a name='L211'></a><a href='#L211'>211</a>
277
- <a name='L212'></a><a href='#L212'>212</a>
278
- <a name='L213'></a><a href='#L213'>213</a>
279
- <a name='L214'></a><a href='#L214'>214</a>
280
- <a name='L215'></a><a href='#L215'>215</a>
281
- <a name='L216'></a><a href='#L216'>216</a>
282
- <a name='L217'></a><a href='#L217'>217</a>
283
- <a name='L218'></a><a href='#L218'>218</a>
284
- <a name='L219'></a><a href='#L219'>219</a>
285
- <a name='L220'></a><a href='#L220'>220</a>
286
- <a name='L221'></a><a href='#L221'>221</a>
287
- <a name='L222'></a><a href='#L222'>222</a>
288
- <a name='L223'></a><a href='#L223'>223</a>
289
- <a name='L224'></a><a href='#L224'>224</a>
290
- <a name='L225'></a><a href='#L225'>225</a>
291
- <a name='L226'></a><a href='#L226'>226</a>
292
- <a name='L227'></a><a href='#L227'>227</a>
293
- <a name='L228'></a><a href='#L228'>228</a>
294
- <a name='L229'></a><a href='#L229'>229</a>
295
- <a name='L230'></a><a href='#L230'>230</a>
296
- <a name='L231'></a><a href='#L231'>231</a>
297
- <a name='L232'></a><a href='#L232'>232</a>
298
- <a name='L233'></a><a href='#L233'>233</a>
299
- <a name='L234'></a><a href='#L234'>234</a>
300
- <a name='L235'></a><a href='#L235'>235</a>
301
- <a name='L236'></a><a href='#L236'>236</a>
302
- <a name='L237'></a><a href='#L237'>237</a>
303
- <a name='L238'></a><a href='#L238'>238</a>
304
- <a name='L239'></a><a href='#L239'>239</a>
305
- <a name='L240'></a><a href='#L240'>240</a>
306
- <a name='L241'></a><a href='#L241'>241</a>
307
- <a name='L242'></a><a href='#L242'>242</a>
308
- <a name='L243'></a><a href='#L243'>243</a>
309
- <a name='L244'></a><a href='#L244'>244</a>
310
- <a name='L245'></a><a href='#L245'>245</a>
311
- <a name='L246'></a><a href='#L246'>246</a>
312
- <a name='L247'></a><a href='#L247'>247</a>
313
- <a name='L248'></a><a href='#L248'>248</a>
314
- <a name='L249'></a><a href='#L249'>249</a>
315
- <a name='L250'></a><a href='#L250'>250</a>
316
- <a name='L251'></a><a href='#L251'>251</a>
317
- <a name='L252'></a><a href='#L252'>252</a>
318
- <a name='L253'></a><a href='#L253'>253</a>
319
- <a name='L254'></a><a href='#L254'>254</a>
320
- <a name='L255'></a><a href='#L255'>255</a>
321
- <a name='L256'></a><a href='#L256'>256</a>
322
- <a name='L257'></a><a href='#L257'>257</a>
323
- <a name='L258'></a><a href='#L258'>258</a>
324
- <a name='L259'></a><a href='#L259'>259</a>
325
- <a name='L260'></a><a href='#L260'>260</a>
326
- <a name='L261'></a><a href='#L261'>261</a>
327
- <a name='L262'></a><a href='#L262'>262</a>
328
- <a name='L263'></a><a href='#L263'>263</a>
329
- <a name='L264'></a><a href='#L264'>264</a>
330
- <a name='L265'></a><a href='#L265'>265</a>
331
- <a name='L266'></a><a href='#L266'>266</a>
332
- <a name='L267'></a><a href='#L267'>267</a>
333
- <a name='L268'></a><a href='#L268'>268</a>
334
- <a name='L269'></a><a href='#L269'>269</a>
335
- <a name='L270'></a><a href='#L270'>270</a>
336
- <a name='L271'></a><a href='#L271'>271</a>
337
- <a name='L272'></a><a href='#L272'>272</a>
338
- <a name='L273'></a><a href='#L273'>273</a>
339
- <a name='L274'></a><a href='#L274'>274</a>
340
- <a name='L275'></a><a href='#L275'>275</a>
341
- <a name='L276'></a><a href='#L276'>276</a>
342
- <a name='L277'></a><a href='#L277'>277</a>
343
- <a name='L278'></a><a href='#L278'>278</a>
344
- <a name='L279'></a><a href='#L279'>279</a>
345
- <a name='L280'></a><a href='#L280'>280</a>
346
- <a name='L281'></a><a href='#L281'>281</a>
347
- <a name='L282'></a><a href='#L282'>282</a>
348
- <a name='L283'></a><a href='#L283'>283</a>
349
- <a name='L284'></a><a href='#L284'>284</a>
350
- <a name='L285'></a><a href='#L285'>285</a>
351
- <a name='L286'></a><a href='#L286'>286</a>
352
- <a name='L287'></a><a href='#L287'>287</a>
353
- <a name='L288'></a><a href='#L288'>288</a>
354
- <a name='L289'></a><a href='#L289'>289</a>
355
- <a name='L290'></a><a href='#L290'>290</a>
356
- <a name='L291'></a><a href='#L291'>291</a>
357
- <a name='L292'></a><a href='#L292'>292</a>
358
- <a name='L293'></a><a href='#L293'>293</a>
359
- <a name='L294'></a><a href='#L294'>294</a>
360
- <a name='L295'></a><a href='#L295'>295</a>
361
- <a name='L296'></a><a href='#L296'>296</a>
362
- <a name='L297'></a><a href='#L297'>297</a>
363
- <a name='L298'></a><a href='#L298'>298</a>
364
- <a name='L299'></a><a href='#L299'>299</a>
365
- <a name='L300'></a><a href='#L300'>300</a>
366
- <a name='L301'></a><a href='#L301'>301</a>
367
- <a name='L302'></a><a href='#L302'>302</a>
368
- <a name='L303'></a><a href='#L303'>303</a>
369
- <a name='L304'></a><a href='#L304'>304</a>
370
- <a name='L305'></a><a href='#L305'>305</a>
371
- <a name='L306'></a><a href='#L306'>306</a>
372
- <a name='L307'></a><a href='#L307'>307</a>
373
- <a name='L308'></a><a href='#L308'>308</a>
374
- <a name='L309'></a><a href='#L309'>309</a>
375
- <a name='L310'></a><a href='#L310'>310</a>
376
- <a name='L311'></a><a href='#L311'>311</a>
377
- <a name='L312'></a><a href='#L312'>312</a>
378
- <a name='L313'></a><a href='#L313'>313</a>
379
- <a name='L314'></a><a href='#L314'>314</a>
380
- <a name='L315'></a><a href='#L315'>315</a>
381
- <a name='L316'></a><a href='#L316'>316</a>
382
- <a name='L317'></a><a href='#L317'>317</a>
383
- <a name='L318'></a><a href='#L318'>318</a>
384
- <a name='L319'></a><a href='#L319'>319</a>
385
- <a name='L320'></a><a href='#L320'>320</a>
386
- <a name='L321'></a><a href='#L321'>321</a>
387
- <a name='L322'></a><a href='#L322'>322</a>
388
- <a name='L323'></a><a href='#L323'>323</a>
389
- <a name='L324'></a><a href='#L324'>324</a>
390
- <a name='L325'></a><a href='#L325'>325</a>
391
- <a name='L326'></a><a href='#L326'>326</a>
392
- <a name='L327'></a><a href='#L327'>327</a>
393
- <a name='L328'></a><a href='#L328'>328</a>
394
- <a name='L329'></a><a href='#L329'>329</a>
395
- <a name='L330'></a><a href='#L330'>330</a>
396
- <a name='L331'></a><a href='#L331'>331</a>
397
- <a name='L332'></a><a href='#L332'>332</a>
398
- <a name='L333'></a><a href='#L333'>333</a>
399
- <a name='L334'></a><a href='#L334'>334</a>
400
- <a name='L335'></a><a href='#L335'>335</a>
401
- <a name='L336'></a><a href='#L336'>336</a>
402
- <a name='L337'></a><a href='#L337'>337</a>
403
- <a name='L338'></a><a href='#L338'>338</a>
404
- <a name='L339'></a><a href='#L339'>339</a>
405
- <a name='L340'></a><a href='#L340'>340</a>
406
- <a name='L341'></a><a href='#L341'>341</a>
407
- <a name='L342'></a><a href='#L342'>342</a>
408
- <a name='L343'></a><a href='#L343'>343</a>
409
- <a name='L344'></a><a href='#L344'>344</a>
410
- <a name='L345'></a><a href='#L345'>345</a>
411
- <a name='L346'></a><a href='#L346'>346</a>
412
- <a name='L347'></a><a href='#L347'>347</a>
413
- <a name='L348'></a><a href='#L348'>348</a>
414
- <a name='L349'></a><a href='#L349'>349</a>
415
- <a name='L350'></a><a href='#L350'>350</a>
416
- <a name='L351'></a><a href='#L351'>351</a>
417
- <a name='L352'></a><a href='#L352'>352</a>
418
- <a name='L353'></a><a href='#L353'>353</a>
419
- <a name='L354'></a><a href='#L354'>354</a>
420
- <a name='L355'></a><a href='#L355'>355</a>
421
- <a name='L356'></a><a href='#L356'>356</a>
422
- <a name='L357'></a><a href='#L357'>357</a>
423
- <a name='L358'></a><a href='#L358'>358</a>
424
- <a name='L359'></a><a href='#L359'>359</a>
425
- <a name='L360'></a><a href='#L360'>360</a>
426
- <a name='L361'></a><a href='#L361'>361</a>
427
- <a name='L362'></a><a href='#L362'>362</a>
428
- <a name='L363'></a><a href='#L363'>363</a>
429
- <a name='L364'></a><a href='#L364'>364</a>
430
- <a name='L365'></a><a href='#L365'>365</a>
431
- <a name='L366'></a><a href='#L366'>366</a>
432
- <a name='L367'></a><a href='#L367'>367</a>
433
- <a name='L368'></a><a href='#L368'>368</a>
434
- <a name='L369'></a><a href='#L369'>369</a>
435
- <a name='L370'></a><a href='#L370'>370</a>
436
- <a name='L371'></a><a href='#L371'>371</a>
437
- <a name='L372'></a><a href='#L372'>372</a>
438
- <a name='L373'></a><a href='#L373'>373</a>
439
- <a name='L374'></a><a href='#L374'>374</a>
440
- <a name='L375'></a><a href='#L375'>375</a>
441
- <a name='L376'></a><a href='#L376'>376</a>
442
- <a name='L377'></a><a href='#L377'>377</a>
443
- <a name='L378'></a><a href='#L378'>378</a>
444
- <a name='L379'></a><a href='#L379'>379</a>
445
- <a name='L380'></a><a href='#L380'>380</a>
446
- <a name='L381'></a><a href='#L381'>381</a>
447
- <a name='L382'></a><a href='#L382'>382</a>
448
- <a name='L383'></a><a href='#L383'>383</a>
449
- <a name='L384'></a><a href='#L384'>384</a>
450
- <a name='L385'></a><a href='#L385'>385</a>
451
- <a name='L386'></a><a href='#L386'>386</a>
452
- <a name='L387'></a><a href='#L387'>387</a>
453
- <a name='L388'></a><a href='#L388'>388</a>
454
- <a name='L389'></a><a href='#L389'>389</a>
455
- <a name='L390'></a><a href='#L390'>390</a>
456
- <a name='L391'></a><a href='#L391'>391</a>
457
- <a name='L392'></a><a href='#L392'>392</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
458
- <span class="cline-any cline-neutral">&nbsp;</span>
459
- <span class="cline-any cline-neutral">&nbsp;</span>
460
- <span class="cline-any cline-neutral">&nbsp;</span>
461
- <span class="cline-any cline-neutral">&nbsp;</span>
462
- <span class="cline-any cline-neutral">&nbsp;</span>
463
- <span class="cline-any cline-neutral">&nbsp;</span>
464
- <span class="cline-any cline-neutral">&nbsp;</span>
465
- <span class="cline-any cline-neutral">&nbsp;</span>
466
- <span class="cline-any cline-neutral">&nbsp;</span>
467
- <span class="cline-any cline-neutral">&nbsp;</span>
468
- <span class="cline-any cline-neutral">&nbsp;</span>
469
- <span class="cline-any cline-neutral">&nbsp;</span>
470
- <span class="cline-any cline-neutral">&nbsp;</span>
471
- <span class="cline-any cline-neutral">&nbsp;</span>
472
- <span class="cline-any cline-neutral">&nbsp;</span>
473
- <span class="cline-any cline-yes">1x</span>
474
- <span class="cline-any cline-yes">1x</span>
475
- <span class="cline-any cline-neutral">&nbsp;</span>
476
- <span class="cline-any cline-neutral">&nbsp;</span>
477
- <span class="cline-any cline-yes">1x</span>
478
- <span class="cline-any cline-yes">1x</span>
479
- <span class="cline-any cline-neutral">&nbsp;</span>
480
- <span class="cline-any cline-yes">1x</span>
481
- <span class="cline-any cline-yes">1x</span>
482
- <span class="cline-any cline-neutral">&nbsp;</span>
483
- <span class="cline-any cline-neutral">&nbsp;</span>
484
- <span class="cline-any cline-neutral">&nbsp;</span>
485
- <span class="cline-any cline-neutral">&nbsp;</span>
486
- <span class="cline-any cline-neutral">&nbsp;</span>
487
- <span class="cline-any cline-yes">1x</span>
488
- <span class="cline-any cline-neutral">&nbsp;</span>
489
- <span class="cline-any cline-neutral">&nbsp;</span>
490
- <span class="cline-any cline-neutral">&nbsp;</span>
491
- <span class="cline-any cline-neutral">&nbsp;</span>
492
- <span class="cline-any cline-neutral">&nbsp;</span>
493
- <span class="cline-any cline-neutral">&nbsp;</span>
494
- <span class="cline-any cline-neutral">&nbsp;</span>
495
- <span class="cline-any cline-yes">2x</span>
496
- <span class="cline-any cline-no">&nbsp;</span>
497
- <span class="cline-any cline-no">&nbsp;</span>
498
- <span class="cline-any cline-neutral">&nbsp;</span>
499
- <span class="cline-any cline-no">&nbsp;</span>
500
- <span class="cline-any cline-neutral">&nbsp;</span>
501
- <span class="cline-any cline-neutral">&nbsp;</span>
502
- <span class="cline-any cline-no">&nbsp;</span>
503
- <span class="cline-any cline-no">&nbsp;</span>
504
- <span class="cline-any cline-no">&nbsp;</span>
505
- <span class="cline-any cline-neutral">&nbsp;</span>
506
- <span class="cline-any cline-neutral">&nbsp;</span>
507
- <span class="cline-any cline-no">&nbsp;</span>
508
- <span class="cline-any cline-no">&nbsp;</span>
509
- <span class="cline-any cline-no">&nbsp;</span>
510
- <span class="cline-any cline-neutral">&nbsp;</span>
511
- <span class="cline-any cline-neutral">&nbsp;</span>
512
- <span class="cline-any cline-no">&nbsp;</span>
513
- <span class="cline-any cline-neutral">&nbsp;</span>
514
- <span class="cline-any cline-neutral">&nbsp;</span>
515
- <span class="cline-any cline-no">&nbsp;</span>
516
- <span class="cline-any cline-no">&nbsp;</span>
517
- <span class="cline-any cline-neutral">&nbsp;</span>
518
- <span class="cline-any cline-no">&nbsp;</span>
519
- <span class="cline-any cline-neutral">&nbsp;</span>
520
- <span class="cline-any cline-neutral">&nbsp;</span>
521
- <span class="cline-any cline-no">&nbsp;</span>
522
- <span class="cline-any cline-neutral">&nbsp;</span>
523
- <span class="cline-any cline-neutral">&nbsp;</span>
524
- <span class="cline-any cline-neutral">&nbsp;</span>
525
- <span class="cline-any cline-neutral">&nbsp;</span>
526
- <span class="cline-any cline-neutral">&nbsp;</span>
527
- <span class="cline-any cline-neutral">&nbsp;</span>
528
- <span class="cline-any cline-neutral">&nbsp;</span>
529
- <span class="cline-any cline-neutral">&nbsp;</span>
530
- <span class="cline-any cline-no">&nbsp;</span>
531
- <span class="cline-any cline-neutral">&nbsp;</span>
532
- <span class="cline-any cline-neutral">&nbsp;</span>
533
- <span class="cline-any cline-no">&nbsp;</span>
534
- <span class="cline-any cline-neutral">&nbsp;</span>
535
- <span class="cline-any cline-no">&nbsp;</span>
536
- <span class="cline-any cline-neutral">&nbsp;</span>
537
- <span class="cline-any cline-neutral">&nbsp;</span>
538
- <span class="cline-any cline-neutral">&nbsp;</span>
539
- <span class="cline-any cline-neutral">&nbsp;</span>
540
- <span class="cline-any cline-neutral">&nbsp;</span>
541
- <span class="cline-any cline-no">&nbsp;</span>
542
- <span class="cline-any cline-neutral">&nbsp;</span>
543
- <span class="cline-any cline-neutral">&nbsp;</span>
544
- <span class="cline-any cline-no">&nbsp;</span>
545
- <span class="cline-any cline-neutral">&nbsp;</span>
546
- <span class="cline-any cline-neutral">&nbsp;</span>
547
- <span class="cline-any cline-neutral">&nbsp;</span>
548
- <span class="cline-any cline-neutral">&nbsp;</span>
549
- <span class="cline-any cline-neutral">&nbsp;</span>
550
- <span class="cline-any cline-neutral">&nbsp;</span>
551
- <span class="cline-any cline-neutral">&nbsp;</span>
552
- <span class="cline-any cline-neutral">&nbsp;</span>
553
- <span class="cline-any cline-neutral">&nbsp;</span>
554
- <span class="cline-any cline-neutral">&nbsp;</span>
555
- <span class="cline-any cline-neutral">&nbsp;</span>
556
- <span class="cline-any cline-neutral">&nbsp;</span>
557
- <span class="cline-any cline-no">&nbsp;</span>
558
- <span class="cline-any cline-neutral">&nbsp;</span>
559
- <span class="cline-any cline-neutral">&nbsp;</span>
560
- <span class="cline-any cline-neutral">&nbsp;</span>
561
- <span class="cline-any cline-no">&nbsp;</span>
562
- <span class="cline-any cline-neutral">&nbsp;</span>
563
- <span class="cline-any cline-neutral">&nbsp;</span>
564
- <span class="cline-any cline-neutral">&nbsp;</span>
565
- <span class="cline-any cline-neutral">&nbsp;</span>
566
- <span class="cline-any cline-neutral">&nbsp;</span>
567
- <span class="cline-any cline-neutral">&nbsp;</span>
568
- <span class="cline-any cline-neutral">&nbsp;</span>
569
- <span class="cline-any cline-neutral">&nbsp;</span>
570
- <span class="cline-any cline-neutral">&nbsp;</span>
571
- <span class="cline-any cline-neutral">&nbsp;</span>
572
- <span class="cline-any cline-neutral">&nbsp;</span>
573
- <span class="cline-any cline-yes">2x</span>
574
- <span class="cline-any cline-neutral">&nbsp;</span>
575
- <span class="cline-any cline-neutral">&nbsp;</span>
576
- <span class="cline-any cline-neutral">&nbsp;</span>
577
- <span class="cline-any cline-neutral">&nbsp;</span>
578
- <span class="cline-any cline-no">&nbsp;</span>
579
- <span class="cline-any cline-neutral">&nbsp;</span>
580
- <span class="cline-any cline-no">&nbsp;</span>
581
- <span class="cline-any cline-no">&nbsp;</span>
582
- <span class="cline-any cline-no">&nbsp;</span>
583
- <span class="cline-any cline-neutral">&nbsp;</span>
584
- <span class="cline-any cline-no">&nbsp;</span>
585
- <span class="cline-any cline-neutral">&nbsp;</span>
586
- <span class="cline-any cline-neutral">&nbsp;</span>
587
- <span class="cline-any cline-no">&nbsp;</span>
588
- <span class="cline-any cline-no">&nbsp;</span>
589
- <span class="cline-any cline-no">&nbsp;</span>
590
- <span class="cline-any cline-neutral">&nbsp;</span>
591
- <span class="cline-any cline-neutral">&nbsp;</span>
592
- <span class="cline-any cline-neutral">&nbsp;</span>
593
- <span class="cline-any cline-neutral">&nbsp;</span>
594
- <span class="cline-any cline-neutral">&nbsp;</span>
595
- <span class="cline-any cline-neutral">&nbsp;</span>
596
- <span class="cline-any cline-neutral">&nbsp;</span>
597
- <span class="cline-any cline-neutral">&nbsp;</span>
598
- <span class="cline-any cline-neutral">&nbsp;</span>
599
- <span class="cline-any cline-neutral">&nbsp;</span>
600
- <span class="cline-any cline-neutral">&nbsp;</span>
601
- <span class="cline-any cline-neutral">&nbsp;</span>
602
- <span class="cline-any cline-neutral">&nbsp;</span>
603
- <span class="cline-any cline-neutral">&nbsp;</span>
604
- <span class="cline-any cline-neutral">&nbsp;</span>
605
- <span class="cline-any cline-neutral">&nbsp;</span>
606
- <span class="cline-any cline-neutral">&nbsp;</span>
607
- <span class="cline-any cline-neutral">&nbsp;</span>
608
- <span class="cline-any cline-neutral">&nbsp;</span>
609
- <span class="cline-any cline-no">&nbsp;</span>
610
- <span class="cline-any cline-no">&nbsp;</span>
611
- <span class="cline-any cline-neutral">&nbsp;</span>
612
- <span class="cline-any cline-neutral">&nbsp;</span>
613
- <span class="cline-any cline-neutral">&nbsp;</span>
614
- <span class="cline-any cline-neutral">&nbsp;</span>
615
- <span class="cline-any cline-no">&nbsp;</span>
616
- <span class="cline-any cline-neutral">&nbsp;</span>
617
- <span class="cline-any cline-no">&nbsp;</span>
618
- <span class="cline-any cline-no">&nbsp;</span>
619
- <span class="cline-any cline-no">&nbsp;</span>
620
- <span class="cline-any cline-no">&nbsp;</span>
621
- <span class="cline-any cline-no">&nbsp;</span>
622
- <span class="cline-any cline-neutral">&nbsp;</span>
623
- <span class="cline-any cline-no">&nbsp;</span>
624
- <span class="cline-any cline-neutral">&nbsp;</span>
625
- <span class="cline-any cline-no">&nbsp;</span>
626
- <span class="cline-any cline-neutral">&nbsp;</span>
627
- <span class="cline-any cline-neutral">&nbsp;</span>
628
- <span class="cline-any cline-neutral">&nbsp;</span>
629
- <span class="cline-any cline-neutral">&nbsp;</span>
630
- <span class="cline-any cline-neutral">&nbsp;</span>
631
- <span class="cline-any cline-neutral">&nbsp;</span>
632
- <span class="cline-any cline-neutral">&nbsp;</span>
633
- <span class="cline-any cline-neutral">&nbsp;</span>
634
- <span class="cline-any cline-neutral">&nbsp;</span>
635
- <span class="cline-any cline-neutral">&nbsp;</span>
636
- <span class="cline-any cline-neutral">&nbsp;</span>
637
- <span class="cline-any cline-neutral">&nbsp;</span>
638
- <span class="cline-any cline-no">&nbsp;</span>
639
- <span class="cline-any cline-no">&nbsp;</span>
640
- <span class="cline-any cline-no">&nbsp;</span>
641
- <span class="cline-any cline-neutral">&nbsp;</span>
642
- <span class="cline-any cline-neutral">&nbsp;</span>
643
- <span class="cline-any cline-neutral">&nbsp;</span>
644
- <span class="cline-any cline-neutral">&nbsp;</span>
645
- <span class="cline-any cline-neutral">&nbsp;</span>
646
- <span class="cline-any cline-neutral">&nbsp;</span>
647
- <span class="cline-any cline-no">&nbsp;</span>
648
- <span class="cline-any cline-neutral">&nbsp;</span>
649
- <span class="cline-any cline-no">&nbsp;</span>
650
- <span class="cline-any cline-neutral">&nbsp;</span>
651
- <span class="cline-any cline-no">&nbsp;</span>
652
- <span class="cline-any cline-neutral">&nbsp;</span>
653
- <span class="cline-any cline-neutral">&nbsp;</span>
654
- <span class="cline-any cline-neutral">&nbsp;</span>
655
- <span class="cline-any cline-no">&nbsp;</span>
656
- <span class="cline-any cline-no">&nbsp;</span>
657
- <span class="cline-any cline-neutral">&nbsp;</span>
658
- <span class="cline-any cline-neutral">&nbsp;</span>
659
- <span class="cline-any cline-neutral">&nbsp;</span>
660
- <span class="cline-any cline-neutral">&nbsp;</span>
661
- <span class="cline-any cline-neutral">&nbsp;</span>
662
- <span class="cline-any cline-neutral">&nbsp;</span>
663
- <span class="cline-any cline-no">&nbsp;</span>
664
- <span class="cline-any cline-neutral">&nbsp;</span>
665
- <span class="cline-any cline-neutral">&nbsp;</span>
666
- <span class="cline-any cline-no">&nbsp;</span>
667
- <span class="cline-any cline-neutral">&nbsp;</span>
668
- <span class="cline-any cline-neutral">&nbsp;</span>
669
- <span class="cline-any cline-neutral">&nbsp;</span>
670
- <span class="cline-any cline-neutral">&nbsp;</span>
671
- <span class="cline-any cline-neutral">&nbsp;</span>
672
- <span class="cline-any cline-neutral">&nbsp;</span>
673
- <span class="cline-any cline-neutral">&nbsp;</span>
674
- <span class="cline-any cline-neutral">&nbsp;</span>
675
- <span class="cline-any cline-neutral">&nbsp;</span>
676
- <span class="cline-any cline-neutral">&nbsp;</span>
677
- <span class="cline-any cline-neutral">&nbsp;</span>
678
- <span class="cline-any cline-no">&nbsp;</span>
679
- <span class="cline-any cline-neutral">&nbsp;</span>
680
- <span class="cline-any cline-neutral">&nbsp;</span>
681
- <span class="cline-any cline-no">&nbsp;</span>
682
- <span class="cline-any cline-neutral">&nbsp;</span>
683
- <span class="cline-any cline-no">&nbsp;</span>
684
- <span class="cline-any cline-no">&nbsp;</span>
685
- <span class="cline-any cline-neutral">&nbsp;</span>
686
- <span class="cline-any cline-no">&nbsp;</span>
687
- <span class="cline-any cline-neutral">&nbsp;</span>
688
- <span class="cline-any cline-neutral">&nbsp;</span>
689
- <span class="cline-any cline-no">&nbsp;</span>
690
- <span class="cline-any cline-neutral">&nbsp;</span>
691
- <span class="cline-any cline-neutral">&nbsp;</span>
692
- <span class="cline-any cline-neutral">&nbsp;</span>
693
- <span class="cline-any cline-neutral">&nbsp;</span>
694
- <span class="cline-any cline-neutral">&nbsp;</span>
695
- <span class="cline-any cline-no">&nbsp;</span>
696
- <span class="cline-any cline-neutral">&nbsp;</span>
697
- <span class="cline-any cline-neutral">&nbsp;</span>
698
- <span class="cline-any cline-neutral">&nbsp;</span>
699
- <span class="cline-any cline-neutral">&nbsp;</span>
700
- <span class="cline-any cline-neutral">&nbsp;</span>
701
- <span class="cline-any cline-neutral">&nbsp;</span>
702
- <span class="cline-any cline-neutral">&nbsp;</span>
703
- <span class="cline-any cline-neutral">&nbsp;</span>
704
- <span class="cline-any cline-neutral">&nbsp;</span>
705
- <span class="cline-any cline-neutral">&nbsp;</span>
706
- <span class="cline-any cline-neutral">&nbsp;</span>
707
- <span class="cline-any cline-neutral">&nbsp;</span>
708
- <span class="cline-any cline-no">&nbsp;</span>
709
- <span class="cline-any cline-neutral">&nbsp;</span>
710
- <span class="cline-any cline-neutral">&nbsp;</span>
711
- <span class="cline-any cline-no">&nbsp;</span>
712
- <span class="cline-any cline-neutral">&nbsp;</span>
713
- <span class="cline-any cline-neutral">&nbsp;</span>
714
- <span class="cline-any cline-no">&nbsp;</span>
715
- <span class="cline-any cline-no">&nbsp;</span>
716
- <span class="cline-any cline-no">&nbsp;</span>
717
- <span class="cline-any cline-neutral">&nbsp;</span>
718
- <span class="cline-any cline-neutral">&nbsp;</span>
719
- <span class="cline-any cline-no">&nbsp;</span>
720
- <span class="cline-any cline-no">&nbsp;</span>
721
- <span class="cline-any cline-neutral">&nbsp;</span>
722
- <span class="cline-any cline-neutral">&nbsp;</span>
723
- <span class="cline-any cline-neutral">&nbsp;</span>
724
- <span class="cline-any cline-no">&nbsp;</span>
725
- <span class="cline-any cline-neutral">&nbsp;</span>
726
- <span class="cline-any cline-neutral">&nbsp;</span>
727
- <span class="cline-any cline-no">&nbsp;</span>
728
- <span class="cline-any cline-neutral">&nbsp;</span>
729
- <span class="cline-any cline-neutral">&nbsp;</span>
730
- <span class="cline-any cline-no">&nbsp;</span>
731
- <span class="cline-any cline-neutral">&nbsp;</span>
732
- <span class="cline-any cline-neutral">&nbsp;</span>
733
- <span class="cline-any cline-neutral">&nbsp;</span>
734
- <span class="cline-any cline-neutral">&nbsp;</span>
735
- <span class="cline-any cline-neutral">&nbsp;</span>
736
- <span class="cline-any cline-neutral">&nbsp;</span>
737
- <span class="cline-any cline-neutral">&nbsp;</span>
738
- <span class="cline-any cline-no">&nbsp;</span>
739
- <span class="cline-any cline-neutral">&nbsp;</span>
740
- <span class="cline-any cline-neutral">&nbsp;</span>
741
- <span class="cline-any cline-neutral">&nbsp;</span>
742
- <span class="cline-any cline-no">&nbsp;</span>
743
- <span class="cline-any cline-no">&nbsp;</span>
744
- <span class="cline-any cline-no">&nbsp;</span>
745
- <span class="cline-any cline-neutral">&nbsp;</span>
746
- <span class="cline-any cline-neutral">&nbsp;</span>
747
- <span class="cline-any cline-neutral">&nbsp;</span>
748
- <span class="cline-any cline-neutral">&nbsp;</span>
749
- <span class="cline-any cline-neutral">&nbsp;</span>
750
- <span class="cline-any cline-neutral">&nbsp;</span>
751
- <span class="cline-any cline-neutral">&nbsp;</span>
752
- <span class="cline-any cline-no">&nbsp;</span>
753
- <span class="cline-any cline-neutral">&nbsp;</span>
754
- <span class="cline-any cline-neutral">&nbsp;</span>
755
- <span class="cline-any cline-neutral">&nbsp;</span>
756
- <span class="cline-any cline-no">&nbsp;</span>
757
- <span class="cline-any cline-no">&nbsp;</span>
758
- <span class="cline-any cline-neutral">&nbsp;</span>
759
- <span class="cline-any cline-neutral">&nbsp;</span>
760
- <span class="cline-any cline-neutral">&nbsp;</span>
761
- <span class="cline-any cline-neutral">&nbsp;</span>
762
- <span class="cline-any cline-neutral">&nbsp;</span>
763
- <span class="cline-any cline-neutral">&nbsp;</span>
764
- <span class="cline-any cline-no">&nbsp;</span>
765
- <span class="cline-any cline-neutral">&nbsp;</span>
766
- <span class="cline-any cline-neutral">&nbsp;</span>
767
- <span class="cline-any cline-no">&nbsp;</span>
768
- <span class="cline-any cline-neutral">&nbsp;</span>
769
- <span class="cline-any cline-neutral">&nbsp;</span>
770
- <span class="cline-any cline-neutral">&nbsp;</span>
771
- <span class="cline-any cline-neutral">&nbsp;</span>
772
- <span class="cline-any cline-neutral">&nbsp;</span>
773
- <span class="cline-any cline-neutral">&nbsp;</span>
774
- <span class="cline-any cline-neutral">&nbsp;</span>
775
- <span class="cline-any cline-yes">2x</span>
776
- <span class="cline-any cline-no">&nbsp;</span>
777
- <span class="cline-any cline-no">&nbsp;</span>
778
- <span class="cline-any cline-neutral">&nbsp;</span>
779
- <span class="cline-any cline-neutral">&nbsp;</span>
780
- <span class="cline-any cline-no">&nbsp;</span>
781
- <span class="cline-any cline-neutral">&nbsp;</span>
782
- <span class="cline-any cline-no">&nbsp;</span>
783
- <span class="cline-any cline-no">&nbsp;</span>
784
- <span class="cline-any cline-no">&nbsp;</span>
785
- <span class="cline-any cline-neutral">&nbsp;</span>
786
- <span class="cline-any cline-neutral">&nbsp;</span>
787
- <span class="cline-any cline-no">&nbsp;</span>
788
- <span class="cline-any cline-no">&nbsp;</span>
789
- <span class="cline-any cline-no">&nbsp;</span>
790
- <span class="cline-any cline-neutral">&nbsp;</span>
791
- <span class="cline-any cline-neutral">&nbsp;</span>
792
- <span class="cline-any cline-neutral">&nbsp;</span>
793
- <span class="cline-any cline-neutral">&nbsp;</span>
794
- <span class="cline-any cline-neutral">&nbsp;</span>
795
- <span class="cline-any cline-neutral">&nbsp;</span>
796
- <span class="cline-any cline-neutral">&nbsp;</span>
797
- <span class="cline-any cline-yes">2x</span>
798
- <span class="cline-any cline-no">&nbsp;</span>
799
- <span class="cline-any cline-neutral">&nbsp;</span>
800
- <span class="cline-any cline-no">&nbsp;</span>
801
- <span class="cline-any cline-no">&nbsp;</span>
802
- <span class="cline-any cline-neutral">&nbsp;</span>
803
- <span class="cline-any cline-neutral">&nbsp;</span>
804
- <span class="cline-any cline-no">&nbsp;</span>
805
- <span class="cline-any cline-neutral">&nbsp;</span>
806
- <span class="cline-any cline-no">&nbsp;</span>
807
- <span class="cline-any cline-no">&nbsp;</span>
808
- <span class="cline-any cline-no">&nbsp;</span>
809
- <span class="cline-any cline-neutral">&nbsp;</span>
810
- <span class="cline-any cline-neutral">&nbsp;</span>
811
- <span class="cline-any cline-no">&nbsp;</span>
812
- <span class="cline-any cline-no">&nbsp;</span>
813
- <span class="cline-any cline-no">&nbsp;</span>
814
- <span class="cline-any cline-no">&nbsp;</span>
815
- <span class="cline-any cline-neutral">&nbsp;</span>
816
- <span class="cline-any cline-neutral">&nbsp;</span>
817
- <span class="cline-any cline-neutral">&nbsp;</span>
818
- <span class="cline-any cline-neutral">&nbsp;</span>
819
- <span class="cline-any cline-no">&nbsp;</span>
820
- <span class="cline-any cline-no">&nbsp;</span>
821
- <span class="cline-any cline-neutral">&nbsp;</span>
822
- <span class="cline-any cline-no">&nbsp;</span>
823
- <span class="cline-any cline-neutral">&nbsp;</span>
824
- <span class="cline-any cline-neutral">&nbsp;</span>
825
- <span class="cline-any cline-neutral">&nbsp;</span>
826
- <span class="cline-any cline-neutral">&nbsp;</span>
827
- <span class="cline-any cline-neutral">&nbsp;</span>
828
- <span class="cline-any cline-no">&nbsp;</span>
829
- <span class="cline-any cline-neutral">&nbsp;</span>
830
- <span class="cline-any cline-neutral">&nbsp;</span>
831
- <span class="cline-any cline-neutral">&nbsp;</span>
832
- <span class="cline-any cline-neutral">&nbsp;</span>
833
- <span class="cline-any cline-neutral">&nbsp;</span>
834
- <span class="cline-any cline-neutral">&nbsp;</span>
835
- <span class="cline-any cline-neutral">&nbsp;</span>
836
- <span class="cline-any cline-neutral">&nbsp;</span>
837
- <span class="cline-any cline-neutral">&nbsp;</span>
838
- <span class="cline-any cline-no">&nbsp;</span>
839
- <span class="cline-any cline-no">&nbsp;</span>
840
- <span class="cline-any cline-no">&nbsp;</span>
841
- <span class="cline-any cline-no">&nbsp;</span>
842
- <span class="cline-any cline-neutral">&nbsp;</span>
843
- <span class="cline-any cline-neutral">&nbsp;</span>
844
- <span class="cline-any cline-neutral">&nbsp;</span>
845
- <span class="cline-any cline-neutral">&nbsp;</span>
846
- <span class="cline-any cline-yes">2x</span>
847
- <span class="cline-any cline-neutral">&nbsp;</span>
848
- <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import {
849
- Body,
850
- CanActivate,
851
- Controller,
852
- Delete,
853
- Get,
854
- Inject,
855
- Logger,
856
- OnModuleInit,
857
- Post,
858
- Req,
859
- Res,
860
- Type,
861
- UseGuards,
862
- applyDecorators,
863
- } from '@nestjs/common';
864
- import { ContextIdFactory, ModuleRef } from '@nestjs/core';
865
- import { randomUUID } from 'crypto';
866
- import type { Request, Response } from 'express';
867
- &nbsp;
868
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
869
- import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
870
- import { McpOptions } from '../interfaces';
871
- import { McpExecutorService } from '../services/mcp-executor.service';
872
- import { McpRegistryService } from '../services/mcp-registry.service';
873
- import { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';
874
- &nbsp;
875
- /**
876
- * Creates a controller for handling Streamable HTTP connections and tool executions
877
- */
878
- export function createStreamableHttpController(
879
- endpoint: string,
880
- globalApiPrefix: string,
881
- guards: Type&lt;CanActivate&gt;[] = [],
882
- decorators: ClassDecorator[] = [],
883
- ) {
884
- @Controller()
885
- @applyDecorators(...decorators)
886
- class StreamableHttpController implements OnModuleInit {
887
- public readonly <span class="cstat-no" title="statement not covered" >logger = new Logger(StreamableHttpController.name);</span>
888
- public <span class="cstat-no" title="statement not covered" >transports: { [sessionId: string]: StreamableHTTPServerTransport } =</span>
889
- {};
890
- public <span class="cstat-no" title="statement not covered" >mcpServers: { [sessionId: string]: McpServer } = {};</span>
891
- &nbsp;
892
- // Singleton instances for stateless mode
893
- public <span class="cstat-no" title="statement not covered" >statelessTransport: StreamableHTTPServerTransport | null = null;</span>
894
- public <span class="cstat-no" title="statement not covered" >statelessMcpServer: McpServer | null = null;</span>
895
- public <span class="cstat-no" title="statement not covered" >isStatelessMode: boolean = false;</span>
896
- &nbsp;
897
- <span class="fstat-no" title="function not covered" > constructor(</span>
898
- @Inject('MCP_OPTIONS') public readonly <span class="cstat-no" title="statement not covered" >options: McpOptions,</span>
899
- public readonly <span class="cstat-no" title="statement not covered" >moduleRef: M</span>oduleRef,
900
- public readonly <span class="cstat-no" title="statement not covered" >toolRegistry: M</span>cpRegistryService,
901
- ) {
902
- // Determine if we're in stateless mode
903
- <span class="cstat-no" title="statement not covered" > this.isStatelessMode = !!options.streamableHttp?.statelessMode;</span>
904
- &nbsp;
905
- // Initialize stateless mode if needed
906
- <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (this.isStatelessMode) {</span>
907
- <span class="cstat-no" title="statement not covered" > this.initializeStatelessMode()</span>
908
- .then(<span class="fstat-no" title="function not covered" >() =</span>&gt; {
909
- <span class="cstat-no" title="statement not covered" > this.logger.debug('Stateless mode initialized');</span>
910
- })
911
- .catch(<span class="fstat-no" title="function not covered" >(e</span>rror) =&gt; {
912
- <span class="cstat-no" title="statement not covered" > this.logger.error('Error initializing stateless mode:', error);</span>
913
- });
914
- }
915
- }
916
- &nbsp;
917
- /**
918
- * Initialize the stateless mode with singleton transport and server
919
- */
920
- public <span class="fstat-no" title="function not covered" >async </span>initializeStatelessMode(): Promise&lt;void&gt; {
921
- <span class="cstat-no" title="statement not covered" > this.logger.log('Initializing MCP Streamable HTTP in stateless mode');</span>
922
- &nbsp;
923
- // Create a singleton transport for all requests
924
- <span class="cstat-no" title="statement not covered" > this.statelessTransport = new StreamableHTTPServerTransport({</span>
925
- // statelessMode: true, // TODO: Uncomment when this PR is merged and released: https://github.com/modelcontextprotocol/typescript-sdk/pull/362
926
- sessionIdGenerator: <span class="fstat-no" title="function not covered" >() =</span>&gt; <span class="cstat-no" title="statement not covered" >undefined,</span>
927
- enableJsonResponse:
928
- this.options.streamableHttp?.enableJsonResponse || false,
929
- });
930
- &nbsp;
931
- // TODO: Remove when this PR is merged and released: https://github.com/modelcontextprotocol/typescript-sdk/pull/362
932
- (<span class="cstat-no" title="statement not covered" >this.statelessTransport as any)._initialized = true;</span>
933
- &nbsp;
934
- // Create a singleton MCP server instance
935
- <span class="cstat-no" title="statement not covered" > this.statelessMcpServer = new McpServer(</span>
936
- { name: this.options.name, version: this.options.version },
937
- {
938
- capabilities: this.options.capabilities || {
939
- tools: {},
940
- resources: {},
941
- resourceTemplates: {},
942
- prompts: {},
943
- },
944
- },
945
- );
946
- &nbsp;
947
- // Connect the transport to the MCP server
948
- <span class="cstat-no" title="statement not covered" > await this.statelessMcpServer.connect(this.statelessTransport);</span>
949
- }
950
- &nbsp;
951
- <span class="fstat-no" title="function not covered" > onModuleInit(</span>) {
952
- <span class="cstat-no" title="statement not covered" > this.logger.log(</span>
953
- `Initialized MCP Streamable HTTP controller at ${endpoint} in ${
954
- this.isStatelessMode ? 'stateless' : 'stateful'
955
- } mode`,
956
- );
957
- }
958
- &nbsp;
959
- /**
960
- * Main HTTP endpoint for both initialization and subsequent requests
961
- */
962
- @Post(endpoint)
963
- @UseGuards(...guards)
964
- <span class="fstat-no" title="function not covered" > async </span>handlePostRequest(
965
- @Req() req: Request,
966
- @Res() res: Response,
967
- @Body() body: unknown,
968
- ) {
969
- <span class="cstat-no" title="statement not covered" > this.logger.debug('Received MCP request:', body);</span>
970
- &nbsp;
971
- <span class="cstat-no" title="statement not covered" > try {</span>
972
- <span class="cstat-no" title="statement not covered" > if (this.isStatelessMode) {</span>
973
- <span class="cstat-no" title="statement not covered" > return this.handleStatelessRequest(req, res, body);</span>
974
- } else {
975
- <span class="cstat-no" title="statement not covered" > return this.handleStatefulRequest(req, res, body);</span>
976
- }
977
- } catch (error) {
978
- <span class="cstat-no" title="statement not covered" > this.logger.error('Error handling MCP request:', error);</span>
979
- <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!res.headersSent) {</span>
980
- <span class="cstat-no" title="statement not covered" > res.status(500).json({</span>
981
- jsonrpc: '2.0',
982
- error: {
983
- code: -32603,
984
- message: 'Internal server error',
985
- },
986
- id: null,
987
- });
988
- }
989
- }
990
- }
991
- &nbsp;
992
- /**
993
- * Handle requests in stateless mode
994
- */
995
- public <span class="fstat-no" title="function not covered" >async </span>handleStatelessRequest(
996
- req: Request,
997
- res: Response,
998
- body: unknown,
999
- ): Promise&lt;void&gt; {
1000
- <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!this.statelessTransport || !this.statelessMcpServer) {</span>
1001
- <span class="cstat-no" title="statement not covered" > await this.initializeStatelessMode();</span>
1002
- }
1003
- &nbsp;
1004
- // ToDo: This will likely change.
1005
- // Handle initialize requests directly
1006
- <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (this.isInitializeRequest(body)) {</span>
1007
- // Check and respond here
1008
- const acceptHeader = (<span class="cstat-no" title="statement not covered" >req.headers['accept'] as string) || '';</span>
1009
- const isEventStream = <span class="cstat-no" title="statement not covered" >acceptHeader.includes('text/event-stream');</span>
1010
- <span class="cstat-no" title="statement not covered" > if (isEventStream) {</span>
1011
- <span class="cstat-no" title="statement not covered" > res.setHeader('Content-Type', 'text/event-stream');</span>
1012
- <span class="cstat-no" title="statement not covered" > res.flushHeaders?.();</span>
1013
- } else {
1014
- <span class="cstat-no" title="statement not covered" > res.setHeader('Content-Type', 'application/json');</span>
1015
- }
1016
- const payload: JSONRPCMessage = <span class="cstat-no" title="statement not covered" >{</span>
1017
- jsonrpc: '2.0',
1018
- id: (body as any).id,
1019
- result: {
1020
- protocolVersion: '2024-11-05',
1021
- capabilities: this.options.capabilities || {},
1022
- instructions: this.options.instructions || '',
1023
- serverInfo: {
1024
- name: this.options.name,
1025
- version: this.options.version,
1026
- },
1027
- },
1028
- };
1029
- <span class="cstat-no" title="statement not covered" > if (isEventStream) {</span>
1030
- const messageId = <span class="cstat-no" title="statement not covered" >randomUUID() + '_' + Date.now();</span>
1031
- <span class="cstat-no" title="statement not covered" > res.write(</span>
1032
- 'event: message\nid: ' +
1033
- messageId +
1034
- '\ndata: ' +
1035
- JSON.stringify(payload) +
1036
- '\n\n',
1037
- );
1038
- <span class="cstat-no" title="statement not covered" > res.end();</span>
1039
- } else {
1040
- <span class="cstat-no" title="statement not covered" > res.json(payload);</span>
1041
- }
1042
- <span class="cstat-no" title="statement not covered" > return;</span>
1043
- }
1044
- &nbsp;
1045
- // Resolve the request-scoped tool executor service
1046
- const contextId = <span class="cstat-no" title="statement not covered" >ContextIdFactory.getByRequest(req);</span>
1047
- const executor = <span class="cstat-no" title="statement not covered" >await this.moduleRef.resolve(</span>
1048
- McpExecutorService,
1049
- contextId,
1050
- { strict: false },
1051
- );
1052
- &nbsp;
1053
- // Register request handlers with the user context from this specific request
1054
- <span class="cstat-no" title="statement not covered" > executor.registerRequestHandlers(this.statelessMcpServer!, req);</span>
1055
- &nbsp;
1056
- // Handle the request with the singleton transport
1057
- <span class="cstat-no" title="statement not covered" > await this.statelessTransport!.handleRequest(req, res, body);</span>
1058
- }
1059
- &nbsp;
1060
- /**
1061
- * Handle requests in stateful mode
1062
- */
1063
- public <span class="fstat-no" title="function not covered" >async </span>handleStatefulRequest(
1064
- req: Request,
1065
- res: Response,
1066
- body: unknown,
1067
- ): Promise&lt;void&gt; {
1068
- // Check for existing session ID
1069
- const sessionId = <span class="cstat-no" title="statement not covered" >req.headers['mcp-session-id'] as string | undefined;</span>
1070
- let transport: StreamableHTTPServerTransport;
1071
- &nbsp;
1072
- <span class="cstat-no" title="statement not covered" > if (sessionId &amp;&amp; this.transports[sessionId]) {</span>
1073
- // Reuse existing transport
1074
- <span class="cstat-no" title="statement not covered" > transport = this.transports[sessionId];</span>
1075
- } else <span class="cstat-no" title="statement not covered" >if (!sessionId &amp;&amp; this.isInitializeRequest(body)) {</span>
1076
- // New initialization request
1077
- <span class="cstat-no" title="statement not covered" > transport = new StreamableHTTPServerTransport({</span>
1078
- sessionIdGenerator:
1079
- this.options.streamableHttp?.sessionIdGenerator ||
1080
- (<span class="fstat-no" title="function not covered" >() =</span>&gt; <span class="cstat-no" title="statement not covered" >randomUUID())</span>,
1081
- enableJsonResponse:
1082
- this.options.streamableHttp?.enableJsonResponse || false,
1083
- });
1084
- &nbsp;
1085
- // Create a new MCP server for this session
1086
- const mcpServer = <span class="cstat-no" title="statement not covered" >new McpServer(</span>
1087
- { name: this.options.name, version: this.options.version },
1088
- {
1089
- capabilities: this.options.capabilities || {
1090
- tools: {},
1091
- resources: {},
1092
- resourceTemplates: {},
1093
- prompts: {},
1094
- },
1095
- },
1096
- );
1097
- &nbsp;
1098
- // Connect the transport to the MCP server BEFORE handling the request
1099
- <span class="cstat-no" title="statement not covered" > await mcpServer.connect(transport);</span>
1100
- &nbsp;
1101
- // Handle the initialization request
1102
- <span class="cstat-no" title="statement not covered" > await transport.handleRequest(req, res, body);</span>
1103
- &nbsp;
1104
- // Store the transport and server by session ID for future requests
1105
- <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (transport.sessionId) {</span>
1106
- <span class="cstat-no" title="statement not covered" > this.transports[transport.sessionId] = transport;</span>
1107
- <span class="cstat-no" title="statement not covered" > this.mcpServers[transport.sessionId] = mcpServer;</span>
1108
- &nbsp;
1109
- // Set up cleanup when connection closes
1110
- <span class="cstat-no" title="statement not covered" > transport.onclose = <span class="fstat-no" title="function not covered" >() =</span>&gt; {</span>
1111
- <span class="cstat-no" title="statement not covered" > this.cleanupSession(transport.sessionId!);</span>
1112
- };
1113
- }
1114
- &nbsp;
1115
- <span class="cstat-no" title="statement not covered" > this.logger.log(</span>
1116
- `Initialized new session with ID: ${transport.sessionId}`,
1117
- );
1118
- <span class="cstat-no" title="statement not covered" > return;</span>
1119
- } else {
1120
- // Invalid request - no session ID or not initialization request
1121
- <span class="cstat-no" title="statement not covered" > res.status(400).json({</span>
1122
- jsonrpc: '2.0',
1123
- error: {
1124
- code: -32000,
1125
- message: 'Bad Request: No valid session ID provided',
1126
- },
1127
- id: null,
1128
- });
1129
- <span class="cstat-no" title="statement not covered" > return;</span>
1130
- }
1131
- &nbsp;
1132
- // For subsequent requests to an existing session
1133
- const mcpServer = <span class="cstat-no" title="statement not covered" >this.mcpServers[sessionId];</span>
1134
- <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!mcpServer) {</span>
1135
- <span class="cstat-no" title="statement not covered" > res.status(404).json({</span>
1136
- jsonrpc: '2.0',
1137
- error: {
1138
- code: -32000,
1139
- message: 'Session not found',
1140
- },
1141
- id: null,
1142
- });
1143
- <span class="cstat-no" title="statement not covered" > return;</span>
1144
- }
1145
- &nbsp;
1146
- // Resolve the request-scoped tool executor service
1147
- const contextId = <span class="cstat-no" title="statement not covered" >ContextIdFactory.getByRequest(req);</span>
1148
- const executor = <span class="cstat-no" title="statement not covered" >await this.moduleRef.resolve(</span>
1149
- McpExecutorService,
1150
- contextId,
1151
- { strict: false },
1152
- );
1153
- &nbsp;
1154
- // Register request handlers with the user context from this specific request
1155
- <span class="cstat-no" title="statement not covered" > executor.registerRequestHandlers(mcpServer, req);</span>
1156
- &nbsp;
1157
- // Handle the request with existing transport
1158
- <span class="cstat-no" title="statement not covered" > await transport.handleRequest(req, res, body);</span>
1159
- }
1160
- &nbsp;
1161
- /**
1162
- * GET endpoint for SSE streams
1163
- */
1164
- @Get(endpoint)
1165
- @UseGuards(...guards)
1166
- <span class="fstat-no" title="function not covered" > async </span>handleGetRequest(@Req() req: Request, @Res() res: Response) {
1167
- <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (this.isStatelessMode) {</span>
1168
- <span class="cstat-no" title="statement not covered" > return this.handleStatelessRequest(req, res, req.body);</span>
1169
- }
1170
- &nbsp;
1171
- const sessionId = <span class="cstat-no" title="statement not covered" >req.headers['mcp-session-id'] as string | undefined;</span>
1172
- &nbsp;
1173
- <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!sessionId || !this.transports[sessionId]) {</span>
1174
- <span class="cstat-no" title="statement not covered" > res.status(400).send('Invalid or missing session ID');</span>
1175
- <span class="cstat-no" title="statement not covered" > return;</span>
1176
- }
1177
- &nbsp;
1178
- <span class="cstat-no" title="statement not covered" > this.logger.debug(`Establishing SSE stream for session ${sessionId}`);</span>
1179
- const transport = <span class="cstat-no" title="statement not covered" >this.transports[sessionId];</span>
1180
- <span class="cstat-no" title="statement not covered" > await transport.handleRequest(req, res);</span>
1181
- }
1182
- &nbsp;
1183
- /**
1184
- * DELETE endpoint for terminating sessions
1185
- */
1186
- @Delete(endpoint)
1187
- @UseGuards(...guards)
1188
- <span class="fstat-no" title="function not covered" > async </span>handleDeleteRequest(@Req() req: Request, @Res() res: Response) {
1189
- <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (this.isStatelessMode) {</span>
1190
- // In stateless mode, we don't have sessions to delete
1191
- <span class="cstat-no" title="statement not covered" > res.status(200).end();</span>
1192
- <span class="cstat-no" title="statement not covered" > return;</span>
1193
- }
1194
- &nbsp;
1195
- const sessionId = <span class="cstat-no" title="statement not covered" >req.headers['mcp-session-id'] as string | undefined;</span>
1196
- &nbsp;
1197
- <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!sessionId || !this.transports[sessionId]) {</span>
1198
- <span class="cstat-no" title="statement not covered" > res.status(400).send('Invalid or missing session ID');</span>
1199
- <span class="cstat-no" title="statement not covered" > return;</span>
1200
- }
1201
- &nbsp;
1202
- <span class="cstat-no" title="statement not covered" > this.logger.debug(`Terminating session ${sessionId}`);</span>
1203
- const transport = <span class="cstat-no" title="statement not covered" >this.transports[sessionId];</span>
1204
- <span class="cstat-no" title="statement not covered" > await transport.handleRequest(req, res);</span>
1205
- <span class="cstat-no" title="statement not covered" > this.cleanupSession(sessionId);</span>
1206
- }
1207
- &nbsp;
1208
- // Helper function to detect initialize requests
1209
- public <span class="fstat-no" title="function not covered" >isInitializeRequest(</span>body: unknown): boolean {
1210
- <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (Array.isArray(body)) {</span>
1211
- <span class="cstat-no" title="statement not covered" > return body.some(</span>
1212
- <span class="fstat-no" title="function not covered" > (m</span>sg) =&gt;
1213
- <span class="cstat-no" title="statement not covered" > typeof msg === 'object' &amp;&amp;</span>
1214
- msg !== null &amp;&amp;
1215
- 'method' in msg &amp;&amp;
1216
- msg.method === 'initialize',
1217
- );
1218
- }
1219
- <span class="cstat-no" title="statement not covered" > return (</span>
1220
- typeof body === 'object' &amp;&amp;
1221
- body !== null &amp;&amp;
1222
- 'method' in body &amp;&amp;
1223
- body.method === 'initialize'
1224
- );
1225
- }
1226
- &nbsp;
1227
- // Clean up session resources
1228
- public <span class="fstat-no" title="function not covered" >cleanupSession(</span>sessionId: string): void {
1229
- <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (sessionId) {</span>
1230
- <span class="cstat-no" title="statement not covered" > this.logger.debug(`Cleaning up session: ${sessionId}`);</span>
1231
- <span class="cstat-no" title="statement not covered" > delete this.transports[sessionId];</span>
1232
- <span class="cstat-no" title="statement not covered" > delete this.mcpServers[sessionId];</span>
1233
- }
1234
- }
1235
- }
1236
- &nbsp;
1237
- return StreamableHttpController;
1238
- }
1239
- &nbsp;</pre></td></tr></table></pre>
1240
-
1241
- <div class='push'></div><!-- for sticky footer -->
1242
- </div><!-- /wrapper -->
1243
- <div class='footer quiet pad2 space-top1 center small'>
1244
- Code coverage generated by
1245
- <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
1246
- at 2025-04-26T05:28:42.460Z
1247
- </div>
1248
- <script src="../prettify.js"></script>
1249
- <script>
1250
- window.onload = function () {
1251
- prettyPrint();
1252
- };
1253
- </script>
1254
- <script src="../sorter.js"></script>
1255
- <script src="../block-navigation.js"></script>
1256
- </body>
1257
- </html>
1258
-