Skip to content

Commit

Permalink
feat: new stack (#116)
Browse files Browse the repository at this point in the history
* feat: adopt biome

* chore: biome auto fix

* chore: ignore biome auto fix commit when git blame

* feat: use pre-commit

* feat: esm

* chore: handle invalid token error

* fix: emit transpiled file

* chore: run action on node 18.18.2
  • Loading branch information
maxam2017 authored Feb 16, 2024
1 parent 3575de9 commit 5ad9ae6
Show file tree
Hide file tree
Showing 13 changed files with 286 additions and 2,039 deletions.
26 changes: 0 additions & 26 deletions .eslintrc.js

This file was deleted.

1 change: 1 addition & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
376a7f5f8d41ae69c74733078c0182813a3dbac7
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node_version: [16]
node_version: [18.18.2]
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node_version }}
Expand Down
9 changes: 9 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
repos:
- repo: local
hooks:
- id: local-biome-check
name: biome check
entry: yarn biome check --apply --files-ignore-unknown=true --no-errors-on-unmatched
language: system
types: [text]
files: "\\.(jsx?|tsx?|c(js|ts)|m(js|ts)|d\\.(ts|cts|mts)|jsonc?)$"
6 changes: 0 additions & 6 deletions .prettierrc.js

This file was deleted.

41 changes: 41 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"$schema": "https://biomejs.dev/schemas/1.4.1/schema.json",
"files": {
"include": ["**/*.ts", "**/*.json"],
"ignore": ["**/node_modules/**", "**/dist/**"]
},
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"complexity": {
"noForEach": "warn"
},
"performance": {
"noAccumulatingSpread": "warn"
},
"style": {
"useTemplate": "warn"
},
"suspicious": {
"noExplicitAny": "warn"
}
}
},
"formatter": {
"enabled": true,
"indentWidth": 2,
"indentStyle": "space",
"lineWidth": 120
},
"javascript": {
"formatter": {
"semicolons": "always",
"trailingComma": "all",
"quoteStyle": "single"
}
}
}
2 changes: 1 addition & 1 deletion dist/index.js

Large diffs are not rendered by default.

42 changes: 13 additions & 29 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,26 @@
"description": "Are you an early 🐤 or a night 🦉? Let's check out in gist",
"author": "maxam2017",
"license": "MIT",
"type": "module",
"scripts": {
"dev": "ts-node src/index.ts",
"build": "tsc src/index.ts --outDir dist && ncc build dist/index.js --minify && find dist/ -type f -not -name 'index.js' -delete",
"lint": "eslint src/ --ext .ts"
"preinstall": "pre-commit install",
"dev": "ts-node-esm src/index.ts",
"build": "tsc && ncc build dist/index.js --minify && find dist/ -type f -not -name 'index.js' -delete",
"lint": "biome lint"
},
"dependencies": {
"@octokit/rest": "^17.2.1",
"dotenv": "^8.2.0"
"@octokit/rest": "^20.0.2",
"dotenv": "^16.4.4"
},
"engines": {
"node": ">=16.0.0"
"node": ">=18"
},
"devDependencies": {
"@biomejs/biome": "1.5.3",
"@types/dotenv": "^8.2.0",
"@types/node": "^13.11.1",
"@types/node-fetch": "^2.5.6",
"@typescript-eslint/eslint-plugin": "^6.4.1",
"@typescript-eslint/parser": "^6.4.1",
"@zeit/ncc": "^0.22.1",
"eslint": "^8.48.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.0",
"husky": "^4.2.5",
"lint-staged": "^10.1.3",
"prettier": "^3.0.2",
"ts-node": "^10.9.1",
"typescript": "5.1.6"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.ts": [
"yarn lint --fix"
]
"@types/node": "^18.18.7",
"@vercel/ncc": "^0.38.1",
"ts-node": "^10.9.2",
"typescript": "^5.3.3"
}
}
4 changes: 1 addition & 3 deletions src/githubQuery.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import fetch from 'node-fetch';

