UNPKG

dobo

Version:

DBMS for Bajo Framework

68 lines (66 loc) 3.24 kB
/** * Sanitize record to conform with the model's definition * * @method * @async * @param {Object} [record] - Record object * @param {Array} [options.fields] - Array of field names to be picked * @param {Object} [options.hidden=[]] - Additional fields to be hidden in addition the one defined in model * @param {boolean} [options.forceNoHidden] - Force ALL fields to be picked, thus ignoring hidden fields * @returns {Object} */ async function sanitizeRecord (record = {}, opts = {}) { const { fields = [], hidden = [], forceNoHidden } = opts const { isEmpty, map, without, isArray, isFunction, isString, get, cloneDeep } = this.app.lib._ const { fillObject } = this.app.lib.aneka const { callHandler, format } = this.app.bajo let allHidden = without([...this.hidden, ...hidden], 'id') if (forceNoHidden === true) allHidden = [] else if (isArray(forceNoHidden)) allHidden = without(allHidden, ...forceNoHidden) let newFields = [...fields] if (isEmpty(newFields)) newFields = map(this.properties, prop => prop.name) if (!newFields.includes('id')) newFields.unshift('id') newFields = without(newFields, ...allHidden) const body = fillObject(record, newFields, null) const newRecord = await this.sanitizeBody({ body, partial: true, noDefault: true, allProps: true }) if (record._ref) newRecord._ref = cloneDeep(record._ref) for (const key in newRecord) { const prop = this.getProperty(key) if (!prop) continue const val = ['object', 'array'].includes(prop.type) ? cloneDeep(newRecord[key]) : newRecord[key] if (isFunction(prop.getValue)) newRecord[key] = await prop.getValue.call(this, val, newRecord, opts) else if (isString(prop.getValue)) newRecord[key] = await callHandler(this.plugin, this, val, newRecord, opts) } if (opts.fmt) { newRecord._fmt = cloneDeep(newRecord) delete newRecord._fmt._ref for (const key in newRecord) { const prop = this.getProperty(key) if (!prop) continue let value = ['object', 'array'].includes(prop.type) ? cloneDeep(newRecord[key]) : newRecord[key] if (prop.values) { const values = await this.buildPropValues(prop, opts) if (isArray(value)) value = value.map(v => (values.find(opt => opt.value === v) ?? {}).text ?? v) else value = (values.find(v => v.value === value) ?? {}).text ?? value } if (prop.format === false) newRecord._fmt[key] = value + '' else if (isFunction(prop.format)) newRecord._fmt[key] = await prop.format.call(this, value, newRecord, opts) else if (isString(prop.format)) newRecord._fmt[key] = await callHandler(this.plugin, this, value, newRecord, opts) else { const options = { lang: get(opts, 'req.lang'), datetime: { dateStyle: get(opts, 'req.site.setting.sumba.dateStyle'), timeStyle: get(opts, 'req.site.setting.sumba.timeStyle'), timeZone: get(opts, 'req.site.setting.sumba.timeZone') }, latitude: ['lat', 'latitude'].includes(key), longitude: ['lon', 'lng', 'longitude'].includes(key) } newRecord._fmt[key] = format(value, prop.type, options) } } } return newRecord } export default sanitizeRecord