Commit 08f16b10 authored by nanahira's avatar nanahira

still problems

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