import * as _ from 'lodash'; function simpleAccessor(lens: string, def: string = '') { return { get: (li: any) => { let val = _.get(li, lens, def); return val; }, set: (li: any, value: string) => { let lexItem = _.cloneDeep(li); let ret = _.set(lexItem, lens, value); return ret; } }; } function simpleAttrAccessor(attrPred: any) { let { attribVal, attribKey, pred, lens } = attrPred; let def = (value: any) => ({ _: value, $: { [attribKey]: attribVal } }); return { get: (li: any) => { let allProps = _.get(li, lens, def('')); let prop = _.filter(allProps, (m) => { return pred(m); }); let mcls = _.get(prop, '[0]._', ''); return mcls; }, set: (li: any, value: string) => { let lexItem = _.cloneDeep(li); let allProps = _.get(lexItem, lens, []); if (allProps.length > 0) { let prop = _.filter(allProps, (m) => { return pred(m); }); _.set(prop, '[0]._', value); } else { _.set(lexItem, lens, [def(value)]); } return lexItem; } }; } function listAttrAccessor(attrPred: any) { let { pred, lens } = attrPred; return { get: (li: any) => { let def: any = []; let morphProps = _.get(li, lens, def); let morphExps = _.filter(morphProps, (m) => { return pred(m); }); let mEs = morphExps.map((me) => { return _.get(me, '_', me); }); return mEs; }, set: (li: any, value: any) => { let lexItem = _.cloneDeep(li); let allProps = _.get(lexItem, lens, []); if (allProps.length > 0) { let keepProps = _.filter(allProps, (m) => { return !pred(m); }); _.set(lexItem, lens, _.concat(keepProps, value)); } else { _.set(lexItem, lens, value); } return lexItem; } }; } function propListAttrAccessor(attrPred: any) { let { attribKey, pred, lens } = attrPred; return { get: (li: any) => { let def: any = []; let morphProps = _.get(li, lens, def); let morphExps = _.filter(morphProps, (m) => { return pred(m); }); let mEs = morphExps.map((me) => { let value = _.get(me, '_', me); let key = _.get(me, '$.' + attribKey, ''); return { value, key }; }); return mEs; }, set: (li: any, value: any) => { let lexItem = _.cloneDeep(li); let allProps = _.get(lexItem, lens, []); let setValue = value.map((v: any) => { let ret = {}; _.set(ret, '$.form', v.key); _.set(ret, '_', v.value); return ret; }); if (allProps.length > 0) { let keepProps = _.filter(allProps, (m) => { return !pred(m); }); _.set(lexItem, lens, _.concat(keepProps, setValue)); } else { _.set(lexItem, lens, setValue); } return lexItem; } }; } const attrPredGen = (lens: string, key: string, val: string, comp: any) => { const pred = (m: any) => comp(_.get(m, '$.' + key, ''), val); return { lens, attribKey: key, attribVal: val, pred }; }; const fieldMetaMap = { label: { type: 'text', ...simpleAccessor('label[0]'), }, unl: { type: 'text', ...simpleAccessor('unl[0]'), }, synset: { type: 'text', ...simpleAccessor('lexprops[0].wnsynset[0]'), }, guid: { type: 'text', ...simpleAccessor('guid[0]'), }, pos: { type: 'select', ...simpleAccessor('pos[0]'), }, image: { type: 'preview', ...simpleAccessor('image[0]'), }, relations: { type: 'text', ...simpleAccessor('relations[0]'), }, frame: { type: 'select', ...simpleAttrAccessor(attrPredGen( 'syntacticprops[0].property', 'id', 'frame', _.isEqual )), }, cat: { type: 'select', ...simpleAttrAccessor(attrPredGen( 'uiprops[0].property', 'id', 'cat', _.isEqual )), }, subcat: { type: 'select', ...simpleAttrAccessor(attrPredGen( 'uiprops[0].property', 'id', 'subcat', _.isEqual )), }, morphclass: { type: 'select', ...simpleAttrAccessor(attrPredGen( 'lexprops[0].morphology[0].morph', 'form', 'morphclass', _.isEqual )) }, morphexceptions: { type: 'proplist', ...propListAttrAccessor(attrPredGen( 'lexprops[0].morphology[0].morph', 'form', 'morphclass', _.negate(_.isEqual) )) }, stats: { type: 'text', ...simpleAccessor('stats[0].property[0]._'), }, lang: { type: 'select', options: ['en', 'es'], ...simpleAccessor('$.id', 'en'), }, syntacticprops: { type: 'list', ...listAttrAccessor(attrPredGen( 'syntacticprops[0].property', 'id', 'frame', _.negate(_.isEqual) )) }, groups: { type: 'list', ...listAttrAccessor(attrPredGen( 'groups[0].property', 'id', 'frame', _.negate(_.isEqual) )) }, }; function getSelectOptions(field: string, entries: any) { let allOpts = entries.map((q: any) => { return fieldMetaMap[field].get(q); }); switch (fieldMetaMap[field].type) { case 'select': return _.uniq(allOpts); case 'list': return _.uniq(_.flatten(allOpts)); case 'proplist': return _.uniq(_.map(_.flatten(allOpts), (v) => _.get(v, 'key'))); default: return []; } } export const xmlToEntries = (xmlData: any) => { let allEntries = _.chain(xmlData) .get('document.lexicon[0].item') .flatMap((o: any) => _.chain(o) .get('entry') .map((p: any) => _.chain(p) .get('lang[0]') .set('guid[0]', o.$.guid) .value()) .value() ) .value(); let langReducer = ((result: any, q: any) => { let lang = fieldMetaMap.lang.get(q); (result[lang] || (result[lang] = [])).push(q); return result; }); let langEntries = _.reduce(allEntries, langReducer, {}); let langs = _.keys(langEntries); let selectableFields = ['select', 'list', 'proplist']; let selectFields = _.fromPairs(langs.map((lang) => { let langOpts = _.fromPairs(_.keys(fieldMetaMap).filter((s) => { return _.includes(selectableFields, fieldMetaMap[s].type); }).map((s) => { let entries = _.get(langEntries, lang, 'en'); // let allOpts = entries.map((q: any) => { // return fieldMetaMap[s].get(q); // }); // let select = _.isEqual(fieldMetaMap[s].type, 'select'); // let selectOptions = select ? _.uniq(allOpts) : _.uniq(_.flatten(allOpts)); return [s, getSelectOptions(s, entries)]; })); return [lang, langOpts]; })); return ({ allEntries, selectFields, fieldMetaMap }); };