import {Condition} from './Condition' import {Modification} from './Modification' import {compareBy, DataClass, parseObject, ReifiedType, TProperty1} from "@lightningkite/khrysalis-runtime"; import {SortPart} from "./SortPart"; import {DataClassPath, DataClassPathAccess, DataClassPathNotNull, DataClassPathSelf} from "./DataClassPath"; (Condition as any).fromJSON = (data: Record, types: Array): Condition => { const type = types[0] let key = Object.keys(data)[0] switch (key) { case "Never": return new Condition.Never() case "Always": return new Condition.Always() case "And": return new Condition.And(parseObject(data.And, [Array, [Condition, type]])) case "Or": return new Condition.Or(parseObject(data.Or, [Array, [Condition, type]])) case "Not": return new Condition.Not(parseObject(data.Not, [Condition, type])) case "Equal": return new Condition.Equal(parseObject(data.Equal, type)) case "NotEqual": return new Condition.NotEqual(parseObject(data.NotEqual, type)) case "Inside": return new Condition.Inside(parseObject(data.Inside, [Array, type])) case "NotInside": return new Condition.NotInside(parseObject(data.NotInside, [Array, type])) case "GreaterThan": return new Condition.GreaterThan(parseObject(data.GreaterThan, type)) case "LessThan": return new Condition.LessThan(parseObject(data.LessThan, type)) case "GreaterThanOrEqual": return new Condition.GreaterThanOrEqual(parseObject(data.GreaterThanOrEqual, type)) case "LessThanOrEqual": return new Condition.LessThanOrEqual(parseObject(data.LessThanOrEqual, type)) case "StringContains": return parseObject(data.StringContains, [Condition.StringContains]) case "FullTextSearch": return parseObject(data.FullTextSearch, [Condition.FullTextSearch]) case "IntBitsClear": return new Condition.IntBitsClear(data.IntBitsClear as number) as unknown as Condition case "IntBitsSet": return new Condition.IntBitsSet(data.IntBitsSet as number) as unknown as Condition case "IntBitsAnyClear": return new Condition.IntBitsAnyClear(data.IntBitsAnyClear as number) as unknown as Condition case "IntBitsAnySet": return new Condition.IntBitsAnySet(data.IntBitsAnySet as number) as unknown as Condition case "ListAllElements": return new Condition.ListAllElements(parseObject(data.ListAllElements, [Condition, type[1]])) as unknown as Condition case "ListAnyElements": return new Condition.ListAnyElements(parseObject(data.ListAnyElements, [Condition, type[1]])) as unknown as Condition case "ListSizesEquals": return new Condition.ListSizesEquals(data.ListSizesEquals as number) as unknown as Condition case "SetAllElements": return new Condition.SetAllElements(parseObject(data.SetAllElements, [Condition, type[1]])) as unknown as Condition case "SetAnyElements": return new Condition.SetAnyElements(parseObject(data.SetAnyElements, [Condition, type[1]])) as unknown as Condition case "SetSizesEquals": return new Condition.SetSizesEquals(data.SetSizesEquals as number) as unknown as Condition case "Exists": return new Condition.Exists(data.Exists as string) as unknown as Condition case "OnKey": return parseObject(data.OnKey, [Condition.OnKey, type[2]]) case "IfNotNull": return new Condition.IfNotNull(parseObject(data.IfNotNull, [Condition, type])) default: const baseType = type[0] const propTypes = baseType.propertyTypes(type.slice(1)) const innerType = propTypes[key] return new Condition.OnField(key as TProperty1, parseObject(data[key], [Condition, innerType])) } } (Condition.Never as any).prototype.toJSON = function (this: Condition.Never): Record { return {Never: true} }; (Condition.Always as any).prototype.toJSON = function (this: Condition.Always): Record { return {Always: true} }; (Condition.And as any).prototype.toJSON = function (this: Condition.And): Record { return {And: this.conditions} }; (Condition.Or as any).prototype.toJSON = function (this: Condition.Or): Record { return {Or: this.conditions} }; (Condition.Not as any).prototype.toJSON = function (this: Condition.Not): Record { return {Not: this.condition} }; (Condition.Equal as any).prototype.toJSON = function (this: Condition.Equal): Record { return {Equal: this.value} }; (Condition.NotEqual as any).prototype.toJSON = function (this: Condition.NotEqual): Record { return {NotEqual: this.value} }; (Condition.Inside as any).prototype.toJSON = function (this: Condition.Inside): Record { return {Inside: this.values} }; (Condition.NotInside as any).prototype.toJSON = function (this: Condition.NotInside): Record { return {NotInside: this.values} }; (Condition.GreaterThan as any).prototype.toJSON = function (this: Condition.GreaterThan): Record { return {GreaterThan: this.value} }; (Condition.LessThan as any).prototype.toJSON = function (this: Condition.LessThan): Record { return {LessThan: this.value} }; (Condition.GreaterThanOrEqual as any).prototype.toJSON = function (this: Condition.GreaterThanOrEqual): Record { return {GreaterThanOrEqual: this.value} }; (Condition.LessThanOrEqual as any).prototype.toJSON = function (this: Condition.LessThanOrEqual): Record { return {LessThanOrEqual: this.value} }; (Condition.StringContains as any).prototype.toJSON = function (this: Condition.StringContains): Record { return {StringContains: {value: this.value, ignoreCase: this.ignoreCase}} }; (Condition.FullTextSearch as any).prototype.toJSON = function (this: Condition.FullTextSearch): Record { return {FullTextSearch: {value: this.value, ignoreCase: this.ignoreCase}} }; (Condition.IntBitsClear as any).prototype.toJSON = function (this: Condition.IntBitsClear): Record { return {IntBitsClear: this.mask} }; (Condition.IntBitsSet as any).prototype.toJSON = function (this: Condition.IntBitsSet): Record { return {IntBitsSet: this.mask} }; (Condition.IntBitsAnyClear as any).prototype.toJSON = function (this: Condition.IntBitsAnyClear): Record { return {IntBitsAnyClear: this.mask} }; (Condition.IntBitsAnySet as any).prototype.toJSON = function (this: Condition.IntBitsAnySet): Record { return {IntBitsAnySet: this.mask} }; (Condition.ListAllElements as any).prototype.toJSON = function (this: Condition.ListAllElements): Record { return {ListAllElements: this.condition} }; (Condition.ListAnyElements as any).prototype.toJSON = function (this: Condition.ListAnyElements): Record { return {ListAnyElements: this.condition} }; (Condition.ListSizesEquals as any).prototype.toJSON = function (this: Condition.ListSizesEquals): Record { return {ListSizesEquals: this.count} }; (Condition.SetAllElements as any).prototype.toJSON = function (this: Condition.SetAllElements): Record { return {SetAllElements: this.condition} }; (Condition.SetAnyElements as any).prototype.toJSON = function (this: Condition.SetAnyElements): Record { return {SetAnyElements: this.condition} }; (Condition.SetSizesEquals as any).prototype.toJSON = function (this: Condition.SetSizesEquals): Record { return {SetSizesEquals: this.count} }; (Condition.Exists as any).prototype.toJSON = function (this: Condition.Exists): Record { return {Exists: this.key} }; (Condition.OnKey as any).prototype.toJSON = function (this: Condition.OnKey): Record { return {OnKey: {key: this.key, condition: this.condition}} }; (Condition.IfNotNull as any).prototype.toJSON = function (this: Condition.IfNotNull): Record { return {IfNotNull: this.condition} }; (Condition.OnField as any).prototype.toJSON = function (this: Condition.OnField): Record { const result: Record = {} result[this.key] = this.condition return result }; (Modification as any).fromJSON = (data: Record, types: Array): Modification => { const type = types[0] let key = Object.keys(data)[0] switch (key) { case "Chain": return new Modification.Chain(parseObject(data.Chain, [Array, [Modification, type]])) case "IfNotNull": return new Modification.IfNotNull(parseObject(data.IfNotNull, [Modification, type])) as unknown as Modification case "Assign": return new Modification.Assign(parseObject(data.Assign, type)) case "CoerceAtMost": return new Modification.CoerceAtMost(parseObject(data.CoerceAtMost, type)) case "CoerceAtLeast": return new Modification.CoerceAtLeast(parseObject(data.CoerceAtLeast, type)) case "Increment": return new Modification.Increment(data.Increment as number) as unknown as Modification case "Multiply": return new Modification.Multiply(data.Multiply as number) as unknown as Modification case "AppendString": return new Modification.AppendString(data.AppendString as string) as unknown as Modification case "ListAppend": return new Modification.ListAppend(parseObject>(data.ListAppend, [Array, type[1]])) as unknown as Modification case "ListRemove": return new Modification.ListRemove(parseObject(data.ListRemove, [Condition, type[1]])) as unknown as Modification case "ListRemoveInstances": return new Modification.ListRemoveInstances(parseObject>(data.ListRemoveInstances, [Array, type[1]])) as unknown as Modification case "ListDropFirst": return new Modification.ListDropFirst() as unknown as Modification case "ListDropLast": return new Modification.ListDropLast() as unknown as Modification case "SetAppend": return new Modification.SetAppend(parseObject>(data.SetAppend, [Array, type[1]])) as unknown as Modification case "SetRemove": return new Modification.SetRemove(parseObject(data.SetRemove, [Condition, type[1]])) as unknown as Modification case "SetRemoveInstances": return new Modification.SetRemoveInstances(parseObject>(data.SetRemoveInstances, [Array, type[1]])) as unknown as Modification case "SetDropFirst": return new Modification.SetDropFirst() as unknown as Modification case "SetDropLast": return new Modification.SetDropLast() as unknown as Modification case "ListPerElement": return parseObject(data.PerElement, [Modification.ListPerElement, type[1]]) case "SetPerElement": return parseObject(data.PerElement, [Modification.SetPerElement, type[1]]) case "Combine": return new Modification.Combine(parseObject>(data.Combine, [Map, [String], type[2]])) as unknown as Modification case "ModifyByKey": return new Modification.ModifyByKey(parseObject>>(data.ModifyByKey, [Map, [String], [Modification, type[2]]])) as unknown as Modification case "RemoveKeys": return new Modification.RemoveKeys(parseObject>(data.RemoveKeys, [Set, [String]])) as unknown as Modification default: const baseType = type[0] const propTypes = baseType.propertyTypes(type.slice(1)) const innerType = propTypes[key] return new Modification.OnField(key as TProperty1, parseObject(data[key], [Modification, innerType])) } } (Modification.Chain as any).prototype.toJSON = function (this: Modification.Chain): Record { return {Chain: this.modifications} }; (Modification.IfNotNull as any).prototype.toJSON = function (this: Modification.IfNotNull): Record { return {IfNotNull: this.modification} }; (Modification.Assign as any).prototype.toJSON = function (this: Modification.Assign): Record { return {Assign: this.value} }; (Modification.CoerceAtMost as any).prototype.toJSON = function (this: Modification.CoerceAtMost): Record { return {CoerceAtMost: this.value} }; (Modification.CoerceAtLeast as any).prototype.toJSON = function (this: Modification.CoerceAtLeast): Record { return {CoerceAtLeast: this.value} }; (Modification.Increment as any).prototype.toJSON = function (this: Modification.Increment): Record { return {Increment: this.by} }; (Modification.Multiply as any).prototype.toJSON = function (this: Modification.Multiply): Record { return {Multiply: this.by} }; (Modification.AppendString as any).prototype.toJSON = function (this: Modification.AppendString): Record { return {AppendString: this.value} }; (Modification.ListAppend as any).prototype.toJSON = function (this: Modification.ListAppend): Record { return {ListAppend: this.items} }; (Modification.ListRemove as any).prototype.toJSON = function (this: Modification.ListRemove): Record { return {ListRemove: this.condition} }; (Modification.ListRemoveInstances as any).prototype.toJSON = function (this: Modification.ListRemoveInstances): Record { return {ListRemoveInstances: this.items} }; (Modification.ListDropFirst as any).prototype.toJSON = function (this: Modification.ListDropFirst): Record { return {ListDropFirst: true} }; (Modification.ListDropLast as any).prototype.toJSON = function (this: Modification.ListDropLast): Record { return {ListDropLast: true} }; (Modification.SetAppend as any).prototype.toJSON = function (this: Modification.SetAppend): Record { return {SetAppend: this.items} }; (Modification.SetRemove as any).prototype.toJSON = function (this: Modification.SetRemove): Record { return {SetRemove: this.condition} }; (Modification.SetRemoveInstances as any).prototype.toJSON = function (this: Modification.SetRemoveInstances): Record { return {SetRemoveInstances: this.items} }; (Modification.SetDropFirst as any).prototype.toJSON = function (this: Modification.SetDropFirst): Record { return {SetDropFirst: true} }; (Modification.SetDropLast as any).prototype.toJSON = function (this: Modification.SetDropLast): Record { return {SetDropLast: true} }; (Modification.Combine as any).prototype.toJSON = function (this: Modification.Combine): Record { return {Combine: this.map} }; (Modification.ModifyByKey as any).prototype.toJSON = function (this: Modification.ModifyByKey): Record { return {ModifyByKey: this.map} }; (Modification.RemoveKeys as any).prototype.toJSON = function (this: Modification.RemoveKeys): Record { return {RemoveKeys: this.fields} }; (Modification.OnField as any).prototype.toJSON = function (this: Modification.OnField): Record { const result: Record = {} result[this.key] = this.modification return result }; function stringToPath(str: String): DataClassPath { let current = new DataClassPathSelf() for(const part of str.split('.')) { if(part.endsWith('?')) { // @ts-ignore current = new DataClassPathNotNull(new DataClassPathAccess(current, part.substring(0, part.length-1))) } else { // @ts-ignore current = new DataClassPathAccess(current, part) } } return current } (SortPart as any).prototype.toJSON = function (this: SortPart): string { return this.ascending ? this.field.toString() : `-${this.field.toString()}` }; (SortPart as any).fromJSON = (value: string, types: Array): SortPart => { const descending = value.startsWith('-') const realName = descending ? value.substring(1) : value return new SortPart(stringToPath(realName), !descending) } (DataClassPath as any).prototype.toJSON = function (this: DataClassPath): string { return this.toString() }; (DataClassPath as any).fromJSON = (value: string, types: Array): DataClassPath => { return stringToPath(value) }