@ -320,11 +320,31 @@ async function fetchFromGitLab(owner: string, repo: string, baseUrl: string): Pr
const projectPath = ` ${ owner } / ${ repo } ` ;
const projectPath = ` ${ owner } / ${ repo } ` ;
const encodedPath = encodeURIComponent ( projectPath ) ;
const encodedPath = encodeURIComponent ( projectPath ) ;
const [ repoData , branchesData , commitsData ] = await Promise . all ( [
// Use proxy endpoint to avoid CORS issues
fetch ( ` ${ baseUrl } /projects/ ${ encodedPath } ` ) . then ( r = > r . json ( ) ) ,
const [ repoResponse , branchesResponse , commitsResponse ] = await Promise . all ( [
fetch ( ` ${ baseUrl } /projects/ ${ encodedPath } /repository/branches ` ) . then ( r = > r . json ( ) ) ,
fetch ( ` /api/gitea-proxy/projects/ ${ encodedPath } ?baseUrl= ${ encodeURIComponent ( baseUrl ) } ` ) ,
fetch ( ` ${ baseUrl } /projects/ ${ encodedPath } /repository/commits?per_page=10 ` ) . then ( r = > r . json ( ) )
fetch ( ` /api/gitea-proxy/projects/ ${ encodedPath } /repository/branches?baseUrl= ${ encodeURIComponent ( baseUrl ) } ` ) ,
fetch ( ` /api/gitea-proxy/projects/ ${ encodedPath } /repository/commits?baseUrl= ${ encodeURIComponent ( baseUrl ) } &per_page=10 ` )
] ) ;
] ) ;
if ( ! repoResponse . ok ) {
console . warn ( ` GitLab API error for repo ${ owner } / ${ repo } : ${ repoResponse . status } ${ repoResponse . statusText } ` ) ;
return null ;
}
const repoData = await repoResponse . json ( ) ;
let branchesData : any [ ] = [ ] ;
let commitsData : any [ ] = [ ] ;
if ( branchesResponse . ok ) {
const data = await branchesResponse . json ( ) ;
branchesData = Array . isArray ( data ) ? data : [ ] ;
}
if ( commitsResponse . ok ) {
const data = await commitsResponse . json ( ) ;
commitsData = Array . isArray ( data ) ? data : [ ] ;
}
const branches : GitBranch [ ] = branchesData . map ( ( b : any ) = > ( {
const branches : GitBranch [ ] = branchesData . map ( ( b : any ) = > ( {
name : b.name ,
name : b.name ,
@ -346,7 +366,7 @@ async function fetchFromGitLab(owner: string, repo: string, baseUrl: string): Pr
// Fetch file tree
// Fetch file tree
let files : GitFile [ ] = [ ] ;
let files : GitFile [ ] = [ ] ;
try {
try {
const treeData = await fetch ( ` ${ baseUrl } /projects/ ${ encodedPath } /repository/tree? recursive=true&per_page=100` ) . then ( r = > r . json ( ) ) ;
const treeData = await fetch ( ` /api/gitea-proxy/projects/ ${ encodedPath } /repository/tree?baseUrl= ${ encodeURIComponent ( baseUrl ) } & recursive=true&per_page=100` ) . then ( r = > r . json ( ) ) ;
files = treeData . map ( ( item : any ) = > ( {
files = treeData . map ( ( item : any ) = > ( {
name : item.name ,
name : item.name ,
path : item.path ,
path : item.path ,
@ -363,7 +383,7 @@ async function fetchFromGitLab(owner: string, repo: string, baseUrl: string): Pr
const readmeFiles = [ 'README.adoc' , 'README.md' , 'README.rst' , 'README.txt' ] ;
const readmeFiles = [ 'README.adoc' , 'README.md' , 'README.rst' , 'README.txt' ] ;
for ( const readmeFile of readmeFiles ) {
for ( const readmeFile of readmeFiles ) {
try {
try {
const fileData = await fetch ( ` ${ baseUrl } /projects/ ${ encodedPath } /repository/files/ ${ encodeURIComponent ( readmeFile ) } /raw?ref= ${ repoData . default_branch } ` ) . then ( r = > {
const fileData = await fetch ( ` /api/gitea-proxy /projects/${ encodedPath } /repository/files/ ${ encodeURIComponent ( readmeFile ) } /raw?baseUrl= ${ encodeURIComponent ( baseUrl ) } & ref= ${ repoData . default_branch } ` ) . then ( r = > {
if ( ! r . ok ) throw new Error ( 'Not found' ) ;
if ( ! r . ok ) throw new Error ( 'Not found' ) ;
return r . text ( ) ;
return r . text ( ) ;
} ) ;
} ) ;
@ -398,7 +418,7 @@ async function fetchFromGitLab(owner: string, repo: string, baseUrl: string): Pr
// If found in tree, fetch it
// If found in tree, fetch it
if ( readmePath ) {
if ( readmePath ) {
try {
try {
const fileData = await fetch ( ` ${ baseUrl } /projects/ ${ encodedPath } /repository/files/ ${ encodeURIComponent ( readmePath ) } /raw?ref= ${ repoData . default_branch } ` ) . then ( r = > {
const fileData = await fetch ( ` /api/gitea-proxy /projects/${ encodedPath } /repository/files/ ${ encodeURIComponent ( readmePath ) } /raw?baseUrl= ${ encodeURIComponent ( baseUrl ) } & ref= ${ repoData . default_branch } ` ) . then ( r = > {
if ( ! r . ok ) throw new Error ( 'Not found' ) ;
if ( ! r . ok ) throw new Error ( 'Not found' ) ;
return r . text ( ) ;
return r . text ( ) ;
} ) ;
} ) ;
@ -436,8 +456,7 @@ async function fetchFromGitLab(owner: string, repo: string, baseUrl: string): Pr
async function fetchFromGitea ( owner : string , repo : string , baseUrl : string ) : Promise < GitRepoInfo | null > {
async function fetchFromGitea ( owner : string , repo : string , baseUrl : string ) : Promise < GitRepoInfo | null > {
try {
try {
// Use proxy endpoint to avoid CORS issues
// Use proxy endpoint to avoid CORS issues
const proxyBaseUrl = encodeURIComponent ( baseUrl ) ;
const repoResponse = await fetch ( ` /api/gitea-proxy/repos/ ${ owner } / ${ repo } ?baseUrl= ${ encodeURIComponent ( baseUrl ) } ` ) ;
const repoResponse = await fetch ( ` /api/gitea-proxy/ ${ proxyBaseUrl } /repos/ ${ owner } / ${ repo } ` ) ;
if ( ! repoResponse . ok ) {
if ( ! repoResponse . ok ) {
console . warn ( ` Gitea API error for repo ${ owner } / ${ repo } : ${ repoResponse . status } ${ repoResponse . statusText } ` ) ;
console . warn ( ` Gitea API error for repo ${ owner } / ${ repo } : ${ repoResponse . status } ${ repoResponse . statusText } ` ) ;
return null ;
return null ;
@ -447,8 +466,8 @@ async function fetchFromGitea(owner: string, repo: string, baseUrl: string): Pro
const defaultBranch = repoData . default_branch || 'master' ;
const defaultBranch = repoData . default_branch || 'master' ;
const [ branchesResponse , commitsResponse ] = await Promise . all ( [
const [ branchesResponse , commitsResponse ] = await Promise . all ( [
fetch ( ` /api/gitea-proxy/ ${ proxyBaseUrl } / repos/${ owner } / ${ repo } /branches ` ) . catch ( ( ) = > null ) ,
fetch ( ` /api/gitea-proxy/repos/ ${ owner } / ${ repo } /branches?baseUrl= ${ encodeURIComponent ( baseUrl ) } ` ) . catch ( ( ) = > null ) ,
fetch ( ` /api/gitea-proxy/ ${ proxyBaseUrl } / repos/${ owner } / ${ repo } /commits?limit=10 ` ) . catch ( ( ) = > null )
fetch ( ` /api/gitea-proxy/repos/ ${ owner } / ${ repo } /commits?baseUrl= ${ encodeURIComponent ( baseUrl ) } & limit=10 ` ) . catch ( ( ) = > null )
] ) ;
] ) ;
let branchesData : any [ ] = [ ] ;
let branchesData : any [ ] = [ ] ;
@ -501,7 +520,7 @@ async function fetchFromGitea(owner: string, repo: string, baseUrl: string): Pro
let files : GitFile [ ] = [ ] ;
let files : GitFile [ ] = [ ] ;
try {
try {
// Try the git/trees endpoint first (more complete)
// Try the git/trees endpoint first (more complete)
const treeResponse = await fetch ( ` /api/gitea-proxy/ ${ proxyBaseUrl } / repos/${ owner } / ${ repo } /git/trees/ ${ defaultBranch } ?recursive=1 ` ) . catch ( ( ) = > null ) ;
const treeResponse = await fetch ( ` /api/gitea-proxy/repos/ ${ owner } / ${ repo } /git/trees/ ${ defaultBranch } ?baseUrl= ${ encodeURIComponent ( baseUrl ) } & recursive=1 ` ) . catch ( ( ) = > null ) ;
if ( treeResponse && treeResponse . ok ) {
if ( treeResponse && treeResponse . ok ) {
const treeData = await treeResponse . json ( ) ;
const treeData = await treeResponse . json ( ) ;
if ( treeData . tree && Array . isArray ( treeData . tree ) ) {
if ( treeData . tree && Array . isArray ( treeData . tree ) ) {
@ -516,7 +535,7 @@ async function fetchFromGitea(owner: string, repo: string, baseUrl: string): Pro
}
}
} else {
} else {
// Fallback to contents endpoint (only root directory)
// Fallback to contents endpoint (only root directory)
const contentsResponse = await fetch ( ` /api/gitea-proxy/ ${ proxyBaseUrl } / repos/${ owner } / ${ repo } /contents?ref= ${ defaultBranch } ` ) . catch ( ( ) = > null ) ;
const contentsResponse = await fetch ( ` /api/gitea-proxy/repos/ ${ owner } / ${ repo } /contents?baseUrl= ${ encodeURIComponent ( baseUrl ) } & ref= ${ defaultBranch } ` ) . catch ( ( ) = > null ) ;
if ( contentsResponse && contentsResponse . ok ) {
if ( contentsResponse && contentsResponse . ok ) {
const contentsData = await contentsResponse . json ( ) ;
const contentsData = await contentsResponse . json ( ) ;
if ( Array . isArray ( contentsData ) ) {
if ( Array . isArray ( contentsData ) ) {
@ -539,7 +558,7 @@ async function fetchFromGitea(owner: string, repo: string, baseUrl: string): Pro
const readmeFiles = [ 'README.adoc' , 'README.md' , 'README.rst' , 'README.txt' ] ;
const readmeFiles = [ 'README.adoc' , 'README.md' , 'README.rst' , 'README.txt' ] ;
for ( const readmeFile of readmeFiles ) {
for ( const readmeFile of readmeFiles ) {
try {
try {
const fileResponse = await fetch ( ` /api/gitea-proxy/ ${ proxyBaseUrl } / repos/${ owner } / ${ repo } /contents/ ${ readmeFile } ?ref= ${ defaultBranch } ` ) ;
const fileResponse = await fetch ( ` /api/gitea-proxy/repos/ ${ owner } / ${ repo } /contents/ ${ readmeFile } ?baseUrl= ${ encodeURIComponent ( baseUrl ) } & ref= ${ defaultBranch } ` ) ;
if ( ! fileResponse . ok ) throw new Error ( 'Not found' ) ;
if ( ! fileResponse . ok ) throw new Error ( 'Not found' ) ;
const fileData = await fileResponse . json ( ) ;
const fileData = await fileResponse . json ( ) ;
if ( fileData . content ) {
if ( fileData . content ) {
@ -578,7 +597,7 @@ async function fetchFromGitea(owner: string, repo: string, baseUrl: string): Pro
// If found in tree, fetch it
// If found in tree, fetch it
if ( readmePath ) {
if ( readmePath ) {
try {
try {
const fileResponse = await fetch ( ` /api/gitea-proxy/ ${ proxyBaseUrl } / repos/${ owner } / ${ repo } /contents/ ${ readmePath } ?ref= ${ defaultBranch } ` ) ;
const fileResponse = await fetch ( ` /api/gitea-proxy/repos/ ${ owner } / ${ repo } /contents/ ${ readmePath } ?baseUrl= ${ encodeURIComponent ( baseUrl ) } & ref= ${ defaultBranch } ` ) ;
if ( ! fileResponse . ok ) throw new Error ( 'Not found' ) ;
if ( ! fileResponse . ok ) throw new Error ( 'Not found' ) ;
const fileData = await fileResponse . json ( ) ;
const fileData = await fileResponse . json ( ) ;
if ( fileData . content ) {
if ( fileData . content ) {