1+ /**
2+ * Mock GitHub API server for testing git clone in API mode.
3+ * Serves fake repo metadata, tree, and file contents.
4+ */
5+ import http from 'node:http' ;
6+
7+ const MOCK_OWNER = 'test-org' ;
8+ const MOCK_REPO = 'test-repo' ;
9+
10+ const files : Record < string , string > = {
11+ 'package.json' : JSON . stringify ( { name : 'test-repo' , version : '1.0.0' , private : true } , null , 2 ) ,
12+ 'README.md' : '# Test Repo\n\nThis is a mock repository for testing git clone API mode.' ,
13+ 'src/index.ts' : 'export const hello = "world";\n' ,
14+ } ;
15+
16+ function handleRequest ( req : http . IncomingMessage , res : http . ServerResponse ) {
17+ res . setHeader ( 'Access-Control-Allow-Origin' , '*' ) ;
18+ res . setHeader ( 'Access-Control-Allow-Headers' , '*' ) ;
19+
20+ if ( req . method === 'OPTIONS' ) {
21+ res . writeHead ( 204 ) ;
22+ res . end ( ) ;
23+ return ;
24+ }
25+
26+ const url = req . url || '' ;
27+
28+ // GET /api/repos/:owner/:repo
29+ if ( url === `/api/repos/${ MOCK_OWNER } /${ MOCK_REPO } ` ) {
30+ res . writeHead ( 200 , { 'Content-Type' : 'application/json' } ) ;
31+ res . end ( JSON . stringify ( {
32+ default_branch : 'main' ,
33+ name : MOCK_REPO ,
34+ full_name : `${ MOCK_OWNER } /${ MOCK_REPO } ` ,
35+ } ) ) ;
36+ return ;
37+ }
38+
39+ // GET /api/repos/:owner/:repo/git/trees/main?recursive=1
40+ if ( url . startsWith ( `/api/repos/${ MOCK_OWNER } /${ MOCK_REPO } /git/trees/` ) ) {
41+ const tree = Object . keys ( files ) . map ( path => ( {
42+ path,
43+ type : 'blob' ,
44+ sha : 'abc123' ,
45+ } ) ) ;
46+ res . writeHead ( 200 , { 'Content-Type' : 'application/json' } ) ;
47+ res . end ( JSON . stringify ( { tree } ) ) ;
48+ return ;
49+ }
50+
51+ // GET /raw/:owner/:repo/:branch/:path — raw file content
52+ const rawMatch = url . match ( / ^ \/ r a w \/ [ ^ / ] + \/ [ ^ / ] + \/ [ ^ / ] + \/ ( .+ ) $ / ) ;
53+ if ( rawMatch ) {
54+ const filePath = rawMatch [ 1 ] ;
55+ if ( files [ filePath ] ) {
56+ res . writeHead ( 200 , { 'Content-Type' : 'text/plain' } ) ;
57+ res . end ( files [ filePath ] ) ;
58+ return ;
59+ }
60+ }
61+
62+ // 404
63+ res . writeHead ( 404 , { 'Content-Type' : 'application/json' } ) ;
64+ res . end ( JSON . stringify ( { message : 'Not Found' } ) ) ;
65+ }
66+
67+ export function startMockGithub ( port : number ) : Promise < http . Server > {
68+ return new Promise ( ( resolve ) => {
69+ const server = http . createServer ( handleRequest ) ;
70+ server . listen ( port , ( ) => resolve ( server ) ) ;
71+ } ) ;
72+ }
0 commit comments