Commit eb5b260e authored by nanahira's avatar nanahira

fix toJSON

parent cc65206b
...@@ -44,7 +44,12 @@ export function resolveSchemaType(schemaType: SchemaType): SchemaOrReference { ...@@ -44,7 +44,12 @@ export function resolveSchemaType(schemaType: SchemaType): SchemaOrReference {
} }
function applyOptionsToSchema(schema: Schema, options: SchemaClassOptions) { function applyOptionsToSchema(schema: Schema, options: SchemaClassOptions) {
Object.assign(schema.meta, options); Object.assign(schema.meta, {
...options,
type: undefined,
dict: undefined,
array: undefined,
});
} }
function getPropertySchemaFromOptions<PT>( function getPropertySchemaFromOptions<PT>(
...@@ -177,7 +182,7 @@ const schemaFields: (keyof Schema)[] = [ ...@@ -177,7 +182,7 @@ const schemaFields: (keyof Schema)[] = [
]; ];
const schemaFunctions: (keyof Schema)[] = [ const schemaFunctions: (keyof Schema)[] = [
'toJSON', // 'toJSON',
'required', 'required',
'hidden', 'hidden',
'role', 'role',
...@@ -193,11 +198,11 @@ const schemaFunctions: (keyof Schema)[] = [ ...@@ -193,11 +198,11 @@ const schemaFunctions: (keyof Schema)[] = [
]; ];
function applySchemaForClass<T>( function applySchemaForClass<T>(
schema: Schema<Partial<T>, T>,
originalClass: ClassType<T>, originalClass: ClassType<T>,
instance: T, instance: T,
originalObject: Partial<T>, originalObject: Partial<T>,
) { ) {
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);
...@@ -218,12 +223,12 @@ function applySchemaForClass<T>( ...@@ -218,12 +223,12 @@ 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];
return applySchemaForClass(originalClass, instance, originalObject); return applySchemaForClass(schema, originalClass, instance, originalObject);
} as unknown as ClassType<T> & Schema<Partial<T>, T>; } as unknown as ClassType<T> & Schema<Partial<T>, T>;
newClass[GeneratedSym] = schema;
Object.defineProperty(newClass, 'name', { Object.defineProperty(newClass, 'name', {
value: originalClass.name, value: originalClass.name,
}); });
...@@ -232,8 +237,12 @@ export function SchemaClass<T>(originalClass: ClassType<T>) { ...@@ -232,8 +237,12 @@ export function SchemaClass<T>(originalClass: ClassType<T>) {
Object.defineProperty(newClass, field, { Object.defineProperty(newClass, field, {
configurable: true, configurable: true,
enumerable: true, enumerable: true,
writable: true, get() {
value: schema[field], return newClass[GeneratedSym][field];
},
set(value) {
newClass[GeneratedSym][field] = value;
},
}); });
} }
for (const functionField of schemaFunctions) { for (const functionField of schemaFunctions) {
...@@ -244,10 +253,18 @@ export function SchemaClass<T>(originalClass: ClassType<T>) { ...@@ -244,10 +253,18 @@ export function SchemaClass<T>(originalClass: ClassType<T>) {
configurable: true, configurable: true,
enumerable: false, enumerable: false,
writable: false, writable: false,
value: Schema.prototype[functionField], value: Schema.prototype[functionField].bind(newClass),
}); });
} }
Object.defineProperty(newClass, 'toJSON', {
configurable: true,
enumerable: false,
writable: false,
value: () =>
Schema.prototype.toJSON.call({ ...newClass, toJSON: undefined }),
});
newClass.toString = schema.toString.bind(schema); newClass.toString = schema.toString.bind(schema);
newClass[kSchema] = true; newClass[kSchema] = true;
return newClass; return newClass;
......
...@@ -18,11 +18,23 @@ describe('Circular schema', () => { ...@@ -18,11 +18,23 @@ describe('Circular schema', () => {
@SchemaProperty({ type: MyProperty }) @SchemaProperty({ type: MyProperty })
myProperty: MyProperty; myProperty: MyProperty;
} }
const schema = MyConfig as Schema<MyConfig>;
it('Should be object type', () => { function checkSchema(schema: Schema) {
const schema = MyConfig as Schema<MyConfig>; expect(schema.dict.myProperty.dict.foo.meta.default).toBe('bar');
expect(schema.type).toBe('object'); expect(schema.type).toBe('object');
expect(schema.dict.myProperty.type).toBe('object'); expect(schema.dict.myProperty.type).toBe('object');
}
it('Should be object type', () => {
checkSchema(schema);
});
it('should serialize', () => {
const data = schema.toJSON();
console.log(JSON.stringify(data, null, 2));
const restoredSchema = new Schema(data);
checkSchema(restoredSchema);
}); });
it('Should be instance', () => { it('Should be instance', () => {
......
...@@ -41,9 +41,24 @@ class Post { ...@@ -41,9 +41,24 @@ class Post {
childPosts?: Post[]; childPosts?: Post[];
} }
function checkSchema(schema: Schema) {
expect(schema[kSchema]).toBeDefined();
expect(schema.dict.name.type).toBe('string');
expect(schema.dict.childPosts.inner.dict.name.type).toBe('string');
const authorSchema = schema.dict.author;
expect(authorSchema.dict.name.type).toBe('string');
}
describe('Recurse schema', () => { describe('Recurse schema', () => {
it('should be a Schema', () => { it('should be a Schema', () => {
expect(Post[kSchema]).toBeDefined(); checkSchema(Post as Schema);
});
it('should serialize', () => {
const data = (Post as Schema).toJSON();
console.log(JSON.stringify(data, null, 2));
const rebuiltSchema = new Schema(data);
checkSchema(rebuiltSchema);
}); });
it('child should be Schema', () => { it('child should be Schema', () => {
......
...@@ -31,7 +31,9 @@ describe('Schema registration', () => { ...@@ -31,7 +31,9 @@ describe('Schema registration', () => {
it('should be serializable', () => { it('should be serializable', () => {
const schema = Config as Schema<Config>; const schema = Config as Schema<Config>;
const plainObject = new Schema(schema.toJSON()); const data = schema.toJSON();
console.log(JSON.stringify(data, null, 2));
const plainObject = new Schema(data);
expect(plainObject.type).toBe('object'); expect(plainObject.type).toBe('object');
expect(plainObject.dict.foo.type).toBe('string'); expect(plainObject.dict.foo.type).toBe('string');
}); });
......
...@@ -44,13 +44,24 @@ describe('Schema arrays', () => { ...@@ -44,13 +44,24 @@ describe('Schema arrays', () => {
const schema = MyConfig as Schema<MyConfig>; const schema = MyConfig as Schema<MyConfig>;
it('should be correct type', () => { function checkSchema(schema: Schema) {
expect(schema.dict.foo.type).toEqual('array'); expect(schema.dict.foo.type).toEqual('array');
expect(schema.dict.bar.type).toEqual('array'); expect(schema.dict.bar.type).toEqual('array');
expect(schema.dict.myProperties.type).toEqual('array'); expect(schema.dict.myProperties.type).toEqual('array');
expect(schema.dict.notArray.type).toEqual('string'); expect(schema.dict.notArray.type).toEqual('string');
expect(schema.dict.myTup.type).toEqual('tuple'); expect(schema.dict.myTup.type).toEqual('tuple');
expect(schema.dict.myTupArr.type).toEqual('array'); expect(schema.dict.myTupArr.type).toEqual('array');
}
it('should be correct type', () => {
checkSchema(schema);
});
it('should serialize', () => {
const data = schema.toJSON();
console.log(JSON.stringify(data, null, 2));
const restoredSchema = new Schema(data);
checkSchema(restoredSchema);
}); });
it('should be instance of property', () => { it('should be instance of property', () => {
......
...@@ -5,10 +5,10 @@ describe('Schema dict', () => { ...@@ -5,10 +5,10 @@ describe('Schema dict', () => {
@RegisterSchema() @RegisterSchema()
class MyProperty { class MyProperty {
@SchemaProperty({ default: 'default' }) @SchemaProperty({ default: 'default' })
name: string; myName: string;
getName() { getName() {
return this.name; return this.myName;
} }
} }
...@@ -36,11 +36,22 @@ describe('Schema dict', () => { ...@@ -36,11 +36,22 @@ describe('Schema dict', () => {
const schema = MyConfig as Schema<MyConfig>; const schema = MyConfig as Schema<MyConfig>;
it('should be correct type', () => { function checkSchema(schema: Schema) {
expect(schema.dict.foo.type).toEqual('dict'); expect(schema.dict.foo.type).toEqual('dict');
expect(schema.dict.fooAndBar.type).toEqual('dict'); expect(schema.dict.fooAndBar.type).toEqual('dict');
expect(schema.dict.myProperties.type).toEqual('dict'); expect(schema.dict.myProperties.type).toEqual('dict');
expect(schema.dict.myPropertiesArr.type).toEqual('array'); expect(schema.dict.myPropertiesArr.type).toEqual('array');
}
it('should be correct type', () => {
checkSchema(schema);
});
it('should serialize', () => {
const data = schema.toJSON();
console.log(JSON.stringify(data, null, 2));
const restoredSchema = new Schema(data);
checkSchema(restoredSchema);
}); });
it('should check dict', () => { it('should check dict', () => {
...@@ -68,13 +79,13 @@ describe('Schema dict', () => { ...@@ -68,13 +79,13 @@ describe('Schema dict', () => {
const config = new MyConfig({ const config = new MyConfig({
myProperties: { myProperties: {
foo: { foo: {
name: 'foo', myName: 'foo',
}, },
}, },
myPropertiesArr: [ myPropertiesArr: [
{ {
bar: { bar: {
name: 'bar', myName: 'bar',
}, },
}, },
], ],
......
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