Code Review Asked on November 25, 2021
Improved version of the original question
I’ve created a simple npm module and CLI program to get the latest GitHub and Bitbucket release from their APIs using Node.js. Please tell me if there’s anything to improve!
#!/usr/bin/env node
const fetch = require("node-fetch");
/**
* @param {string} string
* @return {string}
*/
const normalize = (string) => {
try {
return string.toUpperCase().trim()
} catch (e) {
return string
}
}
/**
* @param {string} url
* @return {string}
*/
const getJSON = async (url) => {
return (await (await fetch(url)).json())
}
module.exports.providerMethods = {
GITHUB: async ({user, repo, part = ""}) => {
let json = await getJSON(`https://api.github.com/repos/${user}/${repo}/releases/latest`)
if (json.message === "Not Found") throw "Invalid repository"
if (!("assets" in json)) throw "Rate limit exceeded"
let browser_download_urls = json.assets.map(asset => asset.browser_download_url)
return browser_download_urls.filter(url => url.includes(part))
},
BITBUCKET: async ({user, repo, part = ""}) => {
let json = await getJSON(`https://api.bitbucket.org/2.0/repositories/${user}/${repo}/downloads/`)
if (json.type === "error") throw "Invalid repository"
let links = json.values.map(value => value.links.self.href)
return links.filter(url => url.includes(part))
}
}
/**
* @param {string} provider
* @param {string} user
* @param {string} repo
* @param {string} part
*/
module.exports.getRelease = async ({provider, user, repo, part = ""}) => {
if (!(module.exports.providerMethods[normalize(provider)])) {
throw "Invalid provider"
}
return module.exports.providerMethods[normalize(provider)]({user, repo, part})
}
const usage = _ => {
console.log(
`Usage: get-release (github|bitbucket) user repo [partofreleasefile]
Ex: get-release github phhusson treble_experimentations
get-release github phhusson treble_experimentations arm64-ab-gapps
get-release bitbucket JesusFreke smali
get-release bitbucket JesusFreke smali baksmali`
)
process.exit(1)
}
// If via CLI
if (require.main === module) {
let args = process.argv.slice(2)
if (args.length !== 3 && args.length !== 4) {
usage()
}
module.exports.getRelease({
provider: args[0],
user: args[1],
repo: args[2],
part: args[3]
}).then(result => {
if (result.length !== 1) {
console.log(result)
} else {
console.log(result[0])
}
}).catch(error => {
console.log(error)
usage()
process.exit(1)
})
}
/**
* Options:
* {
* provider: (github | bitbucket),
* user: username,
* repo: repository,
* part: part of release file name - optional
* }
*
*/
const { getRelease, providerMethods } = require("get-release")
;(async _ => {
let url = await getRelease(
{
provider: "github",
user: "phhusson",
repo: "treble_experimentations",
part: "arm64-ab-gapps"
}
)
console.log(url[0])
})()
const { getRelease, providerMethods } = require("get-release")
providerMethods.GITLAB = async ({user, repo, part = ""}) => {
// Custom code, should return a string
}
Now that you've allowed the users to add custom providers, how about hiding the providerMethods
object itself, and only providing a function which allows them to add to it. This would allow you to also validate if the users' want to override behaviour for predefined providers.
You have a process.exit(1)
inside the call to usage()
. Butm when used from cli, you catch all exceptions, then call the usage
function, and against have another process.exit(1)
.
The call to usage should not be exiting from the program entirely. It is already handled in case of errors. You can then have a --help
commandline parameter, which spits out the usage string (without raising an error for the shell).
Most of your if-
conditions use the negated equality check, which is somewhat harder to follow for a developer (at least in my experience). When checking for args.length
, you have double negation checks. It took me almost a minute to figure out what it is supposed to do. How about applying de Morgan's laws:
if (!(args.length === 3 || args.length === 4))
Or, maybe simply adding a comment?
Also consider:
console.log((result.length === 1) ? result[0] : result)
Answered by hjpotter92 on November 25, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP