UNPKG

@noggin/elastic-noggin-sdk

Version:
206 lines (163 loc) 5.55 kB
import { cloneDeep, merge, isArray, isEqual, union } from 'lodash'; import { IClientT, IEno, IField, II18n, IServerT, ISource, Sid, Tip } from './types'; import { EnoFactory } from '../EnoFactory'; import dataConstants from '../constants'; export { Eno }; interface IToJSONOption { propWhiteList?: string[]; } class Eno implements IEno { readonly tip: Tip = ''; readonly sid: Sid = ''; readonly serverT?: IServerT; readonly clientT?: IClientT; readonly source?: ISource; constructor(proto: IEno) { merge(this, cloneDeep(proto)); } createDeletedEno(branch?: Tip): Eno { const enoFact = new EnoFactory(); enoFact.setProtoToPatch(this); enoFact.setDeleted(true); if (branch) { enoFact.setBranch(branch); } return enoFact.makeEno(); } createSecurityChangedEno(security: Tip, branch?: Tip): Eno { const enoFact = new EnoFactory(); enoFact.setProtoToPatch(this); enoFact.setSecurity(security); if (branch) { enoFact.setBranch(branch); } return enoFact.makeEno(); } toJson(option: IToJSONOption = { }): IEno { const json = Object.create(null); for (const property of Object.keys(this)) { if (option && option.propWhiteList && option.propWhiteList.indexOf(property) === -1) { continue; } json[property] = cloneDeep((<any>this)[property]); } return json; } getBranch(): Tip|null { return this.serverT ? this.serverT.branch : this.clientT ? this.clientT.branch : null; } getType(): Tip|null { return this.source ? this.source.type : null; } getSessionId(): Tip|null { return this.serverT ? this.serverT.session : null; } hasError(): boolean { return !!(this.serverT && this.serverT.error && this.serverT.error.length > 0); } getFieldFormula(fieldTip: Tip): string|null { if (this.source && this.source.field) { const field = this.source.field.filter((f: IField) => f.tip === fieldTip)[0]; return field && field.formula && field.formula.length > 0 ? field.formula[0] : null; } return null; } getFieldValues(fieldTip: Tip, lang: string = dataConstants.LANG_DEFAULT): string[] { if (!this.source || !this.source.field) { return []; } const field = this.source.field.filter((f: IField) => f.tip === fieldTip)[0]; if (!field) { return []; } if (field.value) { return field.value; } if (!field.i18n) { return []; } lang = lang.toLowerCase(); const maybeLang = lang.substr(0, 2); let maybeLangIndex: number|null = null; let defaultLangIndex: number|null = null; for (let i = 0; i < field.i18n.length; i++) { if (field.i18n[i].lang === lang) { return field.i18n[i].value || []; } if (maybeLangIndex === null && field.i18n[i].lang.substr(0, 2) === maybeLang) { maybeLangIndex = i; } else if (defaultLangIndex === null && field.i18n[i].lang === dataConstants.LANG_DEFAULT) { defaultLangIndex = i; } } if (maybeLangIndex !== null) { return field.i18n[maybeLangIndex].value || []; } if (defaultLangIndex !== null) { return field.i18n[defaultLangIndex].value || []; } return []; } getFieldStringValue(fieldTip: Tip, lang: string = dataConstants.LANG_DEFAULT): string | null { return this.getFieldValues(fieldTip, lang).join(', ') || null; } getFieldNumberValue(fieldTip: Tip, lang: string = dataConstants.LANG_DEFAULT): number | null { const values = this.getFieldValues(fieldTip, lang); if (values.length === 0) { return null; } const numberValue = parseFloat(values[0]); if (isNaN(numberValue)) { return null; } return numberValue; } getFieldBooleanValue(fieldTip: Tip, lang: string = dataConstants.LANG_DEFAULT): boolean { const fieldValues = this.getFieldValues(fieldTip, lang); return fieldValues && fieldValues.length > 0 && fieldValues.filter((value: string) => value !== 'true').length === 0; } getFieldJsonValue(fieldTip: Tip): any | null { const value = this.getFieldValues(fieldTip); if (value && value.length > 0) { return JSON.parse(value[0]); } return null; } getFieldRawI18n(fieldTip: Tip): II18n[] { const field = this.source.field.filter((f: IField) => f.tip === fieldTip)[0]; if (isArray(field.i18n)) { return [...field.i18n]; } if (isArray(field.value)) { return [{ lang: dataConstants.LANG_DEFAULT, value: field.value }]; } return []; } // Do deep comparison of this eno and the given eno to check if anything is different. // Not that this does not compare nonce and parent as this is for comparing content isContentDiff(eno: Eno): boolean { if (!this.source || !eno.source) { return true; } return this.source.deleted !== eno.source.deleted || this.source.type !== eno.source.type || this.source.security !== eno.source.security || this._isFieldDiff(eno); } private _isFieldDiff(eno: Eno): boolean { if (!this.source || !this.source.field || !eno.source || !eno.source.field) { return true; } const allFieldTips = union(this.source.field.map(iField => iField.tip), eno.source.field.map(iField => iField.tip)); for (const fieldTip of allFieldTips) { const isDiff = !isEqual(this.getFieldValues(fieldTip), eno.getFieldValues(fieldTip)); if (isDiff) { return true; } } return false; } }