import { Model } from "../model"; import { ensureValue } from "../utils"; export type AnyField = BaseField; export interface SerialMeta { model: Model; networkObject: object; field: BaseField; SKIP: object; } // @ts-ignore Symbol.metadata ??= Symbol("Symbol.metadata"); export const FieldsSym = Symbol('fields'); export function addField(modelMeta, k: string, field: BaseField) { if (!Object.hasOwn.call(modelMeta, FieldsSym)) { const ival = (modelMeta[FieldsSym] ?? {}) as any; // const nval = {}; // Object.setPrototypeOf(nval, ival); const nval = { ...ival }; modelMeta[FieldsSym] = nval; } modelMeta[FieldsSym][k] = field; } export abstract class BaseField> { constructor(ctx: ClassMemberDecoratorContext, options?: O) { addField(ctx.metadata, ctx.name as string, this); this.propertyName = ctx.name as string; const fld = this; ctx.addInitializer(function (this: S) { if (this['_initial_data']) { fld.deserialize(this, this['_initial_data'], { field: fld, model: this, networkObject: this['_initial_data'], SKIP: {}, }) } }); this.options = Object.assign({ }, options); } readonly options: O; // readonly model: typeof Model; readonly propertyName: string; get serializedName() { return this.options['serial_name'] || this.propertyName; } getInstanceMeta(instance: S) { const instMeta = instance._meta; const fieldInstMeta = ensureValue(instMeta, 'fieldData', {}); return ensureValue(fieldInstMeta, this.propertyName, {} as any); } initializeInstance(inst: S) { } abstract decorate(target: any, context: DecoratorContext); abstract serialize(inst: S, object, meta: SerialMeta); abstract deserialize(inst: S, object, meta: SerialMeta); }