import { IModelType, IModelTypeItem, IModelTypeCompositeBuilder, IModelTypeRegistry } from "./model.api" import { ModelParseContext } from "./model.infra" import { ModelTypeArray } from "./model.array" import { ModelTypeObject } from "./model.object" export class ModelTypeRegistry implements IModelTypeRegistry { asItemType(type:IModelType) { let result = >type; if (!result.withConstraints) { result = null; } return result; } removeType(name:string) { if (this._types.hasOwnProperty(name)) { delete this._types[name]; delete this._itemTypes[name]; } } addType(type:IModelType):IModelType { let name = type.name; let oldType = this._types[name]; if (oldType && oldType != type) { console.warn(`redefining type ${name}`, type, JSON.stringify(type, null, 2)); } this._types[name] = type; let itemType = this.asItemType(type); if (itemType) { this._itemTypes[name] = itemType; } return type; } addObjectType(name:string, construct?:()=>C):IModelTypeCompositeBuilder { let result = new ModelTypeObject(name, construct); this.addType(result); return result; } addArrayType(type:IModelType) { let result = new ModelTypeArray(type); this.addType(result); return result; } type(name:string) : IModelType { return this._types[name]; } itemType(name:string) : IModelTypeItem { return this._itemTypes[name]; } getRegisteredNames() { return Object.keys(this._types); } createParseContext(obj:any, type:IModelType, required?:boolean, allowConversion?:boolean) { return new ModelParseContext(obj, type, required, allowConversion); } private _types:{ [name:string]: IModelType; } = {}; private _itemTypes:{ [name:string]: IModelTypeItem; } = {}; }