diff options
Diffstat (limited to 'src/new_fields')
| -rw-r--r-- | src/new_fields/Doc.ts | 4 | ||||
| -rw-r--r-- | src/new_fields/Schema.ts | 22 | ||||
| -rw-r--r-- | src/new_fields/Types.ts | 11 | ||||
| -rw-r--r-- | src/new_fields/URLField.ts | 9 |
4 files changed, 19 insertions, 27 deletions
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 10e8fe7ec..5d18cbb2e 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -33,7 +33,7 @@ export class ObjectField { export type Field = number | string | boolean | ObjectField | RefField; export type Opt<T> = T | undefined; export type FieldWaiting<T extends Field = Field> = Promise<T | undefined>; -export type FieldValue<T extends Field = Field> = Opt<T> | FieldWaiting<T>; +export type FieldResult<T extends Field = Field> = Opt<T> | FieldWaiting<T>; export const Self = Symbol("Self"); @@ -77,7 +77,7 @@ export namespace Doc { return Cast(field, ctor); }); } - export function Get(doc: Doc, key: string, ignoreProto: boolean = false): FieldValue { + export function Get(doc: Doc, key: string, ignoreProto: boolean = false): FieldResult { const self = doc[Self]; return getField(self, key, ignoreProto); } diff --git a/src/new_fields/Schema.ts b/src/new_fields/Schema.ts index 696a5d2a8..3b7078cb0 100644 --- a/src/new_fields/Schema.ts +++ b/src/new_fields/Schema.ts @@ -1,13 +1,7 @@ import { Interface, ToInterface, Cast, FieldCtor, ToConstructor, HasTail, Head, Tail } from "./Types"; import { Doc, Field, ObjectField } from "./Doc"; -import { URLField } from "./URLField"; -type All<T extends Interface[], U extends Doc> = { - 1: makeInterface<[Head<T>], U> & All<Tail<T>, U>, - 0: makeInterface<[Head<T>], U> -}[HasTail<T> extends true ? 1 : 0]; - -type AllToInterface<T extends any[]> = { +type AllToInterface<T extends Interface[]> = { 1: ToInterface<Head<T>> & AllToInterface<Tail<T>>, 0: ToInterface<Head<T>> }[HasTail<T> extends true ? 1 : 0]; @@ -16,7 +10,6 @@ export const emptySchema = createSchema({}); export const Document = makeInterface(emptySchema); export type Document = makeInterface<[typeof emptySchema]>; -const DocSymbol = Symbol("Doc"); export type makeInterface<T extends Interface[], U extends Doc = Doc> = Partial<AllToInterface<T>> & U; // export function makeInterface<T extends Interface[], U extends Doc>(schemas: T): (doc: U) => All<T, U>; // export function makeInterface<T extends Interface, U extends Doc>(schema: T): (doc: U) => makeInterface<T, U>; @@ -29,26 +22,19 @@ export function makeInterface<T extends Interface[], U extends Doc>(...schemas: } const proto = new Proxy({}, { get(target: any, prop) { - if (prop === DocSymbol) { - return target[prop]; - } - const field = target[DocSymbol][prop]; + const field = target.doc[prop]; if (prop in schema) { return Cast(field, (schema as any)[prop]); } return field; }, set(target: any, prop, value) { - if (prop === DocSymbol) { - target[prop] = value; - } - target[DocSymbol][prop] = value; + target.doc[prop] = value; return true; } }); return function (doc: any) { - const obj = Object.create(proto); - obj.__doc = doc; + const obj = Object.create(proto, { doc: { value: doc, writable: false } }); return obj; }; } diff --git a/src/new_fields/Types.ts b/src/new_fields/Types.ts index e4d15e276..f4f66fe5c 100644 --- a/src/new_fields/Types.ts +++ b/src/new_fields/Types.ts @@ -1,4 +1,4 @@ -import { Field, Opt, FieldWaiting, FieldValue } from "./Doc"; +import { Field, Opt, FieldWaiting, FieldResult } from "./Doc"; import { List } from "./List"; export type ToType<T> = @@ -6,7 +6,8 @@ export type ToType<T> = T extends "number" ? number : T extends "boolean" ? boolean : T extends ListSpec<infer U> ? List<U> : - T extends { new(...args: any[]): infer R } ? (R | Promise<R>) : never; + // T extends { new(...args: any[]): infer R } ? (R | Promise<R>) : never; + T extends { new(...args: any[]): infer R } ? R : never; export type ToConstructor<T> = T extends string ? "string" : @@ -35,9 +36,9 @@ export interface Interface { export type FieldCtor<T extends Field> = T extends List<infer R> ? ListSpec<R> : ToConstructor<T>; -export function Cast<T extends FieldCtor<Field>>(field: Field | FieldWaiting | undefined, ctor: T): FieldValue<ToType<T>>; +export function Cast<T extends FieldCtor<Field>>(field: Field | FieldWaiting | undefined, ctor: T): FieldResult<ToType<T>>; export function Cast<T extends FieldCtor<Field>>(field: Field | FieldWaiting | undefined, ctor: T, defaultVal: ToType<T>): ToType<T>; -export function Cast<T extends FieldCtor<Field>>(field: Field | FieldWaiting | undefined, ctor: T, defaultVal?: ToType<T>): FieldValue<ToType<T>> | undefined { +export function Cast<T extends FieldCtor<Field>>(field: Field | FieldWaiting | undefined, ctor: T, defaultVal?: ToType<T>): FieldResult<ToType<T>> | undefined { if (field instanceof Promise) { return defaultVal === undefined ? field.then(f => Cast(f, ctor) as any) : defaultVal; } @@ -66,6 +67,6 @@ export function FieldValue<T extends Field>(field: Opt<T> | Promise<Opt<T>>, def export interface PromiseLike<T> { then(callback: (field: Opt<T> | PromiseLike<T>) => void): void; } -export function PromiseValue<T extends Field>(field: FieldValue<T>): PromiseLike<Opt<T>> { +export function PromiseValue<T extends Field>(field: FieldResult<T>): PromiseLike<Opt<T>> { return field instanceof Promise ? field : { then(cb: ((field: Opt<T>) => void)) { return cb(field); } }; }
\ No newline at end of file diff --git a/src/new_fields/URLField.ts b/src/new_fields/URLField.ts index e456a7d16..1da245e73 100644 --- a/src/new_fields/URLField.ts +++ b/src/new_fields/URLField.ts @@ -13,7 +13,6 @@ function url() { ); } -@Deserializable("url") export class URLField extends ObjectField { @serializable(url()) readonly url: URL; @@ -22,4 +21,10 @@ export class URLField extends ObjectField { super(); this.url = url; } -}
\ No newline at end of file +} + +@Deserializable("audio") export class AudioField extends URLField { } +@Deserializable("image") export class ImageField extends URLField { } +@Deserializable("video") export class VideoField extends URLField { } +@Deserializable("pdf") export class PdfField extends URLField { } +@Deserializable("web") export class WebField extends URLField { }
\ No newline at end of file |
