11import { ofetch } from 'ofetch'
22import { createSharedComposable } from '@vueuse/core'
33import type { RawFile , GithubFile , GitOptions } from '../types'
4+ import { DraftStatus } from '../types/draft'
45
56import { joinURL } from 'ufo'
67
78export const useGit = createSharedComposable ( ( { owner, repo, token, branch, rootDir, authorName, authorEmail } : GitOptions ) => {
89 const gitFiles : Record < string , GithubFile > = { }
910 const $api = ofetch . create ( {
10- baseURL : ' https://api.github.com' ,
11+ baseURL : ` https://api.github.com/repos/ ${ owner } / ${ repo } ` ,
1112 headers : {
1213 Authorization : `Bearer ${ token } ` ,
1314 Accept : 'application/vnd.github.v3+json' ,
@@ -24,15 +25,26 @@ export const useGit = createSharedComposable(({ owner, repo, token, branch, root
2425 }
2526
2627 try {
27- const ghFile : GithubFile = await $api ( `/repos/ ${ owner } / ${ repo } / contents/${ path } ?ref=${ branch } ` )
28+ const ghFile : GithubFile = await $api ( `/contents/${ path } ?ref=${ branch } ` )
2829 if ( cached ) {
2930 gitFiles [ path ] = ghFile
3031 }
3132 return ghFile
3233 }
3334 catch ( error ) {
34- // TODO: Handle error
35- alert ( error )
35+ // Handle different types of errors gracefully
36+ if ( ( error as { status ?: number } ) . status === 404 ) {
37+ console . warn ( `File not found on GitHub: ${ path } ` )
38+ return null
39+ }
40+
41+ console . error ( `Failed to fetch file from GitHub: ${ path } ` , error )
42+
43+ // For development, show alert. In production, you might want to use a toast notification
44+ if ( process . env . NODE_ENV === 'development' ) {
45+ alert ( `Failed to fetch file: ${ path } \n${ ( error as { message ?: string } ) . message || error } ` )
46+ }
47+
3648 return null
3749 }
3850 }
@@ -53,33 +65,45 @@ export const useGit = createSharedComposable(({ owner, repo, token, branch, root
5365
5466 async function commitFilesToGitHub ( { owner, repo, branch, files, message, authorName, authorEmail } : { owner : string , repo : string , branch : string , files : RawFile [ ] , message : string , authorName : string , authorEmail : string } ) {
5567 // Get latest commit SHA
56- const refData = await $api ( `/repos/ ${ owner } / ${ repo } / git/ref/heads/${ branch } ?ref=${ branch } ` )
68+ const refData = await $api ( `/git/ref/heads/${ branch } ?ref=${ branch } ` )
5769 const latestCommitSha = refData . object . sha
5870
5971 // Get base tree SHA
60- const commitData = await $api ( `/repos/repos/ ${ owner } / ${ repo } / git/commits/${ latestCommitSha } ` )
72+ const commitData = await $api ( `/git/commits/${ latestCommitSha } ` )
6173 const baseTreeSha = commitData . tree . sha
6274
6375 // Create blobs and prepare tree
6476 const tree = [ ]
6577 for ( const file of files ) {
66- const blobData = await $api ( `/repos/repos/${ owner } /${ repo } /git/blobs` , {
67- method : 'POST' ,
68- body : JSON . stringify ( {
69- content : file . content ,
70- encoding : file . encoding ,
71- } ) ,
72- } )
73- tree . push ( {
74- path : file . path ,
75- mode : '100644' ,
76- type : 'blob' ,
77- sha : blobData . sha ,
78- } )
78+ if ( file . status === DraftStatus . Deleted ) {
79+ // For deleted files, set sha to null to remove them from the tree
80+ tree . push ( {
81+ path : file . path ,
82+ mode : '100644' ,
83+ type : 'blob' ,
84+ sha : null ,
85+ } )
86+ }
87+ else {
88+ // For new/modified files, create blob and use its sha
89+ const blobData = await $api ( `/git/blobs` , {
90+ method : 'POST' ,
91+ body : JSON . stringify ( {
92+ content : file . content ,
93+ encoding : file . encoding ,
94+ } ) ,
95+ } )
96+ tree . push ( {
97+ path : file . path ,
98+ mode : '100644' ,
99+ type : 'blob' ,
100+ sha : blobData . sha ,
101+ } )
102+ }
79103 }
80104
81105 // Create new tree
82- const treeData = await $api ( `/repos/repos/ ${ owner } / ${ repo } / git/trees` , {
106+ const treeData = await $api ( `/git/trees` , {
83107 method : 'POST' ,
84108 body : JSON . stringify ( {
85109 base_tree : baseTreeSha ,
@@ -88,7 +112,7 @@ export const useGit = createSharedComposable(({ owner, repo, token, branch, root
88112 } )
89113
90114 // Create new commit
91- const newCommit = await $api ( `/repos/repos/ ${ owner } / ${ repo } / git/commits` , {
115+ const newCommit = await $api ( `/git/commits` , {
92116 method : 'POST' ,
93117 body : JSON . stringify ( {
94118 message,
@@ -103,7 +127,7 @@ export const useGit = createSharedComposable(({ owner, repo, token, branch, root
103127 } )
104128
105129 // Update branch ref
106- await $api ( `/repos/repos/ ${ owner } / ${ repo } / git/refs/heads/${ branch } ` , {
130+ await $api ( `/git/refs/heads/${ branch } ` , {
107131 method : 'PATCH' ,
108132 body : JSON . stringify ( { sha : newCommit . sha } ) ,
109133 } )
0 commit comments