dobo
Version:
DBMS for Bajo Framework
56 lines (52 loc) • 2.38 kB
JavaScript
/**
* Sanitize payload body against its model
*
* @method
* @memberof Dobo
* @async
* @param {Object} [options={}]
* @param {Object} [options.body={}]
* @param {Object} [options.model={}]
* @param {boolean} [options.partial=false]
* @param {boolean} [options.strict=false]
* @param {Array} [options.extFields=[]]
* @returns {Object}
*/
async function sanitizeBody ({ body = {}, partial, strict, extFields = [], noDefault, truncateString, onlyTypes = [], action, allProps } = {}) {
const { isSet } = this.app.lib.aneka
const { sanitizeByType } = this.app.dobo
const { omit, has } = this.app.lib._
const result = {}
const sanitize = (name, type) => {
const opts = { strict, action, model: this.name, outputFormat: 'native' }
result[name] = sanitizeByType(result[name], type, opts)
if (['updateRecord', 'upsertRecord'].includes(action) && type === 'string' && result[name] === '') result[name] = null
}
const omitted = []
const details = []
const props = allProps ? this.properties : this.getNonVirtualProperties()
const properties = [...props, ...extFields]
for (const prop of properties) {
try {
if (partial && !has(body, prop.name)) {
// if (prop.type === 'array') result[prop.name] = null
continue
}
result[prop.name] = body[prop.name]
if (prop.type === 'array' && isSet(result[prop.name]) && !Array.isArray(result[prop.name])) result[prop.name] = [result[prop.name]]
if (isSet(result[prop.name])) sanitize(prop.name, prop.type)
if (result[prop.name] === null) continue
if (truncateString && isSet(result[prop.name]) && ['string', 'text'].includes(prop.type)) result[prop.name] = result[prop.name].slice(0, prop.maxLength)
if (prop.name.endsWith('Id') && isSet(result[prop.name]) && prop.type === 'string' && ['smallint', 'integer'].includes(this.driver.idField.type)) result[prop.name] = result[prop.name] + ''
if (result[prop.name] === undefined) omitted.push(prop.name)
} catch (err) {
details.push({ field: prop.name, error: err.message, value: body[prop.name], ext: { type: prop.type } })
}
}
if (details.length > 0) {
const payload = { details, statusCode: 422, code: 'BODY_SANITIZATION', model: this.name }
throw this.plugin.error('sanitizeBodyError', payload)
}
return omit(result, omitted)
}
export default sanitizeBody