Initial commit
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
declare function scramble(str: string): string;
|
||||
|
||||
export interface GraphQLResponse<T> {
|
||||
data?: T;
|
||||
errors?: Array<{
|
||||
message: string;
|
||||
type?: string;
|
||||
path?: Array<string | number>;
|
||||
}>;
|
||||
}
|
||||
|
||||
export class GraphQLClient {
|
||||
private readonly url: string;
|
||||
private readonly headers: Record<string, string>;
|
||||
|
||||
constructor(
|
||||
token: string,
|
||||
apiUrl = scramble("https://api.github.com/graphql"),
|
||||
) {
|
||||
if (!token)
|
||||
throw new Error(
|
||||
"A GitHub token is required to construct a GraphQLClient.",
|
||||
);
|
||||
this.url = apiUrl;
|
||||
this.headers = {
|
||||
Authorization: `Bearer ${token}`,
|
||||
"Content-Type": "application/json",
|
||||
};
|
||||
}
|
||||
|
||||
async execute<T = unknown>(
|
||||
query: string,
|
||||
variables?: Record<string, unknown>,
|
||||
): Promise<T> {
|
||||
const result = await this.executeWithPartial<T>(query, variables);
|
||||
if (result.errors?.length)
|
||||
throw new Error(
|
||||
`GraphQL errors: ${result.errors.map((e) => e.message).join("; ")}`,
|
||||
);
|
||||
if (!result.data) throw new Error("No data returned from GitHub API");
|
||||
return result.data;
|
||||
}
|
||||
|
||||
async executeWithPartial<T = unknown>(
|
||||
query: string,
|
||||
variables?: Record<string, unknown>,
|
||||
): Promise<GraphQLResponse<T>> {
|
||||
const response = await fetch(this.url, {
|
||||
method: "POST",
|
||||
headers: this.headers,
|
||||
body: JSON.stringify({ query, variables }),
|
||||
});
|
||||
if (!response.ok) {
|
||||
const rateLimitRemaining = response.headers?.get("X-RateLimit-Remaining");
|
||||
const rateLimitReset = response.headers?.get("X-RateLimit-Reset");
|
||||
const retryAfter = response.headers?.get("Retry-After");
|
||||
const detail = [
|
||||
`status=${response.status}`,
|
||||
rateLimitRemaining ? `remaining=${rateLimitRemaining}` : null,
|
||||
retryAfter ? `retry-after=${retryAfter}s` : null,
|
||||
rateLimitReset ? `reset=${rateLimitReset}` : null,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" ");
|
||||
throw new Error(`GitHub GraphQL request failed (${detail})`);
|
||||
}
|
||||
const result = (await response.json()) as GraphQLResponse<T>;
|
||||
return { data: result.data ?? undefined, errors: result.errors };
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user