Skip to content

Commit

Permalink
feat(users): Add api for fetch users meta (#96)
Browse files Browse the repository at this point in the history
  • Loading branch information
chef-huan authored Feb 3, 2022
1 parent ecb7b85 commit de763b2
Show file tree
Hide file tree
Showing 4 changed files with 184 additions and 1 deletion.
153 changes: 153 additions & 0 deletions api/users/search.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import { VercelRequest, VercelResponse } from "@vercel/node";
import { gql, request } from "graphql-request";
import { Parser } from "json2csv";
import { PROFILE_SUBGRAPH } from "../../utils";

type User = {
id: string;
internalId: string;
team: { id: string };
isActive: boolean;
nftAddress: string;
tokenId: string;
totalPoints: string;
};

const getUsersFirstPage = async (
pageSize: number,
team: string,
totalPointGreater: string,
totalPointLess: string,
nftAddress: string,
lastUserId: string
) => {
const teamQuery = (team && " team: $team ") || "";
const totalPointsGTQuery = (totalPointGreater && " totalPoints_gt: $totalPointGreater ") || "";
const totalPointsLTQuery = (totalPointLess && " totalPoints_lt: $totalPointLess ") || "";
const nftAddressQuery = (nftAddress && " nftAddress: $nftAddress ") || "";
const lastUserIdQuery = (lastUserId && " internalId_gt: $lastUserId ") || "";

const { users } = await request(
PROFILE_SUBGRAPH,
gql`
query getUsersQuery($pageSize: Int, $team: String, $totalPointGreater: String, $totalPointLess: String, $nftAddress: String, $lastUserId: String) {
users(orderBy: internalId, orderDirection: asc, first: $pageSize, where: ${
"{" +
teamQuery +
totalPointsGTQuery +
totalPointsLTQuery +
nftAddressQuery +
lastUserIdQuery +
"}"
}) {
id
internalId
team {
id
}
isActive
nftAddress
tokenId
totalPoints
}
}
`,
{ pageSize, team, totalPointGreater, totalPointLess, nftAddress, lastUserId }
);

return users;
};

const getCsv = (users: User[]) => {
const fields = [
"id",
"internalId",
"team.id",
"isActive",
"nftAddress",
"tokenId",
"totalPoints",
];

const parser = new Parser({
fields,
});

return parser.parse(users);
};

export default async (req: VercelRequest, res: VercelResponse): Promise<VercelResponse | void> => {
if (req.method === "GET") {
try {
const { authorization } = req.headers;
if (authorization === `${process.env.PROFILE_API_SECRET_KEY}`) {
try {
const {
csv,
team,
totalPointGreater,
totalPointLess,
nftAddress,
page = "1",
} = req.query;
let { pageSize = "1000" } = req.query;

const isCsv = csv === "true";
if (parseInt(pageSize as string) > 1000 || isCsv) {
pageSize = "1000";
}

let lastUserId = "";
let users: User[] = [];

let fetchedPage = 0;
let allFetched = false;
while (fetchedPage < parseInt(page as string) && !allFetched) {
{
const fetchedUsers = await getUsersFirstPage(
parseInt(pageSize as string),
team as string,
totalPointGreater as string,
totalPointLess as string,
nftAddress as string,
lastUserId
);
lastUserId = fetchedUsers[fetchedUsers.length - 1]?.internalId;

if (isCsv) {
users = users.concat(fetchedUsers);
if (fetchedUsers.length < pageSize || lastUserId === undefined) {
allFetched = true;
}
} else {
users = fetchedUsers;
fetchedPage = fetchedPage + 1;
}
}
}

if (isCsv) {
res.setHeader(
"Content-disposition",
`attachment; filename=profile-${new Date().toISOString()}.csv`
);
res.setHeader("Content-Type", "text/csv");
res.status(200).send(getCsv(users));
} else {
res.status(200).json({ data: users, success: true });
}
} catch (error) {
console.log(error);
throw new Error("Error refreshing Trading Competition Leaderboard");
}
} else {
res.status(401).json({ success: false });
}
} catch (err) {
res.status(500).json({ statusCode: 500 });
}
} else {
res.setHeader("Allow", "GET");
res.status(405).end("Method Not Allowed");
}
};
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@
}
},
"dependencies": {
"@types/json2csv": "^5.0.3",
"ethers": "^5.4.0",
"graphql": "^15.5.0",
"graphql-request": "^3.5.0",
"json2csv": "^5.0.6",
"mongoose": "^5.13.0"
},
"devDependencies": {
Expand Down
2 changes: 2 additions & 0 deletions utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export const TRADING_COMPETITION_V2_SUBGRAPH =

export const TRADING_COMPETITION_SUBGRAPH = TRADING_COMPETITION_V2_SUBGRAPH;

export const PROFILE_SUBGRAPH = "https://api.thegraph.com/subgraphs/name/pancakeswap/profile";

/**
* Check for the validity of a username based on rules (see documentation).
*
Expand Down
28 changes: 27 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1142,6 +1142,13 @@
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad"
integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==

"@types/json2csv@^5.0.3":
version "5.0.3"
resolved "https://registry.yarnpkg.com/@types/json2csv/-/json2csv-5.0.3.tgz#759514772a90e35b08c10808dedeaf52248af418"
integrity sha512-ZJEv6SzhPhgpBpxZU4n/TZekbZqI4EcyXXRwms1lAITG2kIAtj85PfNYafUOY1zy8bWs5ujaub0GU4copaA0sw==
dependencies:
"@types/node" "*"

"@types/minimist@^1.2.0":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256"
Expand Down Expand Up @@ -1731,6 +1738,11 @@ combined-stream@^1.0.8:
dependencies:
delayed-stream "~1.0.0"

commander@^6.1.0:
version "6.2.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c"
integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==

compare-func@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-2.0.0.tgz#fb65e75edbddfd2e568554e8b5b05fff7a51fcb3"
Expand Down Expand Up @@ -3263,6 +3275,15 @@ json-stable-stringify-without-jsonify@^1.0.1:
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=

json2csv@^5.0.6:
version "5.0.6"
resolved "https://registry.yarnpkg.com/json2csv/-/json2csv-5.0.6.tgz#590e0e1b9579e59baa53bda0c0d840f4d8009687"
integrity sha512-0/4Lv6IenJV0qj2oBdgPIAmFiKKnh8qh7bmLFJ+/ZZHLjSeiL3fKKGX3UryvKPbxFbhV+JcYo9KUC19GJ/Z/4A==
dependencies:
commander "^6.1.0"
jsonparse "^1.3.1"
lodash.get "^4.4.2"

[email protected], json5@^2.1.2:
version "2.2.0"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3"
Expand All @@ -3279,7 +3300,7 @@ jsonfile@^6.0.1:
optionalDependencies:
graceful-fs "^4.1.6"

jsonparse@^1.2.0:
jsonparse@^1.2.0, jsonparse@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=
Expand Down Expand Up @@ -3344,6 +3365,11 @@ lodash.clonedeep@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=

lodash.get@^4.4.2:
version "4.4.2"
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=

lodash.merge@^4.6.2:
version "4.6.2"
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
Expand Down

1 comment on commit de763b2

@vercel
Copy link

@vercel vercel bot commented on de763b2 Feb 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.