UNPKG

cheetah-framework

Version:

Cheetah Framework JS used in all our applications

137 lines (110 loc) 3.32 kB
const defaultParserOptions = { verb: 'index', acceptedFieldFilter: () => true, afterFieldParse: field => field, labelPrefix: 'structure.labels.' } class Structure { constructor (structure, parserOptions = {}) { this.parserOptions = _.defaults(parserOptions, defaultParserOptions) this.structure = structure[this.parserOptions.verb] this.translationErrors = [] this.warn = true } toQueryBuilderFields () { this.translationErrors.splice(0) const fields = this.parseFieldStructure(this.convertToFieldMap()) if (this.warn && this.translationErrors.length) { console.warn(this.translationErrors.join(',\n')) } return fields } noWarn () { this.warn = false return this } convertToFieldMap () { const fieldMap = new Map() _.each(this.structure.criteria_fields, fieldData => { if ( !this.parserOptions.acceptedFieldFilter(fieldData) || // If field is not accepted by user-defined filter !this.isAcceptedField(fieldData) // or by default filter. ) { return } const keyPath = fieldData.field.split('.') const fieldKey = keyPath.pop() this.buildFieldStructure(keyPath, fieldKey, fieldData, fieldMap) }) return fieldMap } isAcceptedField (field) { if (field.type === 'array' && _.get(field, 'sub_definition.length') !== 1) { return false } return true } buildFieldStructure (keyPath, fieldKey, field, fieldMap, relationPath = []) { if (keyPath.length) { if (this.keyIsRelation([...relationPath, keyPath[0]].join('.'))) { const subKey = keyPath.shift() if (!fieldMap.has(subKey)) { fieldMap.set(subKey, new Map()) } this.buildFieldStructure(keyPath, fieldKey, field, fieldMap.get(subKey), [...relationPath, subKey]) } else { fieldMap.set([...keyPath, fieldKey].join('.'), field) } } else { fieldMap.set(fieldKey, field) } } parseFieldStructure (fieldMap) { return _.map([...fieldMap], ([fieldKey, field]) => { const parsedField = this.parseField(field, fieldKey) return this.parserOptions.afterFieldParse(parsedField) }) } parseField (field, key) { const baseField = { key, label: key.split('.').map(key => { const path = this.parserOptions.labelPrefix + key if (cheetahApp.$te(path)) { return cheetahApp.$tc(path) } else { this.translationErrors.push(`Missing translation path "${path}"`) } return path }).join(' → ') } if (field instanceof Map) { return { ...baseField, type: 'relation', relationFields: this.parseFieldStructure(field) } } if (field.type === 'array') { return this.parseField(_.head(field.sub_definition), key) } if (field.enum_values) { return { ...baseField, type: 'enum', choices: field.enum_values } } const [type, typeModifier] = field.type.split(':') return { ...baseField, type, typeModifier, ...(field.type === 'model' ? { resource: field.related } : {}) } } keyIsRelation (key) { return _.includes(this.structure.with, key) } } export default Structure