jsonql-contract
Version:
JS API / command line tool to generate the contract.json for jsonql
145 lines (132 loc) • 4.2 kB
JavaScript
// some utils methods
const fsx = require('fs-extra')
const { extname, resolve } = require('path')
const { transform } = require('lodash')
const { isObject, isObjectHasKey } = require('jsonql-params-validator')
const { JsonqlError } = require('jsonql-errors')
const { timestamp } = require('jsonql-utils')
const { SOCKET_AUTH_NAME } = require('jsonql-constants')
const checkOptions = require('./options')
const debug = require('debug')
const MODULE_NAME = 'jsonql-contract'
const getTimestamp = () => timestamp(true)
const getDebug = (name) => debug(MODULE_NAME).extend(name)
/**
* check if there is a config file and use that value instead
* @param {object} opts transformed
* @return {object} config from file
*/
const checkForConfigFile = opts => {
if (opts.configFile) {
const cfile = resolve(opts.configFile)
if (fsx.existsSync(cfile)) {
const ext = extname(cfile).replace('.','').toLowerCase()
return (ext === 'json')
? fsx.readJsonSync(cfile)
: require(cfile)
} else {
console.info(`Config file: ${cfile} could not be found!`)
}
}
return opts
}
/**
* break down the process from applyDefaultOptions
* @param {object} config user supply
* @param {boolean|string} cmd command from cli
* @return {object} Promise resolve to transformed version
*/
const getConfigFromArgs = (config, cmd) => (
Promise.resolve(
transform(config, (result, value, key) => {
if (key === '_') {
switch (cmd) {
case 'create':
let [inDir, outDir] = value
result.inDir = inDir
result.outDir = outDir
break
case 'remote':
// @TODO
throw new Error('Not support at the moment!')
case 'config':
// we don't need to do anything here
// console.log('config', key, value)
break
}
} else {
result[key] = value
}
}, {})
)
)
/**
* normalize the parameter before passing to the config
* @param {object} config could be argv or direct
* @param {boolean|string} [cmd=false] when calling from cli it will get what cmd its calling
* @return {object} tested and filtered
*/
const applyDefaultOptions = (config, cmd = false) => (
getConfigFromArgs(config, cmd)
.then(config => {
getDebug('applyDefaultOptions')('show config', config)
if (config.public === 'true' || config.public === 1 || config.public === '1') {
config.public = true // because it might be a string true
}
return config
})
.then(checkForConfigFile)
.then(checkOptions)
)
/**
* create a message to tell the user where the file is
* @param {object} config clean supply
* @return {function} accept dist param --> return config
*/
const checkFile = config => {
return dist => {
if (config.returnAs === 'file') {
if (!fsx.existsSync(dist)) {
throw new JsonqlError('File is not generated!', dist)
}
console.info('Your contract file generated in: %s', dist)
} else {
if (!isObject(dist)) {
throw new JsonqlError('Contract json not in the correct format!')
}
}
return config // now keep returning the config for next op
}
}
/**
* ported from the public-contract/index to avoid a circular referenc
* take this out on it's own and also export it for use later
* @1.9.1 we keep the login method if this is a standalone
* @param {object} contract to process
* @param {string} key the type key
* @param {object} config for extract the validatorHandlerName
* @return {object} cleaned contract
*/
function removeSrvAuthFromContract(contract, key, config) {
const { disconnectHandlerName, validatorHandlerName } = config
let names = [validatorHandlerName]
if (key === SOCKET_AUTH_NAME) {
names.push(disconnectHandlerName)
}
const ctn = names.length
for (let i = 0; i < ctn; ++i) {
let name = names[i]
if (contract[key] && isObjectHasKey(contract[key], name)) {
delete contract[key][name]
}
}
return contract
}
// export
module.exports = {
removeSrvAuthFromContract,
getTimestamp,
checkFile,
applyDefaultOptions,
getDebug
}