Commit 08f16b10 authored by nanahira's avatar nanahira

still problems

parent 59081a2a
import {
ClassType,
GeneratedSym,
IndexSym,
RefSym,
SchemaClassOptions,
SchemaOptions,
......@@ -14,6 +16,9 @@ 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 {
if (schemaType && schemaType[RefSym]) {
return schemaType as SchemaReference;
......@@ -71,6 +76,10 @@ 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 (typeof value === 'function' && !value[kSchema]) {
return SchemaClass(value as { new (...args: any[]): any });
}
......@@ -116,6 +125,11 @@ function schemasFromDict<T>(dict: SchemaOptionsDict<T>) {
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,
......@@ -193,7 +207,7 @@ function applySchemaForClass<T>(
instance: T,
originalObject: Partial<T>,
) {
const schema = schemaFromClass(originalClass);
const schema = originalClass[GeneratedSym] as Schema<Partial<T>, T>;
const newRawObject = new schema(originalObject);
for (const key in schema.dict) {
const transformer = reflector.get('Transformer', originalClass, key);
......@@ -214,6 +228,7 @@ function applySchemaForClass<T>(
export function SchemaClass<T>(originalClass: ClassType<T>) {
const schema = schemaFromClass(originalClass);
originalClass[GeneratedSym] = schema;
const newClass = function (...args: any[]): T {
const instance = new originalClass(...args);
const originalObject = args[0];
......@@ -251,6 +266,11 @@ export function SchemaClass<T>(originalClass: ClassType<T>) {
export function RegisterSchema(options: SchemaClassOptions = {}) {
return function <T>(originalClass: ClassType<T>): any {
Metadata.set('SchemaClassOptions', options)(originalClass);
return SchemaClass(originalClass);
const newClass = SchemaClass(originalClass);
const currentIndex = index++;
refMap.set(currentIndex, newClass);
originalClass[IndexSym] = currentIndex;
newClass[IndexSym] = currentIndex;
return newClass;
};
}
......@@ -21,8 +21,6 @@ export type SchemaSource<S = any, T = S> =
| Function
| { new (...args: any[]): any };
export const RefSym = Symbol('SchemasteryGenRef');
export interface SchemaReference<S = any, T = S> {
[RefSym]: true;
factory: () => SchemaType<S, T>;
......@@ -46,3 +44,7 @@ export interface SchemaOptions extends SchemaClassOptions {
}
export type SchemaOptionsDict<T> = { [P in keyof T]?: SchemaOptions };
export const RefSym = Symbol('SchemasteryGenRef');
export const GeneratedSym = Symbol('GeneratedSym');
export const IndexSym = Symbol('IndexSym');
......@@ -2,6 +2,23 @@ import { DefineSchema, RegisterSchema, SchemaRef } from '../src/decorators';
import { kSchema } from '../src/utility/kschema';
import Schema from 'schemastery';
@RegisterSchema()
class Author {
constructor(_: Partial<Author>) {}
@DefineSchema()
name: string;
getName?() {
return this.name;
}
@DefineSchema({
type: SchemaRef(() => Post),
})
posts?: Post[];
}
@RegisterSchema()
class Post {
constructor(_: Partial<Post>) {}
......@@ -14,9 +31,9 @@ class Post {
}
@DefineSchema({
type: SchemaRef(() => Post),
type: SchemaRef(() => Author),
})
child?: Post;
author?: Author;
}
describe('Recurse schema', () => {
......@@ -25,15 +42,13 @@ describe('Recurse schema', () => {
});
it('child should be Schema', () => {
const childPost = (Post as Schema<Post>).dict.child;
expect(childPost[kSchema]).toBeDefined();
expect(childPost === Post);
const authorSchema = (Post as Schema<Author>).dict.author;
expect(authorSchema[kSchema]).toBeDefined();
});
it('child of child should be Schema', () => {
const childPost = (Post as Schema<Post>).dict.child.dict.child;
expect(childPost[kSchema]).toBeDefined();
expect(childPost === Post);
const authorSchema = (Post as Schema<Post>).dict.author.inner.dict.posts;
expect(authorSchema[kSchema]).toBeDefined();
});
it('should resolve value', () => {
......@@ -46,26 +61,24 @@ describe('Recurse schema', () => {
it('should be able to recurse', () => {
const post = new Post({
name: 'test',
child: {
name: 'test',
author: {
name: 'Shigma',
},
});
expect(post.child.getName()).toBe('test');
expect(post.author.getName()).toBe('Shigma');
});
it('should recurse twice', () => {
const post = new Post({
name: 'test',
child: {
name: 'test',
child: {
name: 'test',
},
author: {
name: 'Shigma',
posts: [{ name: 'test' }, { name: 'test1' }],
},
});
expect(post.getName()).toBe('test');
expect(post.child.getName()).toBe('test');
expect(post.child.child.getName()).toBe('test');
expect(post.author.getName()).toBe('Shigma');
expect(post.author.posts[1].getName()).toBe('test1');
});
});
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