@@ -45,10 +45,10 @@ export class ApiParser {
4545 if ( typeof response . data === "string" ) {
4646 try {
4747 spec = JSON . parse ( response . data ) ;
48- } catch ( jsonError ) {
48+ } catch {
4949 try {
5050 spec = YAML . parse ( response . data ) ;
51- } catch ( yamlError ) {
51+ } catch {
5252 throw new Error (
5353 "Invalid OpenAPI specification from URL: must be valid JSON or YAML format" ,
5454 ) ;
@@ -62,10 +62,10 @@ export class ApiParser {
6262 // Try to parse as JSON first, then fall back to YAML
6363 try {
6464 spec = JSON . parse ( specUrlOrJson ) ;
65- } catch ( jsonError ) {
65+ } catch {
6666 try {
6767 spec = YAML . parse ( specUrlOrJson ) ;
68- } catch ( yamlError ) {
68+ } catch {
6969 throw new Error (
7070 "Invalid OpenAPI specification: must be valid JSON or YAML format" ,
7171 ) ;
@@ -154,10 +154,14 @@ export class ApiParser {
154154 endpoints . push ( currentEndpoint ) ;
155155 }
156156
157+ const method = methodMatch [ 1 ] . toUpperCase ( ) ;
158+ const path = methodMatch [ 2 ] . trim ( ) ;
159+
157160 currentEndpoint = {
158- method : methodMatch [ 1 ] . toUpperCase ( ) ,
159- path : methodMatch [ 2 ] . trim ( ) ,
161+ method,
162+ path,
160163 description : methodMatch [ 3 ] . trim ( ) ,
164+ operationId : this . generateOperationId ( method , path ) ,
161165 parameters : [ ] ,
162166 } ;
163167 continue ;
@@ -602,11 +606,13 @@ export class ApiParser {
602606 : item . request . url . raw ;
603607
604608 const path = this . extractPath ( url ) ;
609+ const method = item . request . method ;
605610
606611 endpoints . push ( {
607612 path,
608- method : item . request . method ,
613+ method,
609614 description : item . name || "" ,
615+ operationId : this . generateOperationId ( method , path ) ,
610616 parameters : this . extractPostmanParameters ( item . request ) ,
611617 } ) ;
612618 }
@@ -617,6 +623,41 @@ export class ApiParser {
617623 }
618624 }
619625
626+ /**
627+ * Generate operationId from method and path
628+ * e.g., GET /submissions -> getSubmissions
629+ * e.g., POST /submissions/{id}/documents -> postSubmissionsIdDocuments
630+ */
631+ private generateOperationId ( method : string , path : string ) : string {
632+ // Convert method to lowercase
633+ const methodLower = method . toLowerCase ( ) ;
634+
635+ // Clean and convert path to camelCase
636+ // Remove leading slash and split by /
637+ const pathParts = path
638+ . replace ( / ^ \/ / , "" ) // Remove leading slash
639+ . split ( "/" )
640+ . filter ( ( part ) => part . length > 0 ) // Remove empty parts
641+ . map ( ( part ) => {
642+ // Replace path parameters {id} with just "id"
643+ if ( part . startsWith ( "{" ) && part . endsWith ( "}" ) ) {
644+ return part . slice ( 1 , - 1 ) ;
645+ }
646+ // Replace hyphens and underscores with spaces for proper casing
647+ return part . replace ( / [ - _ ] / g, " " ) ;
648+ } )
649+ . map ( ( part ) => {
650+ // Convert to title case for all parts
651+ return part
652+ . split ( " " )
653+ . map ( ( word ) => word . charAt ( 0 ) . toUpperCase ( ) + word . slice ( 1 ) )
654+ . join ( "" ) ;
655+ } )
656+ . join ( "" ) ;
657+
658+ return methodLower + ( pathParts || "Root" ) ;
659+ }
660+
620661 /**
621662 * Extract path from URL
622663 */
0 commit comments