diff options
Diffstat (limited to 'src/fields/Schema.ts')
-rw-r--r-- | src/fields/Schema.ts | 78 |
1 files changed, 41 insertions, 37 deletions
diff --git a/src/fields/Schema.ts b/src/fields/Schema.ts index 7ad376a28..f035eeb0d 100644 --- a/src/fields/Schema.ts +++ b/src/fields/Schema.ts @@ -1,13 +1,13 @@ -import { Interface, ToInterface, Cast, ToConstructor, HasTail, Head, Tail, ListSpec, ToType, DefaultFieldConstructor } from "./Types"; -import { Doc, Field } from "./Doc"; -import { ObjectField } from "./ObjectField"; -import { RefField } from "./RefField"; -import { SelfProxy } from "./FieldSymbols"; -import { List } from "./List"; +import { Interface, ToInterface, Cast, ToConstructor, HasTail, Head, Tail, ListSpec, ToType, DefaultFieldConstructor } from './Types'; +import { Doc, Field } from './Doc'; +import { ObjectField } from './ObjectField'; +import { RefField } from './RefField'; +import { SelfProxy } from './DocSymbols'; +import { List } from './List'; type AllToInterface<T extends Interface[]> = { - 1: ToInterface<Head<T>> & AllToInterface<Tail<T>>, - 0: ToInterface<Head<T>> + 1: ToInterface<Head<T>> & AllToInterface<Tail<T>>; + 0: ToInterface<Head<T>>; }[HasTail<T> extends true ? 1 : 0]; export const emptySchema = createSchema({}); @@ -28,36 +28,40 @@ export function makeInterface<T extends Interface[]>(...schemas: T): InterfaceFu schema[key] = s[key]; } } - const proto = new Proxy({}, { - get(target: any, prop, receiver) { - const field = receiver.doc?.[prop]; - if (prop in schema) { - const desc = prop === "proto" ? Doc : (schema as any)[prop]; // bcz: proto doesn't appear in schemas ... maybe it should? - if (typeof desc === "object" && "defaultVal" in desc && "type" in desc) {//defaultSpec - return Cast(field, desc.type, desc.defaultVal); - } - if (typeof desc === "function" && !ObjectField.isPrototypeOf(desc) && !RefField.isPrototypeOf(desc)) { - const doc = Cast(field, Doc); - if (doc === undefined) { - return undefined; + const proto = new Proxy( + {}, + { + get(target: any, prop, receiver) { + const field = receiver.doc?.[prop]; + if (prop in schema) { + const desc = prop === 'proto' ? Doc : (schema as any)[prop]; // bcz: proto doesn't appear in schemas ... maybe it should? + if (typeof desc === 'object' && 'defaultVal' in desc && 'type' in desc) { + //defaultSpec + return Cast(field, desc.type, desc.defaultVal); } - if (doc instanceof Doc) { - return desc(doc); + if (typeof desc === 'function' && !ObjectField.isPrototypeOf(desc) && !RefField.isPrototypeOf(desc)) { + const doc = Cast(field, Doc); + if (doc === undefined) { + return undefined; + } + if (doc instanceof Doc) { + return desc(doc); + } + return doc.then(doc => doc && desc(doc)); } - return doc.then(doc => doc && desc(doc)); + return Cast(field, desc); } - return Cast(field, desc); - } - return field; - }, - set(target: any, prop, value, receiver) { - receiver.doc && (receiver.doc[prop] = value); // receiver.doc may be undefined as the result of a change in acls - return true; + return field; + }, + set(target: any, prop, value, receiver) { + receiver.doc && (receiver.doc[prop] = value); // receiver.doc may be undefined as the result of a change in acls + return true; + }, } - }); + ); // !(doc instanceof Doc) && (throw new Error("Currently wrapping a schema in another schema isn't supported")); const fn = (doc: Doc) => Object.create(proto, { doc: { value: doc[SelfProxy], writable: false } }); - return ((doc?: Doc | Doc[]) => (doc instanceof List ? doc : undefined)?.map?.(fn) ?? fn((doc as Doc) ?? new Doc)) as InterfaceFunc<T>; + return ((doc?: Doc | Doc[]) => (doc instanceof List ? doc : undefined)?.map?.(fn) ?? fn((doc as Doc) ?? new Doc())) as InterfaceFunc<T>; } export type makeStrictInterface<T extends Interface> = Partial<ToInterface<T>>; @@ -75,8 +79,8 @@ export function makeStrictInterface<T extends Interface>(schema: T): (doc: Doc) this.__doc[key] = value; return; } - throw new TypeError("Expected type " + type); - } + throw new TypeError('Expected type ' + type); + }, }); } return function (doc: any) { @@ -95,12 +99,12 @@ export function createSchema<T extends Interface>(schema: T): T & { proto: ToCon } export function listSpec<U extends ToConstructor<Field>>(type: U): ListSpec<ToType<U>> { - return { List: type as any };//TODO Types + return { List: type as any }; //TODO Types } export function defaultSpec<T extends ToConstructor<Field>>(type: T, defaultVal: ToType<T>): DefaultFieldConstructor<ToType<T>> { return { type: type as any, - defaultVal + defaultVal, }; -}
\ No newline at end of file +} |