I tried to come up with a good challenge to learn some Rx.js programming and I came up with this chain of operations below. As well as a bit of code that works and does these things.
- Take github username
- Create folder based on username (
/repos-${user}) - Get all repos for username (
https://api.github.com/users/${user}/repos) - Get the hash of the repo data
- Create file where name is hash and content is repo
I'm looking for insights and optimizations, shortcuts, etc, to make this better.
Here's the code.
import { join } from 'path'
import axios from 'axios'
import Rx from 'rx'
import Promise from 'bluebird'
import crypto from 'crypto'
import fs from 'fs-extra'
import Debug from 'debug'
let debug = Debug('github-repos')
Promise.promisifyAll(fs)
let {
ensureDirAsync,
outputJsonAsync } = fs
function getRepos (user) {
let theUrl = `https://api.github.com/users/${user}/repos`
return axios.get(theUrl)
.then(result => {
debug(`got results back for ${user}`)
return result.data
})
}
function getHash (json) {
let text = JSON.stringify(json)
return crypto.createHash('md5').update(text).digest('hex')
}
function createDir (user) {
return ensureDirAsync(join(__dirname, `/repos-${user}`))
}
function createFile (user, hash, data) {
let file = join(__dirname, `/repos-${user}/${hash}.json`)
return outputJsonAsync(file, data).then(x => file)
}
let ghUser$ = Rx.Observable.from(['reggi', 'jackofseattle', 'nolanlawson'])
let ensureUser$ = ghUser$
.do((u) => debug(`Creating directory for: ${u}`))
.flatMap(u => createDir(u))
let getRepos$ = ghUser$
.do((u) => debug(`fetching user repos for: ${u}`))
.flatMap(u => getRepos(u))
let repos$ = getRepos$
.flatMap(repos => repos.map(repo => ({hash: getHash(repo), repo}))) // create hash for each
let fileWriter$ = repos$
.map(repo => ({user: repo.repo.owner.login, hash: repo.hash, repo: repo.repo}))
.flatMap(({user, hash, repo}) => {
return createFile(user, hash, repo)
})
.do((file) => debug(`wrote a new repo to json ${file}`))
.toArray()
let reposSubscription = fileWriter$.subscribe(
function (x) {
debug('subscription')
},
function (err) {
console.log('Error: %s', err)
},
function (e) {
debug('Completed')
});