You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
2.6 KiB

// Native
const { homedir } = require('os')
const path = require('path')
// Packages
const fs = require('fs-extra')
const ms = require('ms')
// Ours
const { get: getUser } = require('./user')
// `8h` is arbitrarily used based on the average sleep time
const TTL = ms('8h')
let file = process.env.NOW_JSON
? path.resolve(process.env.NOW_JSON)
: path.resolve(homedir(), '.now.json')
function setConfigFile(nowjson) {
file = path.resolve(nowjson)
}
function save(data) {
fs.writeFileSync(file, JSON.stringify(data, null, 2))
}
/**
* Reads the config file
*
* Optionally, always queries the API to get the user info even if the
* config file is not present
*
* @param {Boolean} force [false] Queries the API even if the config
* file is not present. If `true`, `token`
* *must* be specified
* @param {String} token Will be used to autenticate in the API
if needed
* @param {String} apiUrl URL of the API to be used
* @return {Object}
*/
async function read({ force = false, token, apiUrl } = {}) {
let existing = {}
try {
existing = fs.readFileSync(file, 'utf8')
existing = JSON.parse(existing)
} catch (err) {}
// Will happen if `force`d or if `--token` is used and it's different from
// The one that's stored (which can be `undefined`)
if ((force && token) || (token && token !== existing.token)) {
const user = await getUser({ token, apiUrl })
if (user) {
return {
token,
user: {
uid: user.uid,
username: user.username,
email: user.email
},
currentTeam: existing.currentTeam
}
}
return {}
}
if (!existing.token) {
return {}
}
if (!existing.lastUpdate || Date.now() - existing.lastUpdate > TTL) {
// TODO: update `teams` info
const token = existing.token
const user = await getUser({ token })
if (user) {
existing.user = user
existing.lastUpdate = Date.now()
save(existing)
}
}
return existing
}
/**
* Merges the `data` object onto the
* JSON config stored in `.now.json`.
*
* (atomic)
* @param {Object} data
*/
async function merge(data) {
const cfg = Object.assign({}, await read(), data)
save(cfg)
}
// Removes a key from the config and store the result
async function remove(key) {
const cfg = await read()
delete cfg[key]
fs.writeFileSync(file, JSON.stringify(cfg, null, 2))
}
// We need to remove the config file when running `now logout`
const removeFile = async () => fs.remove(file)
module.exports = {
setConfigFile,
read,
merge,
remove,
removeFile
}