@@ -21,11 +21,12 @@ import Vapor
2121enum Github {
2222
2323 enum Error : Swift . Error {
24- case decodeContentFailed( URI , Swift . Error )
24+ case decodeContentFailed( _ url: String , Swift . Error )
25+ case encodeContentFailed( _ url: String , Swift . Error )
2526 case missingToken
2627 case noBody
2728 case invalidURL( String )
28- case postRequestFailed( URI , Swift . Error )
29+ case postRequestFailed( _ url : String , Swift . Error )
2930 case requestFailed( HTTPStatus )
3031 }
3132
@@ -108,7 +109,7 @@ extension Github {
108109 return " https://api.github.com/repos/ \( owner) / \( repository) / \( resource. rawValue) "
109110 }
110111 }
111-
112+
112113 @available ( * , deprecated)
113114 static func fetch( client: Client , uri: URI , headers: [ ( String , String ) ] = [ ] ) async throws -> ( content: String , etag: String ? ) {
114115 guard let token = Current . githubToken ( ) else {
@@ -211,12 +212,15 @@ extension Github {
211212
212213extension Github {
213214
215+ @available ( * , deprecated)
214216 static let graphQLApiUri = URI ( string: " https://api.github.com/graphql " )
217+ static let graphQLApiURL = " https://api.github.com/graphql "
215218
216219 struct GraphQLQuery : Content {
217220 var query : String
218221 }
219222
223+ @available ( * , deprecated)
220224 static func fetchResource< T: Decodable > ( _ type: T . Type , client: Client , query: GraphQLQuery ) async throws ( Github. Error) -> T {
221225 guard let token = Current . githubToken ( ) else {
222226 throw Error . missingToken
@@ -228,7 +232,7 @@ extension Github {
228232 try $0. content. encode ( query)
229233 }
230234 } catch {
231- throw . postRequestFailed( Self . graphQLApiUri, error)
235+ throw . postRequestFailed( graphQLApiUri. string , error)
232236 }
233237
234238 guard !isRateLimited( response) else {
@@ -244,25 +248,57 @@ extension Github {
244248 do {
245249 return try response. content. decode ( T . self, using: decoder)
246250 } catch {
247- throw . decodeContentFailed( Self . graphQLApiUri, error)
251+ throw . decodeContentFailed( graphQLApiUri. string, error)
252+ }
253+ }
254+
255+ static func fetchResource< T: Decodable > ( _ type: T . Type , query: GraphQLQuery ) async throws ( Github. Error) -> T {
256+ guard let token = Current . githubToken ( ) else {
257+ throw Error . missingToken
258+ }
259+
260+ @Dependency ( \. httpClient) var httpClient
261+
262+ let body = try run {
263+ try JSONEncoder ( ) . encode ( query)
264+ } rethrowing: {
265+ Error . encodeContentFailed ( graphQLApiURL, $0)
266+ }
267+
268+ let response = try await run {
269+ try await httpClient. post ( url: graphQLApiURL, headers: defaultHeaders ( with: token) , body: body)
270+ } rethrowing: {
271+ Error . postRequestFailed ( graphQLApiURL, $0)
272+ }
273+
274+ guard !isRateLimited( response) else {
275+ Current . logger ( ) . critical ( " rate limited while fetching resource \( T . self) " )
276+ throw Error . requestFailed ( . tooManyRequests)
277+ }
278+
279+ guard response. status == . ok else {
280+ Current . logger ( ) . warning ( " fetchResource< \( T . self) > request failed with status \( response. status) " )
281+ throw Error . requestFailed ( response. status)
282+ }
283+
284+ guard let body = response. body else { throw Github . Error. noBody }
285+
286+ return try run {
287+ try decoder. decode ( T . self, from: body)
288+ } rethrowing: {
289+ Error . decodeContentFailed ( graphQLApiURL, $0)
248290 }
249291 }
250292
251- static func fetchMetadata( client : Client , owner: String , repository: String ) async throws ( Github. Error) -> Metadata {
293+ static func fetchMetadata( owner: String , repository: String ) async throws ( Github. Error) -> Metadata {
252294 struct Response < T: Decodable & Equatable > : Decodable , Equatable {
253295 var data : T
254296 }
255297 return try await fetchResource ( Response< Metadata> . self ,
256- client: client,
257298 query: Metadata . query ( owner: owner, repository: repository) )
258299 . data
259300 }
260301
261- static func fetchMetadata( client: Client , packageUrl: String ) async throws -> Metadata {
262- let ( owner, name) = try parseOwnerName ( url: packageUrl)
263- return try await fetchMetadata ( client: client, owner: owner, repository: name)
264- }
265-
266302}
267303
268304
0 commit comments