export default async function (query: string) {
export default async function (query: string): Promise<any> {
const res = await fetch('https://api.github.com/graphql', {
method: 'POST',
headers: {
Expand Down
95 changes: 48 additions & 47 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
import { resolve } from 'path';
import { config } from 'dotenv';
import { Octokit } from '@octokit/rest';
import { config } from 'dotenv';

import githubQuery from './githubQuery';
import generateBarChart from './generateBarChart';
import {
userInfoQuery,
createContributedRepoQuery,
createCommittedDateQuery,
} from './queries';
import generateBarChart from './generateBarChart.js';
import githubQuery from './githubQuery.js';
import { createCommittedDateQuery, createContributedRepoQuery, userInfoQuery } from './queries.js';
/**
* get environment variable
*/
config({ path: resolve(__dirname, '../.env') });
config({ path: ['.env'] });

interface IRepo {
name: string;
Expand All @@ -37,7 +32,7 @@ interface Edge {
/**
* First, get user id
*/
const userResponse = await githubQuery(userInfoQuery).catch(error =>
const userResponse = await githubQuery(userInfoQuery).catch((error) =>
console.error(`Unable to get username and id\n${error}`),
);
const { login: username, id } = userResponse?.data?.viewer ?? {};
Expand All @@ -46,25 +41,31 @@ interface Edge {
* Second, get contributed repos
*/
const contributedRepoQuery = createContributedRepoQuery(username);
const repoResponse = await githubQuery(contributedRepoQuery).catch(error =>
const repoResponse = await githubQuery(contributedRepoQuery).catch((error) =>
console.error(`Unable to get the contributed repo\n${error}`),
);
const repos: IRepo[] =
repoResponse?.data?.user?.repositoriesContributedTo?.nodes
.filter((repoInfo: RepoInfo) => !repoInfo?.isFork)
.map((repoInfo: RepoInfo) => ({
name: repoInfo?.name,
owner: repoInfo?.owner?.login,
}));

/**
* If the token is invalid, stop the process
*/
if (repoResponse.message === 'Bad credentials') {
console.error('Invalid GitHub token. Please renew the GH_TOKEN');
return;
}

const repos: IRepo[] = repoResponse?.data?.user?.repositoriesContributedTo?.nodes
.filter((repoInfo: RepoInfo) => !repoInfo?.isFork)
.map((repoInfo: RepoInfo) => ({
name: repoInfo?.name,
owner: repoInfo?.owner?.login,
}));

/**
* Third, get commit time and parse into commit-time/hour diagram
*/
const committedTimeResponseMap = await Promise.all(
repos.map(({ name, owner }) =>
githubQuery(createCommittedDateQuery(id, name, owner)),
),
).catch(error => console.error(`Unable to get the commit info\n${error}`));
repos.map(({ name, owner }) => githubQuery(createCommittedDateQuery(id, name, owner))),
).catch((error) => console.error(`Unable to get the commit info\n${error}`));

if (!committedTimeResponseMap) return;

Expand All @@ -73,25 +74,23 @@ interface Edge {
let evening = 0; // 18 - 24
let night = 0; // 0 - 6

committedTimeResponseMap.forEach(committedTimeResponse => {
committedTimeResponse?.data?.repository?.defaultBranchRef?.target?.history?.edges.forEach(
(edge: Edge) => {
const committedDate = edge?.node?.committedDate;
const timeString = new Date(committedDate).toLocaleTimeString('en-US', {
hour12: false,
timeZone: process.env.TIMEZONE,
});
const hour = +timeString.split(':')[0];

/**
* voting and counting
*/
if (hour >= 6 && hour < 12) morning++;
if (hour >= 12 && hour < 18) daytime++;
if (hour >= 18 && hour < 24) evening++;
if (hour >= 0 && hour < 6) night++;
},
);
committedTimeResponseMap.forEach((committedTimeResponse) => {
committedTimeResponse?.data?.repository?.defaultBranchRef?.target?.history?.edges.forEach((edge: Edge) => {
const committedDate = edge?.node?.committedDate;
const timeString = new Date(committedDate).toLocaleTimeString('en-US', {
hour12: false,
timeZone: process.env.TIMEZONE,
});
const hour = +timeString.split(':')[0];

/**
* voting and counting
*/
if (hour >= 6 && hour < 12) morning++;
if (hour >= 12 && hour < 18) daytime++;
if (hour >= 18 && hour < 24) evening++;
if (hour >= 0 && hour < 6) night++;
});
});

/**
Expand Down Expand Up @@ -127,18 +126,20 @@ interface Edge {
.get({
gist_id: `${process.env.GIST_ID}`,
})
.catch(error => console.error(`Unable to update gist\n${error}`));
.catch((error) => console.error(`Unable to update gist\n${error}`));
if (!gist) return;

if (!gist.data.files) {
console.error('No file found in the gist');
return;
}

const filename = Object.keys(gist.data.files)[0];
await octokit.gists.update({
gist_id: `${process.env.GIST_ID}`,
files: {
[filename]: {
filename:
morning + daytime > evening + night
? "I'm an early 🐤"
: "I'm a night 🦉",
filename: morning + daytime > evening + night ? "I'm an early 🐤" : "I'm a night 🦉",
content: lines.join('\n'),
},
},
Expand Down
6 changes: 1 addition & 5 deletions src/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,7 @@ export const createContributedRepoQuery = (username: string) => `
}
`;

export const createCommittedDateQuery = (
id: string,
name: string,
owner: string,
) => `
export const createCommittedDateQuery = (id: string, name: string, owner: string) => `
query {
repository(owner: "${owner}", name: "${name}") {
defaultBranchRef {
Expand Down
18 changes: 18 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"target": "es2020",
"lib": ["esnext"],
"module": "esnext",
"strict": true,
"esModuleInterop": true,
"moduleResolution": "node",
"skipLibCheck": false,
"noUnusedLocals": true,
"noImplicitAny": true,
"allowJs": true,
"noEmit": false,
"outDir": "dist",
"resolveJsonModule": true,
},
"include": ["src/**/*"]
}
Loading

0 comments on commit 5ad9ae6

Please sign in to comment.