Skip to content

Commit

Permalink
Merge pull request #11 from adamborowski/7-data-fetching-utilites
Browse files Browse the repository at this point in the history
refactor: abstract gql from client
  • Loading branch information
adamborowski committed Jan 25, 2023
2 parents 58754f7 + 2ed5a36 commit 2673230
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 46 deletions.
51 changes: 7 additions & 44 deletions src/common/api/clients/graphqlSearchClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,65 +2,28 @@

import { SearchClient } from "./SearchClient";
import { Adapter } from "./Adapter";
import { ZodError } from "zod";

// todo make abstract to satisfy any graphql query in the future
// for now make it search specific
// or - consider moving the entire client to feature folder
export const createGraphqlSearchClient = <ServerType, ClientType>(
base: string,
token: string,
queryBuilder: (query: string) => {
query: string;
variables: Record<string, string>;
},
adapter: Adapter<ServerType, ClientType>
): SearchClient<ClientType> => ({
search: async (query, signal) => {
const gql = {
// TODO inject specific query from external
query: `query ($query: String!) {
search(query: $query, type: REPOSITORY, first: 50) {
repositoryCount
nodes {
... on Repository {
databaseId
name
owner {
login
}
url
description
stargazerCount
forkCount
}
}
pageInfo {
endCursor
startCursor
}
}
}`,
variables: { query },
};
const response = await fetch(base, {
method: "POST",
headers: {
Authorization: "Bearer " + token,
"Content-Type": "application/json",
},
signal,
body: JSON.stringify(gql),
body: JSON.stringify(queryBuilder(query)),
});
const json = await response.json();

try {
const serverResponse = adapter.parse(json);
return adapter.serverToClient(serverResponse);
} catch (e) {
if (e instanceof ZodError) {
// FIXME this might be specific to adapter not client
throw new Error(
e.issues.map((i) => `${i.path}: ${i.message}`).join("\n")
);
}
throw e;
}
const serverResponse = adapter.parse(json);
return adapter.serverToClient(serverResponse);
},
});
16 changes: 16 additions & 0 deletions src/common/services/flattenZodError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { ZodError } from "zod";

export const flattenZodError =
<P extends unknown[], R>(originalFunction: (...args: P) => R) =>
(...args: P) => {
try {
return originalFunction(...args);
} catch (e) {
if (e instanceof ZodError) {
throw new Error(
e.issues.map((i) => `${i.path}: ${i.message}`).join("\n")
);
}
throw e;
}
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Adapter } from "../../../../common/api/clients/Adapter";
import z from "zod";
import { Repository, repositorySchema } from "../../types";
import { flattenZodError } from "../../../../common/services/flattenZodError";

const searchRepositorySchema = z.object({
databaseId: z.number(),
Expand All @@ -24,7 +25,7 @@ export const repositoryAdapter: Adapter<
z.infer<typeof searchPayloadSchema>,
Repository
> = {
parse: searchPayloadSchema.parse,
parse: flattenZodError(searchPayloadSchema.parse),
serverToClient: (serverResponse) =>
serverResponse.data.search.nodes.map(
({
Expand All @@ -36,7 +37,7 @@ export const repositoryAdapter: Adapter<
owner,
description,
}) =>
repositorySchema.parse({
flattenZodError(repositorySchema.parse)({
id: databaseId,
name,
owner: owner.login,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,26 @@ import { createGraphqlSearchClient } from "../../../../common/api/clients/graphq
export const repositorySearchClient = createGraphqlSearchClient(
"https://api.github.com/graphql",
process.env.REACT_APP_GITHUB_TOKEN!,
(query) => ({
query: `query ($query: String!) {
search(query: $query, type: REPOSITORY, first: 50) {
repositoryCount
nodes {
... on Repository {
databaseId
name
owner {
login
}
url
description
stargazerCount
forkCount
}
}
}
}`,
variables: { query },
}),
repositoryAdapter
);

0 comments on commit 2673230

Please sign in to comment.