feat: get committers by org

No timerange yet
This commit is contained in:
r1oga
2023-01-10 16:06:48 +01:00
parent f61a904ab3
commit 9599c42aee
11 changed files with 26108 additions and 374 deletions

View File

@@ -14,6 +14,7 @@
"@r1oga/eslint-config": "^1.1.6",
"@r1oga/prettier-config": "^1.1.8",
"@types/jest": "^29.2.3",
"@types/node": "^18.11.18",
"@types/yargs": "^17.0.19",
"concurrently": "^7.6.0",
"husky": "^8.0.2",

104
pnpm-lock.yaml generated
View File

@@ -4,6 +4,7 @@ specifiers:
'@r1oga/eslint-config': ^1.1.6
'@r1oga/prettier-config': ^1.1.8
'@types/jest': ^29.2.3
'@types/node': ^18.11.18
'@types/yargs': ^17.0.19
concurrently: ^7.6.0
husky: ^8.0.2
@@ -31,11 +32,12 @@ devDependencies:
'@r1oga/eslint-config': 1.1.6_bh7fyjwf3qvjuxqkkpsm2qjvfa
'@r1oga/prettier-config': 1.1.8_prettier@2.8.1
'@types/jest': 29.2.3
'@types/node': 18.11.18
'@types/yargs': 17.0.19
concurrently: 7.6.0
husky: 8.0.2
is-ci: 3.0.1
jest: 29.3.1_@types+node@18.11.9
jest: 29.3.1_@types+node@18.11.18
jest-chain: 1.1.6
jest-mock-extended: 3.0.1_p6ekqnroyms5nhqbfxosryz7rm
jest-runner-eslint: 1.1.0_eslint@8.30.0+jest@29.3.1
@@ -48,7 +50,7 @@ devDependencies:
nps: 5.10.0
reflect-metadata: 0.1.13
ts-jest: 29.0.3_ritnbaj5usesqvlmws2tp6jzcu
ts-node-dev: 2.0.0_3v2cms72gsblw7jmali7btb3pu
ts-node-dev: 2.0.0_awa2wsr5thmg3i7jqycphctjfq
tsconfig-paths: 4.1.0
tslib: 2.4.1
typescript: 4.9.4
@@ -460,7 +462,7 @@ packages:
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
dependencies:
'@jest/types': 27.5.1
'@types/node': 18.11.9
'@types/node': 18.11.18
chalk: 4.1.2
jest-message-util: 27.5.1
jest-util: 27.5.1
@@ -472,7 +474,7 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.3.1
'@types/node': 18.11.9
'@types/node': 18.11.18
chalk: 4.1.2
jest-message-util: 29.3.1
jest-util: 29.3.1
@@ -493,14 +495,14 @@ packages:
'@jest/test-result': 29.3.1
'@jest/transform': 29.3.1
'@jest/types': 29.3.1
'@types/node': 18.11.9
'@types/node': 18.11.18
ansi-escapes: 4.3.2
chalk: 4.1.2
ci-info: 3.6.1
exit: 0.1.2
graceful-fs: 4.2.10
jest-changed-files: 29.2.0
jest-config: 29.3.1_@types+node@18.11.9
jest-config: 29.3.1_@types+node@18.11.18
jest-haste-map: 29.3.1
jest-message-util: 29.3.1
jest-regex-util: 29.2.0
@@ -527,7 +529,7 @@ packages:
dependencies:
'@jest/fake-timers': 27.5.1
'@jest/types': 27.5.1
'@types/node': 18.11.9
'@types/node': 18.11.18
jest-mock: 27.5.1
dev: true
@@ -537,7 +539,7 @@ packages:
dependencies:
'@jest/fake-timers': 29.3.1
'@jest/types': 29.3.1
'@types/node': 18.11.9
'@types/node': 18.11.18
jest-mock: 29.3.1
dev: true
@@ -564,7 +566,7 @@ packages:
dependencies:
'@jest/types': 27.5.1
'@sinonjs/fake-timers': 8.1.0
'@types/node': 18.11.9
'@types/node': 18.11.18
jest-message-util: 27.5.1
jest-mock: 27.5.1
jest-util: 27.5.1
@@ -576,7 +578,7 @@ packages:
dependencies:
'@jest/types': 29.3.1
'@sinonjs/fake-timers': 9.1.2
'@types/node': 18.11.9
'@types/node': 18.11.18
jest-message-util: 29.3.1
jest-mock: 29.3.1
jest-util: 29.3.1
@@ -618,7 +620,7 @@ packages:
'@jest/transform': 29.3.1
'@jest/types': 29.3.1
'@jridgewell/trace-mapping': 0.3.17
'@types/node': 18.11.9
'@types/node': 18.11.18
chalk: 4.1.2
collect-v8-coverage: 1.0.1
exit: 0.1.2
@@ -747,7 +749,7 @@ packages:
dependencies:
'@types/istanbul-lib-coverage': 2.0.4
'@types/istanbul-reports': 3.0.1
'@types/node': 18.11.9
'@types/node': 18.11.18
'@types/yargs': 15.0.14
chalk: 4.1.2
dev: true
@@ -758,7 +760,7 @@ packages:
dependencies:
'@types/istanbul-lib-coverage': 2.0.4
'@types/istanbul-reports': 3.0.1
'@types/node': 18.11.9
'@types/node': 18.11.18
'@types/yargs': 16.0.4
chalk: 4.1.2
dev: true
@@ -770,7 +772,7 @@ packages:
'@jest/schemas': 29.0.0
'@types/istanbul-lib-coverage': 2.0.4
'@types/istanbul-reports': 3.0.1
'@types/node': 18.11.9
'@types/node': 18.11.18
'@types/yargs': 17.0.19
chalk: 4.1.2
dev: true
@@ -952,7 +954,7 @@ packages:
/@types/graceful-fs/4.1.5:
resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==}
dependencies:
'@types/node': 18.11.9
'@types/node': 18.11.18
dev: true
/@types/hast/2.3.4:
@@ -992,8 +994,8 @@ packages:
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
dev: true
/@types/node/18.11.9:
resolution: {integrity: sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==}
/@types/node/18.11.18:
resolution: {integrity: sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==}
dev: true
/@types/parse-json/4.0.0:
@@ -2246,7 +2248,7 @@ packages:
'@typescript-eslint/eslint-plugin': 5.46.1_mqzxmroayievgzgel6yrqgih5i
'@typescript-eslint/utils': 5.46.1_lzzuuodtsqwxnvqeq4g4likcqa
eslint: 8.30.0
jest: 29.3.1_@types+node@18.11.9
jest: 29.3.1_@types+node@18.11.18
transitivePeerDependencies:
- supports-color
- typescript
@@ -3129,7 +3131,7 @@ packages:
'@jest/expect': 29.3.1
'@jest/test-result': 29.3.1
'@jest/types': 29.3.1
'@types/node': 18.11.9
'@types/node': 18.11.18
chalk: 4.1.2
co: 4.6.0
dedent: 0.7.0
@@ -3148,7 +3150,7 @@ packages:
- supports-color
dev: true
/jest-cli/29.3.1_@types+node@18.11.9:
/jest-cli/29.3.1_@types+node@18.11.18:
resolution: {integrity: sha512-TO/ewvwyvPOiBBuWZ0gm04z3WWP8TIK8acgPzE4IxgsLKQgb377NYGrQLc3Wl/7ndWzIH2CDNNsUjGxwLL43VQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
hasBin: true
@@ -3165,7 +3167,7 @@ packages:
exit: 0.1.2
graceful-fs: 4.2.10
import-local: 3.1.0
jest-config: 29.3.1_@types+node@18.11.9
jest-config: 29.3.1_@types+node@18.11.18
jest-util: 29.3.1
jest-validate: 29.3.1
prompts: 2.4.2
@@ -3176,7 +3178,7 @@ packages:
- ts-node
dev: true
/jest-config/29.3.1_@types+node@18.11.9:
/jest-config/29.3.1_@types+node@18.11.18:
resolution: {integrity: sha512-y0tFHdj2WnTEhxmGUK1T7fgLen7YK4RtfvpLFBXfQkh2eMJAQq24Vx9472lvn5wg0MAO6B+iPfJfzdR9hJYalg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
peerDependencies:
@@ -3191,7 +3193,7 @@ packages:
'@babel/core': 7.20.2
'@jest/test-sequencer': 29.3.1
'@jest/types': 29.3.1
'@types/node': 18.11.9
'@types/node': 18.11.18
babel-jest: 29.3.1_@babel+core@7.20.2
chalk: 4.1.2
ci-info: 3.6.1
@@ -3267,7 +3269,7 @@ packages:
'@jest/environment': 27.5.1
'@jest/fake-timers': 27.5.1
'@jest/types': 27.5.1
'@types/node': 18.11.9
'@types/node': 18.11.18
jest-mock: 27.5.1
jest-util: 27.5.1
jsdom: 16.7.0
@@ -3285,7 +3287,7 @@ packages:
'@jest/environment': 27.5.1
'@jest/fake-timers': 27.5.1
'@jest/types': 27.5.1
'@types/node': 18.11.9
'@types/node': 18.11.18
jest-mock: 27.5.1
jest-util: 27.5.1
dev: true
@@ -3297,7 +3299,7 @@ packages:
'@jest/environment': 29.3.1
'@jest/fake-timers': 29.3.1
'@jest/types': 29.3.1
'@types/node': 18.11.9
'@types/node': 18.11.18
jest-mock: 29.3.1
jest-util: 29.3.1
dev: true
@@ -3318,7 +3320,7 @@ packages:
dependencies:
'@jest/types': 27.5.1
'@types/graceful-fs': 4.1.5
'@types/node': 18.11.9
'@types/node': 18.11.18
anymatch: 3.1.3
fb-watchman: 2.0.2
graceful-fs: 4.2.10
@@ -3338,7 +3340,7 @@ packages:
dependencies:
'@jest/types': 29.3.1
'@types/graceful-fs': 4.1.5
'@types/node': 18.11.9
'@types/node': 18.11.18
anymatch: 3.1.3
fb-watchman: 2.0.2
graceful-fs: 4.2.10
@@ -3423,7 +3425,7 @@ packages:
jest: ^24.0.0 || ^25.0.0 || ^26.0.0 || ^27.0.0 || ^28.0.0 || ^29.0.0
typescript: ^3.0.0 || ^4.0.0
dependencies:
jest: 29.3.1_@types+node@18.11.9
jest: 29.3.1_@types+node@18.11.18
ts-essentials: 7.0.3_typescript@4.9.4
typescript: 4.9.4
dev: true
@@ -3433,7 +3435,7 @@ packages:
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
dependencies:
'@jest/types': 27.5.1
'@types/node': 18.11.9
'@types/node': 18.11.18
dev: true
/jest-mock/29.3.1:
@@ -3441,7 +3443,7 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.3.1
'@types/node': 18.11.9
'@types/node': 18.11.18
jest-util: 29.3.1
dev: true
@@ -3532,7 +3534,7 @@ packages:
create-jest-runner: 0.6.0
dot-prop: 5.3.0
eslint: 8.30.0
jest: 29.3.1_@types+node@18.11.9
jest: 29.3.1_@types+node@18.11.18
dev: true
/jest-runner-prettier/1.0.0_jest@29.3.1+prettier@2.8.1:
@@ -3543,7 +3545,7 @@ packages:
dependencies:
create-jest-runner: 0.8.0
emphasize: 5.0.0
jest: 29.3.1_@types+node@18.11.9
jest: 29.3.1_@types+node@18.11.18
jest-diff: 27.5.1
jest-runner: 27.5.1
p-limit: 4.0.0
@@ -3564,7 +3566,7 @@ packages:
'@jest/test-result': 27.5.1
'@jest/transform': 27.5.1
'@jest/types': 27.5.1
'@types/node': 18.11.9
'@types/node': 18.11.18
chalk: 4.1.2
emittery: 0.8.1
graceful-fs: 4.2.10
@@ -3596,7 +3598,7 @@ packages:
'@jest/test-result': 29.3.1
'@jest/transform': 29.3.1
'@jest/types': 29.3.1
'@types/node': 18.11.9
'@types/node': 18.11.18
chalk: 4.1.2
emittery: 0.13.1
graceful-fs: 4.2.10
@@ -3657,7 +3659,7 @@ packages:
'@jest/test-result': 29.3.1
'@jest/transform': 29.3.1
'@jest/types': 29.3.1
'@types/node': 18.11.9
'@types/node': 18.11.18
chalk: 4.1.2
cjs-module-lexer: 1.2.2
collect-v8-coverage: 1.0.1
@@ -3680,7 +3682,7 @@ packages:
resolution: {integrity: sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
dependencies:
'@types/node': 18.11.9
'@types/node': 18.11.18
graceful-fs: 4.2.10
dev: true
@@ -3758,7 +3760,7 @@ packages:
engines: {node: '>= 10.14.2'}
dependencies:
'@jest/types': 26.6.2
'@types/node': 18.11.9
'@types/node': 18.11.18
chalk: 4.1.2
graceful-fs: 4.2.10
is-ci: 2.0.0
@@ -3770,7 +3772,7 @@ packages:
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
dependencies:
'@jest/types': 27.5.1
'@types/node': 18.11.9
'@types/node': 18.11.18
chalk: 4.1.2
ci-info: 3.6.1
graceful-fs: 4.2.10
@@ -3782,7 +3784,7 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.3.1
'@types/node': 18.11.9
'@types/node': 18.11.18
chalk: 4.1.2
ci-info: 3.6.1
graceful-fs: 4.2.10
@@ -3829,7 +3831,7 @@ packages:
dependencies:
ansi-escapes: 6.0.0
chalk: 4.1.2
jest: 29.3.1_@types+node@18.11.9
jest: 29.3.1_@types+node@18.11.18
jest-regex-util: 29.2.0
jest-watcher: 29.3.1
slash: 5.0.0
@@ -3843,7 +3845,7 @@ packages:
dependencies:
'@jest/test-result': 29.3.1
'@jest/types': 29.3.1
'@types/node': 18.11.9
'@types/node': 18.11.18
ansi-escapes: 4.3.2
chalk: 4.1.2
emittery: 0.13.1
@@ -3863,7 +3865,7 @@ packages:
resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==}
engines: {node: '>= 10.13.0'}
dependencies:
'@types/node': 18.11.9
'@types/node': 18.11.18
merge-stream: 2.0.0
supports-color: 8.1.1
dev: true
@@ -3872,13 +3874,13 @@ packages:
resolution: {integrity: sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@types/node': 18.11.9
'@types/node': 18.11.18
jest-util: 29.3.1
merge-stream: 2.0.0
supports-color: 8.1.1
dev: true
/jest/29.3.1_@types+node@18.11.9:
/jest/29.3.1_@types+node@18.11.18:
resolution: {integrity: sha512-6iWfL5DTT0Np6UYs/y5Niu7WIfNv/wRTtN5RSXt2DIEft3dx3zPuw/3WJQBCJfmEzvDiEKwoqMbGD9n49+qLSA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
hasBin: true
@@ -3891,7 +3893,7 @@ packages:
'@jest/core': 29.3.1
'@jest/types': 29.3.1
import-local: 3.1.0
jest-cli: 29.3.1_@types+node@18.11.9
jest-cli: 29.3.1_@types+node@18.11.18
transitivePeerDependencies:
- '@types/node'
- supports-color
@@ -5120,7 +5122,7 @@ packages:
'@babel/core': 7.20.2
bs-logger: 0.2.6
fast-json-stable-stringify: 2.1.0
jest: 29.3.1_@types+node@18.11.9
jest: 29.3.1_@types+node@18.11.18
jest-util: 29.3.1
json5: 2.2.1
lodash.memoize: 4.1.2
@@ -5130,7 +5132,7 @@ packages:
yargs-parser: 21.1.1
dev: true
/ts-node-dev/2.0.0_3v2cms72gsblw7jmali7btb3pu:
/ts-node-dev/2.0.0_awa2wsr5thmg3i7jqycphctjfq:
resolution: {integrity: sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==}
engines: {node: '>=0.8.0'}
hasBin: true
@@ -5149,7 +5151,7 @@ packages:
rimraf: 2.7.1
source-map-support: 0.5.21
tree-kill: 1.2.2
ts-node: 10.9.1_3v2cms72gsblw7jmali7btb3pu
ts-node: 10.9.1_awa2wsr5thmg3i7jqycphctjfq
tsconfig: 7.0.0
typescript: 4.9.4
transitivePeerDependencies:
@@ -5158,7 +5160,7 @@ packages:
- '@types/node'
dev: true
/ts-node/10.9.1_3v2cms72gsblw7jmali7btb3pu:
/ts-node/10.9.1_awa2wsr5thmg3i7jqycphctjfq:
resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
hasBin: true
peerDependencies:
@@ -5177,7 +5179,7 @@ packages:
'@tsconfig/node12': 1.0.11
'@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.3
'@types/node': 18.11.9
'@types/node': 18.11.18
acorn: 8.8.1
acorn-walk: 8.2.0
arg: 4.1.3

View File

@@ -1,15 +1,7 @@
const BASE_URL = 'https://hub.snapshot.org'
export const URLS = {
EXPLORE: `${BASE_URL}/api/explore`,
GQL: `${BASE_URL}/graphql`,
}
export const HEADERS = {
origin: 'https://snapshot.org',
referer: 'https://snapshot.org/',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-site',
'sec-gpc': '1',
GH_SQL: 'https://api.github.com/graphql',
SNAPSHOT_EXPLORE: `${BASE_URL}/api/explore`,
SNAPSHOT_GQL: `${BASE_URL}/graphql`,
}

View File

@@ -0,0 +1,44 @@
import { URLS } from './constants'
import committersQuery from './graphql/committers-query'
const GH_PAT = process.env
if (GH_PAT === undefined) throw new Error('GH_PAT is not defined')
// const pickLogin : ()
export const getCommittersByOrg = async (org: string) => {
const res = await fetch(URLS.GH_SQL, {
body: JSON.stringify({
query: committersQuery,
variables: { login: org },
}),
headers: {
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
Authorization: `bearer ${process.env.GH_PAT}`,
'Content-Type': 'application/json',
},
method: 'POST',
})
const r = await res.json()
const repos = r.data.organization.repositories.nodes
// const repos = (await res.json()).data.organization.repositories.nodes
// console.log(repos)
return [
...new Set(
(repos as any[])
.reduce<string[]>((repos, repo) => {
// console.log(repo)
if (repo.defaultBranchRef !== null) {
repos.push(
repo.defaultBranchRef.target.history.nodes.map(
(node: any) => node.author.user.login,
),
)
}
return repos
}, [])
.flat(),
),
]
}

View File

@@ -1,3 +1,4 @@
import { URLS } from './constants'
import { getSpaces } from './get-spaces'
import spacesGqlQuery from './graphql/spaces-gql-query'
@@ -10,7 +11,7 @@ export const getGhOrgs = async ({
}): Promise<string[]> => {
const spacesIds = (await getSpaces({ min, size })()).map(({ id }) => id)
const res = await fetch('https://hub.snapshot.org/graphql', {
const res = await fetch(URLS.SNAPSHOT_GQL, {
body: JSON.stringify({
operationName: 'Spaces',
query: spacesGqlQuery,

View File

@@ -9,7 +9,7 @@ export const filterSpaces =
export const getSpaces =
({ min = 10, size = 100 }: { min: number; size: number }) =>
async () =>
fetch(URLS.EXPLORE).then(async (res) =>
fetch(URLS.SNAPSHOT_EXPLORE).then(async (res) =>
res.json().then((res) =>
Object.entries(res.spaces as Space[])
.reduce<Array<{ id: string; followers: number }>>(

View File

@@ -0,0 +1,28 @@
export default `
query orgs($login: String!) {
organization(login: $login) {
repositories(first: 100) {
nodes {
name
defaultBranchRef {
name
target {
... on Commit {
history(since: "2023-01-01T00:00:00Z") {
nodes {
author {
user {
login
}
}
}
}
}
}
}
}
}
}
}
`

25
src/graphql/gh.graphql Normal file
View File

@@ -0,0 +1,25 @@
query orgs {
organization(login: "uniswap") {
repositories(first: 100) {
nodes {
name
defaultBranchRef {
name
target {
... on Commit {
history(since: "2023-01-01T00:00:00Z") {
nodes {
author {
user {
login
}
}
}
}
}
}
}
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -30,6 +30,8 @@ const jestLintConfig: JestConfigWithTsJest = {
testPathIgnorePatterns: [
'<rootDir>/pnpm-lock.yaml',
'<rootDir>/test/coverage',
'<rootDir>/src/graphql/*.graphql',
'<rootDir>/src/graphql/.graphqlconfig',
],
}

View File

@@ -0,0 +1,13 @@
import { getCommittersByOrg } from '../../src/get-commiters-by-org'
describe('getCommitters', () => {
it('should return a list of committers', async () => {
const committers = await getCommittersByOrg('uniswap')
expect(committers.length).toBeGreaterThan(0)
committers.forEach((committer) => {
expect(typeof committer).toBe('string')
expect(committer).toBeTruthy()
})
})
})