Commit 0cb2dd23 authored by nanahira's avatar nanahira

finish backref

parent 08f16b10
......@@ -37,11 +37,10 @@ export function SchemaProperty(options: SchemaOptions = {}): PropertyDecorator {
) {
options.array = true;
}
if (
options.type &&
typeof options.type !== 'string' &&
(options.type as Schema<any>)[kSchema]
((options.type as Schema<any>)[kSchema] || options.type[RefSym])
) {
const cl = options.type as ClassType<any>;
let dec: PropertyDecorator;
......
import {
ClassType,
GeneratedSym,
IndexSym,
RefSym,
SchemaClassOptions,
SchemaOptions,
......@@ -16,10 +15,7 @@ import _ from 'lodash';
import { Metadata } from '../metadata/metadata';
import { kSchema } from '../utility/kschema';
let index = 0;
const refMap = new Map<number, Schema<any>>();
function resolveSchemaType(schemaType: SchemaType): SchemaOrReference {
export function resolveSchemaType(schemaType: SchemaType): SchemaOrReference {
if (schemaType && schemaType[RefSym]) {
return schemaType as SchemaReference;
}
......@@ -76,13 +72,12 @@ function getPropertySchemaFromOptions<PT>(
function resolveSchemaReference<S = any, T = S>(ref: SchemaReference<S, T>) {
const value = ref.factory();
console.log(value);
if (value[IndexSym]) {
return refMap.get(value[IndexSym]);
/*if (value[kSchema]) {
return value;
}
if (typeof value === 'function' && !value[kSchema]) {
return SchemaClass(value as { new (...args: any[]): any });
}
}*/
return value;
}
......@@ -121,24 +116,19 @@ function schemasFromDict<T>(dict: SchemaOptionsDict<T>) {
SchemaOptionsDict<T>[P]
>;
} = _.mapValues(dict, (opt) => getPropertySchemaFromOptions(opt));
const schema = Schema.object({});
for (const _key of Object.keys(schemaDict)) {
const key = _key as keyof T;
if (schemaDict[key][RefSym]) {
const schemaOptions = dict[key];
/*schemaDict[key] = resolvePropertySchemaFromOptions({
...schemaOptions,
type: resolveSchemaReference(schemaDict[key] as SchemaReference),
});*/
tempDefGet(schemaDict, key, () =>
resolvePropertySchemaFromOptions({
...schemaOptions,
type: resolveSchemaReference(schemaDict[key] as SchemaReference),
}),
tempDefGet(schema.dict, _key, () =>
resolvePropertySchemaFromOptions(schemaOptions),
);
} else {
schema.set(_key, schemaDict[_key]);
}
}
return Schema.object(schemaDict);
return schema;
}
function schemaOptionsFromClass<T>(cl: ClassType<T>): SchemaOptionsDict<T> {
......@@ -266,11 +256,6 @@ export function SchemaClass<T>(originalClass: ClassType<T>) {
export function RegisterSchema(options: SchemaClassOptions = {}) {
return function <T>(originalClass: ClassType<T>): any {
Metadata.set('SchemaClassOptions', options)(originalClass);
const newClass = SchemaClass(originalClass);
const currentIndex = index++;
refMap.set(currentIndex, newClass);
originalClass[IndexSym] = currentIndex;
newClass[IndexSym] = currentIndex;
return newClass;
return SchemaClass(originalClass);
};
}
......@@ -47,4 +47,3 @@ export type SchemaOptionsDict<T> = { [P in keyof T]?: SchemaOptions };
export const RefSym = Symbol('SchemasteryGenRef');
export const GeneratedSym = Symbol('GeneratedSym');
export const IndexSym = Symbol('IndexSym');
import { Metadata } from '../metadata/metadata';
import { ClassType } from '../def';
import { ClassType, RefSym, SchemaOrReference, SchemaReference } from '../def';
import Schema from 'schemastery';
import _ from 'lodash';
import { kSchema } from './kschema';
import { resolveSchemaType } from '../decorators';
export function SetTransformer(transformer: (val: any) => any) {
return Metadata.set('Transformer', transformer);
}
export function transformSingle<T>(
cl: ClassType<T> & Partial<Schema>,
cl: SchemaOrReference<T> | ClassType<T>,
val: any,
) {
if (cl[kSchema]) {
return new cl(val);
if (cl[RefSym]) {
const ref = cl as SchemaReference<T>;
return transformSingle(resolveSchemaType(ref.factory()), val);
} else if (cl[kSchema]) {
const schema = cl as Schema<T>;
return new schema(val);
} else {
return val;
}
}
export function transformArray<T>(cl: ClassType<T>, val: any[]) {
export function transformArray<T>(
cl: SchemaOrReference<T> | ClassType<T>,
val: any[],
) {
if (!val) {
return;
}
......@@ -27,7 +35,11 @@ export function transformArray<T>(cl: ClassType<T>, val: any[]) {
return result;
}
export function transformDict<T>(cl: ClassType<T>, val: any, array: boolean) {
export function transformDict<T>(
cl: SchemaOrReference<T> | ClassType<T>,
val: any,
array: boolean,
) {
if (!val) {
return;
}
......
......@@ -34,6 +34,11 @@ class Post {
type: SchemaRef(() => Author),
})
author?: Author;
@DefineSchema({
type: SchemaRef(() => Post),
})
childPosts?: Post[];
}
describe('Recurse schema', () => {
......@@ -47,7 +52,8 @@ describe('Recurse schema', () => {
});
it('child of child should be Schema', () => {
const authorSchema = (Post as Schema<Post>).dict.author.inner.dict.posts;
const authorSchema = (Post as Schema<Post>).dict.childPosts.inner.dict
.author;
expect(authorSchema[kSchema]).toBeDefined();
});
......@@ -64,8 +70,11 @@ describe('Recurse schema', () => {
author: {
name: 'Shigma',
},
childPosts: [{ name: 'child' }],
});
expect(post.author.getName()).toBe('Shigma');
expect(post.childPosts[0].getName()).toBe('child');
});
it('should recurse twice', () => {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment