import { optional_config_decorator } from "@matchlighter/common_library/decorators/utils"; import { Model } from "../model"; import { BaseField, SerialMeta } from "./base"; import { injectObservability, Observability } from "../mobx_internal"; import { collection } from "./collection"; import { reference, reference_id } from "./reference"; export interface FieldOptions { serial_name?: string; // removable: boolean; observable?: Observability; serialize?: boolean | ((netValue, meta: SerialMeta) => any); deserialize?: boolean | ((value, meta: SerialMeta) => any); } export class Field, R extends Model> extends BaseField<{}, FieldOptions, S> { constructor(ctx: ClassMemberDecoratorContext, options?: FieldOptions) { super(ctx, Object.assign({ serialize: true, deserialize: true, serial_name: ctx.name as string, } as FieldOptions, options)); } decorate(value: any, context: ClassMemberDecoratorContext) { return injectObservability(this.options.observable)(value, context); } serialize(inst: S, object: any, meta: SerialMeta) { const f = this.options.serialize; if (f) { let v = inst[this.propertyName]; if (typeof f == 'function') v = f(v, meta); if (v !== meta.SKIP) object[this.serializedName] = v; } } deserialize(inst: S, object: any, meta: SerialMeta) { const f = this.options.deserialize; if (f) { let v = object[this.serializedName]; if (typeof f == 'function') v = f(v, meta); if (v !== meta.SKIP) inst[this.propertyName] = v; } } } export const field_ = optional_config_decorator([null], (config: FieldOptions & { key?: string }) => (value: any, ctx: ClassAccessorDecoratorContext | ClassFieldDecoratorContext) => { const field = new Field(ctx, config); return field.decorate(value, ctx); }) export const field: typeof field_ & { reference: typeof reference, ref: typeof reference, collection: typeof collection, reference_id: typeof reference_id, } = field_ as any; field.reference = field.ref = reference; field.collection = collection; field.reference_id = reference_id;