@@ -5,15 +5,11 @@ import (
55 _ "embed"
66 "errors"
77 "fmt"
8- "io"
98 "mokapi/js/compiler"
109 "mokapi/js/faker"
1110 "mokapi/providers/openapi"
12- "mokapi/providers/openapi/schema"
1311 "mokapi/runtime"
1412 "mokapi/schema/json/generator"
15- "net/http"
16- "net/textproto"
1713 "reflect"
1814 "slices"
1915 "strings"
@@ -137,32 +133,38 @@ func (m *mokapi) getApis() []ApiSummary {
137133 var result []ApiSummary
138134 for _ , api := range m .app .ListHttp () {
139135 if api .Info .Name == "" {
140- log .Warnf ("mcp tool mokapi_get_api_spec : skip empty HTTTP API name" )
136+ log .Warnf ("mcp tool mokapi_execute_code : skip empty HTTTP API name" )
141137 continue
142138 }
143139 result = append (result , ApiSummary {
144140 Name : api .Info .Name ,
145141 Type : "http" ,
146142 })
147143 }
144+ for _ , api := range m .app .Kafka .List () {
145+ if api .Info .Name == "" {
146+ log .Warnf ("mcp tool mokapi_execute_code: skip empty Kafka API name" )
147+ continue
148+ }
149+ result = append (result , ApiSummary {
150+ Name : api .Info .Name ,
151+ Type : "kafka" ,
152+ })
153+ }
148154 slices .SortStableFunc (result , func (a , b ApiSummary ) int {
149155 return strings .Compare (a .Name , b .Name )
150156 })
151157 return result
152158}
153159
154160func (m * mokapi ) getApi (name string ) any {
155- for _ , api := range m .app .ListHttp () {
156- if api .Info .Name == name {
157- return & OpenAPI {
158- Name : name ,
159- Type : "http" ,
160- info : api ,
161- handler : api .Handler (m .app .Monitor .Http , m .app .Engine , m .app .Events ),
162- }
163- }
161+ var api any
162+ api = m .getHttpApi (name )
163+ if api != nil {
164+ return api
164165 }
165- return nil
166+ api = m .getKafkaApi (name )
167+ return api
166168}
167169
168170func (m * mokapi ) fake (v goja.Value ) (any , error ) {
@@ -173,279 +175,6 @@ func (m *mokapi) fake(v goja.Value) (any, error) {
173175 return generator .New (& generator.Request {Schema : js })
174176}
175177
176- type OpenAPI struct {
177- Name string `json:"name"`
178- Type string `json:"type"`
179-
180- info * runtime.HttpInfo
181- handler openapi.Handler
182- }
183-
184- type OperationSummary struct {
185- Id string `json:"id"`
186- Method string `json:"method"`
187- Path string `json:"path"`
188- Summary string `json:"summary"`
189- Parameters []string `json:"parameters"`
190- }
191-
192- type Operation struct {
193- OperationId string `json:"operationId"`
194- Method string `json:"method"`
195- Path string `json:"path"`
196- Summary string `json:"summary"`
197- Description string `json:"description,omitempty"`
198- Parameters []RequestParameters `json:"parameters,omitempty"`
199- RequestBody RequestBody `json:"requestBody,omitempty"`
200-
201- spec * openapi.Operation
202- handler openapi.Handler
203- }
204-
205- type RequestParameters struct {
206- Name string `json:"name"`
207- In string `json:"in"`
208- Required bool `json:"required"`
209- Schema * schema.Schema
210- Description string `json:"description,omitempty"`
211- }
212-
213- type RequestBody struct {
214- Description string `json:"description,omitempty"`
215- Required bool `json:"required"`
216- Contents []Content `json:"contents"`
217- }
218-
219- type Content struct {
220- ContentType string `json:"contentType"`
221- Schema * schema.Schema `json:"schema"`
222- }
223-
224- type Response struct {
225- StatusCode int `json:"statusCode"`
226- Description string `json:"description,omitempty"`
227- Content []Content `json:"content"`
228- }
229-
230- func (o * OpenAPI ) GetOperations () []OperationSummary {
231- var result []OperationSummary
232- for _ , p := range o .info .Paths {
233- if p .Value == nil {
234- continue
235- }
236- for method , op := range p .Value .Operations () {
237- os := OperationSummary {
238- Id : getOperationId (method , op ),
239- Method : method ,
240- Path : p .Value .Path ,
241- Summary : op .Summary ,
242- }
243-
244- if os .Summary == "" {
245- os .Summary = p .Value .Summary
246- }
247-
248- params := append (op .Path .Parameters , op .Parameters ... )
249- for _ , param := range params {
250- if param .Value == nil {
251- continue
252- }
253- os .Parameters = append (os .Parameters , param .Value .Name )
254- }
255- slices .SortStableFunc (os .Parameters , func (a , b string ) int {
256- return strings .Compare (a , b )
257- })
258-
259- result = append (result , os )
260- }
261- }
262-
263- slices .SortStableFunc (result , func (a , b OperationSummary ) int {
264- c := strings .Compare (a .Path , b .Path )
265- if c != 0 {
266- return c
267- }
268- return strings .Compare (a .Method , b .Method )
269- })
270-
271- return result
272- }
273-
274- func (o * OpenAPI ) GetOperation (id string ) (* Operation , error ) {
275- for _ , p := range o .info .Paths {
276- if p .Value == nil {
277- continue
278- }
279- for method , op := range p .Value .Operations () {
280-
281- operationId := getOperationId (method , op )
282- if id != operationId {
283- continue
284- }
285-
286- r := & Operation {
287- OperationId : operationId ,
288- Method : method ,
289- Path : p .Value .Path ,
290- Summary : op .Summary ,
291- Description : op .Description ,
292- spec : op ,
293- handler : o .handler ,
294- }
295- for _ , param := range op .Parameters {
296- if param .Value == nil {
297- continue
298- }
299- r .Parameters = append (r .Parameters , RequestParameters {
300- Name : param .Value .Name ,
301- In : param .Value .Type .String (),
302- Required : param .Value .Required ,
303- Schema : param .Value .Schema ,
304- Description : param .Value .Description ,
305- })
306- }
307- slices .SortStableFunc (r .Parameters , func (a , b RequestParameters ) int {
308- return strings .Compare (a .Name , b .Name )
309- })
310-
311- if op .RequestBody != nil && op .RequestBody .Value != nil {
312- r .RequestBody = RequestBody {
313- Description : op .RequestBody .Value .Description ,
314- Required : op .RequestBody .Value .Required ,
315- }
316- for ct , content := range op .RequestBody .Value .Content {
317- r .RequestBody .Contents = append (r .RequestBody .Contents , Content {
318- ContentType : ct ,
319- Schema : content .Schema ,
320- })
321- }
322- }
323- return r , nil
324- }
325- }
326- return nil , fmt .Errorf ("operation with ID '%s' not found. Hint: Use getOperations() to see the full list of valid IDs" , id )
327- }
328-
329- func (op * Operation ) GetResponseSchema (statusCode int ) * Response {
330- r := op .spec .Responses .GetResponse (statusCode )
331- if r == nil {
332- return nil
333- }
334- result := & Response {
335- StatusCode : statusCode ,
336- Description : r .Description ,
337- }
338- for ct , content := range r .Content {
339- result .Content = append (result .Content , Content {
340- ContentType : ct ,
341- Schema : content .Schema ,
342- })
343- }
344- return result
345- }
346-
347- type InvokeRequest struct {
348- Path map [string ]string `json:"path"`
349- Query map [string ]string `json:"query"`
350- Header map [string ][]string `json:"header"`
351- Body string `json:"body"`
352- }
353-
354- type InvokeResponse struct {
355- StatusCode int `json:"statusCode"`
356- Headers map [string ][]string `json:"headers"`
357- Body string `json:"body"`
358- }
359-
360- func (op * Operation ) Invoke (req InvokeRequest ) (InvokeResponse , error ) {
361- result := InvokeResponse {Headers : make (map [string ][]string )}
362-
363- var body io.Reader
364- if req .Body != "" {
365- body = strings .NewReader (req .Body )
366- }
367-
368- path := op .Path
369- query := ""
370- params := append (op .spec .Path .Parameters , op .spec .Parameters ... )
371- for _ , p := range params {
372- if p .Value == nil {
373- continue
374- }
375- switch p .Value .Type {
376- case openapi .ParameterPath :
377- if req .Path == nil {
378- return result , fmt .Errorf ("invoke request %s %s failed: missing path parameter '%s'" , op .Method , op .Path , p .Value .Name )
379- }
380- val , ok := req .Path [p .Value .Name ]
381- if ! ok {
382- return result , fmt .Errorf ("invoke request %s %s failed: missing path parameter '%s'" , op .Method , op .Path , p .Value .Name )
383- }
384- path = strings .ReplaceAll (path , fmt .Sprintf ("{%s}" , p .Value .Name ), val )
385- case openapi .ParameterQuery :
386- if req .Query == nil && p .Value .Required {
387- return result , fmt .Errorf ("invoke request %s %s failed: missing query parameter '%s'" , op .Method , op .Path , p .Value .Name )
388- }
389- val , ok := req .Query [p .Value .Name ]
390- if ! ok {
391- if ! p .Value .Required {
392- continue
393- }
394- return result , fmt .Errorf ("invoke request %s %s failed: missing query parameter '%s'" , op .Method , op .Path , p .Value .Name )
395- }
396- if query != "" {
397- query += "&"
398- }
399- query += fmt .Sprintf ("%s=%s" , p .Value .Name , val )
400- }
401- }
402-
403- if query != "" {
404- path += "?" + query
405- }
406-
407- r , err := http .NewRequest (op .Method , path , body )
408- if err != nil {
409- return result , fmt .Errorf ("error creating request: %w" , err )
410- }
411- for _ , p := range params {
412- if p .Value == nil || p .Value .Type != openapi .ParameterHeader {
413- continue
414- }
415- if req .Header == nil && p .Value .Required {
416- return result , fmt .Errorf ("invoke request %s %s failed: missing header parameter '%s'" , op .Method , op .Path , p .Value .Name )
417- }
418- val , ok := req .Header [p .Value .Name ]
419- if ! ok {
420- if ! p .Value .Required {
421- continue
422- }
423- return result , fmt .Errorf ("invoke request %s %s failed: missing header parameter '%s'" , op .Method , op .Path , p .Value .Name )
424- }
425- r .Header [textproto .CanonicalMIMEHeaderKey (p .Value .Name )] = val
426- }
427-
428- he := op .handler .ServeHTTP (& result , r )
429- if he != nil {
430- result .StatusCode = he .StatusCode
431- result .Body = he .Message
432- }
433- return result , nil
434- }
435-
436- func (r * InvokeResponse ) Header () http.Header {
437- return r .Headers
438- }
439-
440- func (r * InvokeResponse ) WriteHeader (statusCode int ) {
441- r .StatusCode = statusCode
442- }
443-
444- func (r * InvokeResponse ) Write (body []byte ) (int , error ) {
445- r .Body = string (body )
446- return len (body ), nil
447- }
448-
449178type customFieldNameMapper struct {
450179}
451180
0 commit comments