Files
snk/packages/github-user-contribution/index.ts
2020-10-20 19:43:05 +02:00

91 lines
2.2 KiB
TypeScript

import fetch from "node-fetch";
import * as parser from "fast-xml-parser";
// const traverse = (
// o: any,
// callback: (elements: { name: string; "#text": string; attrs: any }[]) => void,
// path: { name: string; "#text": string; attrs: any }[] = []
// ) => {
// if (o && typeof o === "object")
// Object.entries(o)
// .filter(([o]) => o !== "attr" && o !== "#text")
// .forEach(([name, v]) => {
// const el = { name, attrs: v.attrs, "#text": v["#text"] };
// const p = [el, ...path];
// callback(p);
// traverse(v, callback, p);
// });
// };
const findNode = (o: any, condition: (x: any) => boolean): any => {
if (o && typeof o === "object") {
if (condition(o)) return o;
for (const c of Object.values(o)) {
const res = findNode(c, condition);
if (res) return res;
}
}
};
const parseUserPage = (content: string) => {
const o = parser.parse(content, {
attrNodeName: "attr",
attributeNamePrefix: "",
ignoreAttributes: false,
});
//
// parse colorScheme
const legend = findNode(
o,
(x) => x.attr && x.attr.class && x.attr.class.trim() === "legend"
);
const colorScheme = legend.li.map(
(x: any) => x.attr.style.match(/background\-color: +(#\w+)/)![1]!
);
//
// parse cells
const svg = findNode(
o,
(x) =>
x.attr && x.attr.class && x.attr.class.trim() === "js-calendar-graph-svg"
);
const cells = svg.g.g
.map((g: any, x: number) =>
g.rect.map(({ attr }: any, y: number) => {
const color = attr.fill;
const count = +attr["data-count"];
const date = attr["data-date"];
const k = colorScheme.indexOf(color);
return { x, y, color, count, date, k };
})
)
.flat();
return { cells, colorScheme };
};
/**
* get the contribution grid from a github user page
*
* @param userName
*/
export const getGithubUserContribution = async (userName: string) => {
const res = await fetch(`https://github.com/${userName}`);
const resText = await res.text();
return parseUserPage(resText);
};
type ThenArg<T> = T extends PromiseLike<infer U> ? U : T;
export type Res = ThenArg<ReturnType<typeof getGithubUserContribution>>;
export type Cell = Res["cells"][number];