@@ -47,106 +47,91 @@ interface GitHubFileInfo {
4747}
4848
4949/**
50- * Helper function to validate if a URL is a GitHub blob URL
50+ * Custom GitHub URL resolver for private repositories
5151 */
52- const isValidGitHubBlobUrl = ( url : string ) : boolean => {
53- try {
54- const parsedUrl = new URL ( url ) ;
55- return (
56- parsedUrl . hostname === 'github.com' &&
57- parsedUrl . pathname . split ( '/' ) [ 3 ] === 'blob'
58- ) ;
59- } catch ( error ) {
60- return false ;
61- }
62- } ;
63-
64- /**
65- * Convert GitHub web URL to API URL
66- */
67- const convertGitHubWebUrl = ( url : string ) : string => {
68- // Remove fragment from URL before processing
69- const urlWithoutFragment = url . split ( '#' ) [ 0 ] ;
70-
71- // Handle GitHub web URLs like: https://github.com/owner/repo/blob/branch/path
72- // eslint-disable-next-line no-useless-escape
73- const githubWebPattern = / ^ h t t p s : \/ \/ g i t h u b \. c o m \/ ( [ ^ \/ ] + ) \/ ( [ ^ \/ ] + ) \/ b l o b \/ ( [ ^ \/ ] + ) \/ ( .+ ) $ / ;
74- const match = urlWithoutFragment . match ( githubWebPattern ) ;
75-
76- if ( match ) {
77- const [ , owner , repo , branch , filePath ] = match ;
78- return `https://api.github.com/repos/${ owner } /${ repo } /contents/${ filePath } ?ref=${ branch } ` ;
79- }
80-
81- return url ;
82- } ;
83-
84- /**
85- * Custom resolver for private repositories
86- */
87- const createHttpWithAuthResolver = ( ) => ( {
52+ const createGitHubResolver = ( ) => ( {
8853 schema : 'https' ,
8954 order : 1 ,
9055
56+ canRead : ( uri : any ) => {
57+ try {
58+ const url = new URL ( uri . toString ( ) ) ;
59+ return url . hostname === 'raw.githubusercontent.com' ||
60+ url . hostname === 'github.com' ||
61+ url . hostname === 'api.github.com' ;
62+ } catch ( error ) {
63+ return false ;
64+ }
65+ } ,
66+
67+ /**
68+ * Convert GitHub web URL to API URL
69+ */
70+ convertGitHubWebUrl : ( url : string ) : string => {
71+ // Remove fragment from URL before processing
72+ const urlWithoutFragment = url . split ( '#' ) [ 0 ] ;
73+
74+ // Handle GitHub web URLs like: https://github.com/owner/repo/blob/branch/path
75+ // eslint-disable-next-line no-useless-escape
76+ const githubWebPattern = / ^ h t t p s : \/ \/ g i t h u b \. c o m \/ ( [ ^ \/ ] + ) \/ ( [ ^ \/ ] + ) \/ b l o b \/ ( [ ^ \/ ] + ) \/ ( .+ ) $ / ;
77+ const match = urlWithoutFragment . match ( githubWebPattern ) ;
78+
79+ if ( match ) {
80+ const [ , owner , repo , branch , path ] = match ;
81+ return `https://api.github.com/repos/${ owner } /${ repo } /contents/${ path } ?ref=${ branch } ` ;
82+ }
83+ return url ;
84+ } ,
85+
9186 read : async ( uri : any ) => {
9287 let url = uri . toString ( ) ;
93-
88+ const originalUrl = url ;
89+
9490 // Default headers
9591 const headers : Record < string , string > = {
96- 'User-Agent' : 'AsyncAPI-CLI' ,
92+ 'User-Agent' : 'AsyncAPI-CLI'
9793 } ;
9894
9995 const authInfo = await ConfigService . getAuthForUrl ( url ) ;
10096
101- if ( isValidGitHubBlobUrl ( url ) ) {
102- url = convertGitHubWebUrl ( url ) ;
97+ if ( url . includes ( 'github.com' ) && url . includes ( '/blob/' ) ) {
98+ url = createGitHubResolver ( ) . convertGitHubWebUrl ( url ) ;
10399 }
104-
105- // Only require authentication for GitHub URLs
100+
106101 if ( authInfo ) {
107102 headers [ 'Authorization' ] = `${ authInfo . authType } ${ authInfo . token } ` ;
108103 Object . assign ( headers , authInfo . headers ) ; // merge custom headers
104+ } else {
105+ throw new Error ( `Cannot resolve URL: ${ url } - No authentication configured for this GitHub repository` ) ;
109106 }
110107
111108 if ( url . includes ( 'api.github.com' ) ) {
112109 headers [ 'Accept' ] = 'application/vnd.github.v3+json' ;
113110 const res = await fetch ( url , { headers } ) ;
114111 if ( ! res . ok ) {
115- throw new Error (
116- `Failed to fetch GitHub API URL: ${ url } - ${ res . statusText } `
117- ) ;
112+ throw new Error ( `Failed to fetch GitHub API URL: ${ url } - ${ res . statusText } ` ) ;
118113 }
119- const fileInfo = ( await res . json ( ) ) as GitHubFileInfo ;
114+ const fileInfo = await res . json ( ) as GitHubFileInfo ;
120115
121116 if ( fileInfo . download_url ) {
122117 const contentRes = await fetch ( fileInfo . download_url , { headers } ) ;
123118 if ( ! contentRes . ok ) {
124- throw new Error (
125- `Failed to fetch content from download URL: ${ fileInfo . download_url } - ${ contentRes . statusText } `
126- ) ;
119+ throw new Error ( `Failed to fetch content from download URL: ${ fileInfo . download_url } - ${ contentRes . statusText } ` ) ;
127120 }
128121 return await contentRes . text ( ) ;
129122 }
130- throw new Error (
131- `No download URL found in GitHub API response for: ${ url } `
132- ) ;
123+ throw new Error ( `No download URL found in GitHub API response for: ${ url } ` ) ;
133124 } else if ( url . includes ( 'raw.githubusercontent.com' ) ) {
134125 headers [ 'Accept' ] = 'application/vnd.github.v3.raw' ;
135126 const res = await fetch ( url , { headers } ) ;
136127 if ( ! res . ok ) {
137- throw new Error (
138- `Failed to fetch GitHub URL: ${ url } - ${ res . statusText } `
139- ) ;
128+ throw new Error ( `Failed to fetch GitHub URL: ${ url } - ${ res . statusText } ` ) ;
140129 }
141130 return await res . text ( ) ;
142131 } else {
143- const res = await fetch ( url , { headers } ) ;
144- if ( ! res . ok ) {
145- throw new Error ( `Failed to fetch URL: ${ url } - ${ res . statusText } ` ) ;
146- }
147- return await res . text ( ) ;
132+ throw new Error ( `Unsupported GitHub URL format: ${ originalUrl } ` ) ;
148133 }
149- } ,
134+ }
150135} ) ;
151136
152137const { writeFile } = promises ;
@@ -188,7 +173,7 @@ export class ValidationService extends BaseService {
188173 resolver : {
189174 cache : false ,
190175 resolvers : [
191- createHttpWithAuthResolver ( ) ,
176+ createGitHubResolver ( ) ,
192177 ...( parserOptions . __unstable ?. resolver ?. resolvers || [ ] )
193178 ] ,
194179 } ,
@@ -318,7 +303,7 @@ export class ValidationService extends BaseService {
318303 __unstable : {
319304 resolver : {
320305 cache : false ,
321- resolvers : [ createHttpWithAuthResolver ( ) ] ,
306+ resolvers : [ createGitHubResolver ( ) ] ,
322307 } ,
323308 } ,
324309 } ) ;
@@ -516,4 +501,4 @@ export class ValidationService extends BaseService {
516501 return 'Unknown' ;
517502 }
518503 }
519- }
504+ }
0 commit comments