mirror of
https://github.com/zkitter/groups.git
synced 2026-01-10 07:48:12 -05:00
feat: get list of spaces filtered by followers count from snapshot.org (#5)
* chore: update .eslintignore * feat:test: get spaces by min of followers * lint * fix: do filter using GitHub prop This prop is not available in response from explore api endpoint. Need to use a graphql query * Add script * format
This commit is contained in:
@@ -1,10 +1,7 @@
|
||||
node_modules
|
||||
package-lock.json
|
||||
pnpm-lock.yaml
|
||||
yarn.lock
|
||||
|
||||
# build dirs
|
||||
build
|
||||
dist
|
||||
|
||||
# Jest
|
||||
|
||||
44
README.md
44
README.md
@@ -1,40 +1,14 @@
|
||||
<div style='display: flex'>
|
||||
<img alt='ts icon' width='50' src='https://raw.githubusercontent.com/devicons/devicon/master/icons/typescript/typescript-original.svg'/>
|
||||
<span style='font-weight: bold'>  <strong>PROJECT TEMPLATE</strong></span>
|
||||
</div>
|
||||
<br/>
|
||||
# GH Groups
|
||||
|
||||
 
|
||||
[](https://coveralls.io/github/r1oga/ts-template?branch=main)
|
||||
[](https://github.com/prettier/prettier) [](http://standardjs.com)
|
||||
[](https://github.com/sezna/nps)
|
||||
Get list of GH users who contributed to the GitHub org of a given group of DAOs.
|
||||
|
||||
| Feature | With | Configuration File |
|
||||
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Typings | [Typescript](https://www.typescriptlang.org/) | [tsconfig.json](./tsconfig.json) |
|
||||
| Scripts | [Nps](https://github.com/sezna/nps) | [package-scripts.yaml](./package-scripts.yaml) |
|
||||
| Testing | [Jest](https://jestjs.io/), [ts-jest](https://kulshekhar.github.io/ts-jest/) | [jest.config.ts](test/jest.config.ts) |
|
||||
| Coverage reports | [Coveralls](https://coveralls.io/) | [Coveralls GitHub Action](https://github.com/marketplace/actions/coveralls-github-action) |
|
||||
| Linting | [Eslint](https://eslint.org/) | [.eslintrc.yaml](./.eslintrc.yaml) |
|
||||
| Formatting | [Prettier](https://prettier.io/) | [.prettierrc.yaml](./.prettierrc.yaml) |
|
||||
| Continuous Integration | [GitHub Workflow](https://docs.github.com/en/actions/using-workflows) | [.github/workflows](./.github/workflows) |
|
||||
| Import aliases | [Typescript paths](https://www.typescriptlang.org/tsconfig#paths), [module-alias](https://github.com/ilearnio/module-alias) | [tsconfig.json](https://github.com/r1oga/ts-template/blob/5d6983a6d28429b9dd256edf40bad5ee48c33d9c/tsconfig.json#L26), [package.json](https://github.com/r1oga/ts-template/blob/5d6983a6d28429b9dd256edf40bad5ee48c33d9c/package.json#L9) |
|
||||
| Rollup exports | [Barrelsby](https://github.com/bencoveney/barrelsby) | [.barrelsby.json](./.barrelsby.json) |
|
||||
| Containerization | [Docker](https://www.docker.com/) | [Dockerfile](./Dockerfile), [docker-compose.yaml](./docker-compose.yaml) |
|
||||
| Pre-commit hook (linting, formatting) | [Husky](https://typicode.github.io/husky), [lint-staged](https://github.com/okonet/lint-staged) | [pre-commit](./.husky/pre-commit), [.lintstagedrc.yaml](./.lintstagedrc.yaml) |
|
||||
| Security Checks | [Snyk](https://snyk.io/) | [snyk.yaml](./.github/workflows/snyk.yaml) |
|
||||
## Usage
|
||||
|
||||
## Start
|
||||
- script: `nps 'fetch -m <min followers amount> -s <group size>`
|
||||
- node
|
||||
|
||||
Node
|
||||
```
|
||||
import { getSpaces} from './src/getSpaces'
|
||||
|
||||
```commandline
|
||||
npm run setup
|
||||
nps start
|
||||
```
|
||||
|
||||
Docker
|
||||
|
||||
```commandline
|
||||
docker compose up
|
||||
```
|
||||
const spaces = await getSpaces({min, size})()
|
||||
```
|
||||
|
||||
@@ -16,6 +16,10 @@ scripts:
|
||||
script: nps lint.fix format.fix
|
||||
hiddenFromHelp: Fix linting and formatting errors
|
||||
|
||||
fetch:
|
||||
script: tsnd --cls --respawn --transpile-only scripts
|
||||
description: Fetch query results (-m <min> -s <size>)
|
||||
|
||||
format:
|
||||
default:
|
||||
script: nps 'test.once --selectProjects prettier --coverage false'
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
"@r1oga/eslint-config": "^1.1.6",
|
||||
"@r1oga/prettier-config": "^1.1.8",
|
||||
"@types/jest": "^29.2.3",
|
||||
"@types/yargs": "^17.0.19",
|
||||
"concurrently": "^7.6.0",
|
||||
"husky": "^8.0.2",
|
||||
"is-ci": "^3.0.1",
|
||||
@@ -33,7 +34,8 @@
|
||||
"ts-node-dev": "^2.0.0",
|
||||
"tsconfig-paths": "^4.1.0",
|
||||
"tslib": "^2.4.1",
|
||||
"typescript": "^4.9.4"
|
||||
"typescript": "^4.9.4",
|
||||
"yargs": "^17.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
|
||||
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
@@ -4,6 +4,7 @@ specifiers:
|
||||
'@r1oga/eslint-config': ^1.1.6
|
||||
'@r1oga/prettier-config': ^1.1.8
|
||||
'@types/jest': ^29.2.3
|
||||
'@types/yargs': ^17.0.19
|
||||
concurrently: ^7.6.0
|
||||
husky: ^8.0.2
|
||||
is-ci: ^3.0.1
|
||||
@@ -24,11 +25,13 @@ specifiers:
|
||||
tsconfig-paths: ^4.1.0
|
||||
tslib: ^2.4.1
|
||||
typescript: ^4.9.4
|
||||
yargs: ^17.6.2
|
||||
|
||||
devDependencies:
|
||||
'@r1oga/eslint-config': 1.1.6_bh7fyjwf3qvjuxqkkpsm2qjvfa
|
||||
'@r1oga/prettier-config': 1.1.8_prettier@2.8.1
|
||||
'@types/jest': 29.2.3
|
||||
'@types/yargs': 17.0.19
|
||||
concurrently: 7.6.0
|
||||
husky: 8.0.2
|
||||
is-ci: 3.0.1
|
||||
@@ -49,6 +52,7 @@ devDependencies:
|
||||
tsconfig-paths: 4.1.0
|
||||
tslib: 2.4.1
|
||||
typescript: 4.9.4
|
||||
yargs: 17.6.2
|
||||
|
||||
packages:
|
||||
|
||||
@@ -767,7 +771,7 @@ packages:
|
||||
'@types/istanbul-lib-coverage': 2.0.4
|
||||
'@types/istanbul-reports': 3.0.1
|
||||
'@types/node': 18.11.9
|
||||
'@types/yargs': 17.0.13
|
||||
'@types/yargs': 17.0.19
|
||||
chalk: 4.1.2
|
||||
dev: true
|
||||
|
||||
@@ -1036,8 +1040,8 @@ packages:
|
||||
'@types/yargs-parser': 21.0.0
|
||||
dev: true
|
||||
|
||||
/@types/yargs/17.0.13:
|
||||
resolution: {integrity: sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==}
|
||||
/@types/yargs/17.0.19:
|
||||
resolution: {integrity: sha512-cAx3qamwaYX9R0fzOIZAlFpo4A+1uBVCxqpKz9D26uTF4srRXaGTTsikQmaotCtNdbhzyUH7ft6p9ktz9s6UNQ==}
|
||||
dependencies:
|
||||
'@types/yargs-parser': 21.0.0
|
||||
dev: true
|
||||
|
||||
35
scripts/index.ts
Normal file
35
scripts/index.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { hideBin } from 'yargs/helpers'
|
||||
import yargs from 'yargs/yargs'
|
||||
|
||||
import { getSpaces } from '../src'
|
||||
|
||||
const options = {
|
||||
min: {
|
||||
alias: 'm',
|
||||
describe: 'DAO min number of followers on snapshot.org',
|
||||
type: 'number',
|
||||
},
|
||||
size: {
|
||||
alias: 's',
|
||||
describe: 'number of org to fetch from snapshot.org. 0 means no limit',
|
||||
type: 'number',
|
||||
},
|
||||
}
|
||||
|
||||
// @ts-expect-error
|
||||
const argv = yargs(hideBin(process.argv)).options(options).help().argv as {
|
||||
min: number
|
||||
size: number
|
||||
}
|
||||
|
||||
const main = async () => {
|
||||
const spaces = await getSpaces({ min: argv.min, size: argv.size })()
|
||||
console.log(spaces)
|
||||
}
|
||||
|
||||
main()
|
||||
.then(() => process.exit(0))
|
||||
.catch((err) => {
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
@@ -1,27 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# https://github.com/adrian-gheorghe/demo-docker-secrets-env-vars
|
||||
set -e
|
||||
|
||||
file_env() {
|
||||
local var="$1"
|
||||
local fileVar="${var}_FILE"
|
||||
local def="${2:-}"
|
||||
|
||||
if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then
|
||||
echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
|
||||
exit 1
|
||||
fi
|
||||
local val="$def"
|
||||
if [ "${!var:-}" ]; then
|
||||
val="${!var}"
|
||||
elif [ "${!fileVar:-}" ]; then
|
||||
val="$(< "${!fileVar}")"
|
||||
fi
|
||||
export "$var"="$val"
|
||||
unset "$fileVar"
|
||||
}
|
||||
|
||||
file_env "SECRET"
|
||||
|
||||
exec "$@"
|
||||
1
src/constants.ts
Normal file
1
src/constants.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const SNAPSHOT_API_URL = 'https://hub.snapshot.org/api/explore'
|
||||
30
src/get-spaces.ts
Normal file
30
src/get-spaces.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { SNAPSHOT_API_URL } from './constants'
|
||||
import { Space } from './types'
|
||||
|
||||
export const filterSpaces =
|
||||
(min: number) =>
|
||||
({ followers }: Space) =>
|
||||
followers !== undefined && followers >= min
|
||||
|
||||
export const getSpaces =
|
||||
({ min = 10, size = 100 }: { min: number; size: number }) =>
|
||||
async () =>
|
||||
fetch(SNAPSHOT_API_URL).then(async (res) =>
|
||||
res.json().then((res) =>
|
||||
Object.values(res.spaces as Space[])
|
||||
.reduce<Space[]>((spaces, space) => {
|
||||
// console.log(space)
|
||||
if (filterSpaces(min)(space)) spaces.push(space)
|
||||
|
||||
return spaces
|
||||
}, [])
|
||||
// @ts-expect-error - filterSpaces already ensures that props are defined
|
||||
.sort((a, b) => b.followers - a.followers)
|
||||
.slice(0, size),
|
||||
),
|
||||
)
|
||||
|
||||
export const get100TopDaosWithMin10kFollowers = getSpaces({
|
||||
min: 10_000,
|
||||
size: 0,
|
||||
})
|
||||
@@ -0,0 +1 @@
|
||||
export * from './get-spaces'
|
||||
|
||||
5
src/types.ts
Normal file
5
src/types.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export interface Space {
|
||||
followers?: number
|
||||
github?: string
|
||||
name: string
|
||||
}
|
||||
24
test/unit/filter-spaces.test.ts
Normal file
24
test/unit/filter-spaces.test.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { filterSpaces } from '../../src'
|
||||
|
||||
describe('filterSpaces', () => {
|
||||
it('should return true if followers is greater than min', () => {
|
||||
const followers = 100
|
||||
const min = 10
|
||||
expect(filterSpaces(min)({ followers, name: 'name' })).toBe(true)
|
||||
})
|
||||
it('should return false if followers is less than min', () => {
|
||||
const followers = 10
|
||||
const min = 100
|
||||
expect(
|
||||
filterSpaces(min)({ followers, github: 'github', name: 'name' }),
|
||||
).toBe(false)
|
||||
})
|
||||
|
||||
it('should return false if followers is undefined', () => {
|
||||
const followers = undefined
|
||||
const min = 100
|
||||
expect(
|
||||
filterSpaces(min)({ followers, github: 'github', name: 'name' }),
|
||||
).toBe(false)
|
||||
})
|
||||
})
|
||||
28
test/unit/get-spaces.test.ts
Normal file
28
test/unit/get-spaces.test.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { get100TopDaosWithMin10kFollowers, getSpaces } from '../../src'
|
||||
|
||||
describe('getSpaces', () => {
|
||||
it('should return an array of spaces', async () => {
|
||||
const MIN = 20_000
|
||||
const SIZE = 50
|
||||
|
||||
const spaces = await getSpaces({ min: MIN, size: SIZE })()
|
||||
|
||||
expect(spaces.length).toBeGreaterThan(0)
|
||||
expect(spaces.length).toBeLessThanOrEqual(SIZE)
|
||||
spaces.forEach(({ followers, name }) => {
|
||||
expect(followers).toBeGreaterThanOrEqual(MIN)
|
||||
expect(name).toBeTruthy()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('getTop100DaosWithMin10kFollowers', () => {
|
||||
it('should return an array of spaces', async () => {
|
||||
const spaces = await get100TopDaosWithMin10kFollowers()
|
||||
|
||||
expect(spaces.length).toBeLessThanOrEqual(100)
|
||||
spaces.forEach(({ followers }) => {
|
||||
expect(followers).toBeGreaterThanOrEqual(10_000)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"include": ["src", "test"],
|
||||
"include": ["src", "scripts", "test"],
|
||||
"exclude": ["test/coverage"],
|
||||
"files": ["node_modules/jest-chain/types/index.d.ts"],
|
||||
"compilerOptions": {
|
||||
|
||||
Reference in New Issue
Block a user