export type Primitive = string|number|boolean|string[]|number[]; export interface IKeypath { readonly keys: string[]; readonly path: string; readonly pointer: string; // JsonPointer syntax } export interface Predicate { (x:T):boolean; } export interface Comparison { (x:T, y:T):boolean; } export interface IModelObject { [key:string]:T; } export interface IClientProps { propExists(key:string):boolean; propGet(key:string):any; propSet(key:string, val:any):void; propKeys():string[]; propsCopyFrom(that: IClientProps):void; } export interface IMessageProps { [key:string]:number|string|any; } export enum MessageSeverity { NOTE, SUCCESS, WARNING, ERROR } export interface IStatusMessage { msg:string; code:string; qualifiers?: string[]; props?:IMessageProps; severity: MessageSeverity; } export interface IPropertyStatusMessage extends IStatusMessage { property:string; } export interface IModelParseContext { validate(): boolean parse(): any; currentValue():any; currentRequired():boolean; currentKeyPath():string[]; currentType():IModelType; pushItem(key:string|number, required:boolean, type:IModelType):void; popItem():void; subContext(): IModelParseContext; addWarning(msg:string, code:string):void; addError(msg:string, code:string):void; addErrorEx(msg:string, code:string, props: IMessageProps):void; addWarningEx(msg:string, code:string, props: IMessageProps):void; addMessage(isError:boolean, msg:string, code:string):void; addMessage(severity:MessageSeverity, msg:string, code:string):void; addMessageEx(isError:boolean, msg:string, code:string, props: IMessageProps):void; addMessageEx(severity:MessageSeverity, msg:string, code:string, props: IMessageProps):void; addMessages(msgs:IPropertyStatusMessage[]): void; _removeMessages(filter:(m:IPropertyStatusMessage)=>boolean):void; hasMessagesForCurrentValue():boolean; messages:IPropertyStatusMessage[]; warnings:IPropertyStatusMessage[]; errors: IPropertyStatusMessage[]; readonly allowConversion:boolean; } export interface IModelType extends IClientProps { name:string; kind:string; qualifiers:string[]; parse(ctx:IModelParseContext):T; validate(ctx:IModelParseContext):void; unparse(val:T):any; create():T; createEmpty():T; asItemType(): IModelTypeItem | undefined; asCompositeType(): IModelTypeComposite | undefined; } export interface IModelTypeConstrainable extends IModelType { withConstraints(...c:IModelTypeConstraint[]):this; withNameAndConstraints(name: string, ...c:IModelTypeConstraint[]):this; findConstraints(p:Predicate>):IModelTypeConstraint[]; } export interface IModelTypeConstraint { id:string; checkAndAdjustValue(val:T, ctx:IModelParseContext):T; usedItems?():string[]; appliesTo?(kind:string):boolean; possibleValuesForContextData?(name:string|number, data:T):any[]; slice?(fields: string[]|number[]): IModelTypeConstraint; } export interface IModelTypeConstraintFactory { [kind:string]:(options:any) => IModelTypeConstraint; } export interface IModelTypeItem extends IModelTypeConstrainable { fromString(valStr:string):T; asString(val:T):string; lowerBound():IModelTypeConstraint; upperBound():IModelTypeConstraint; possibleValues():T[]; // null -> no list of allowed values, no values possible -> empty array } export interface IModelTypeEntry { key:string; type:IModelType; required:boolean; } export interface IModelTypeComposite extends IModelTypeConstrainable { items:IModelTypeEntry[]; findItem(name: string | number): IModelTypeEntry; itemType(name:string|number):IModelType; slice(name:string[]|number[]):IModelTypeComposite; /** * return: null -> no list of allowed values, * empty array -> no values possible */ possibleValuesForContextData(name:string|number, data:any):any[]; } export interface IModelTypeCompositeBuilder extends IModelTypeComposite { extend(type:IModelTypeComposite):IModelTypeCompositeBuilder; addItem(key:string, type:IModelType, required?:boolean):IModelTypeCompositeBuilder; findItem(key: string): IModelTypeEntry; withReplacedItems(newItems: { [key: string]: IModelType|undefined; }): IModelTypeComposite; addConstraint(c:IModelTypeConstraint):IModelTypeCompositeBuilder; } export interface IModelTypeRegistry { type(name:string) : IModelType; itemType(name:string) : IModelTypeItem; addType(type:IModelType): void; getRegisteredNames():string[]; }