Commit ef40b463 authored by nanahira's avatar nanahira

add SchemaConf

parent bcaff9bf
Pipeline #6138 passed with stages
in 30 seconds
...@@ -14,6 +14,10 @@ npm install koishi-utils-schemagen reflect-metadata ...@@ -14,6 +14,10 @@ npm install koishi-utils-schemagen reflect-metadata
```ts ```ts
// 使用装饰器定义 Schema。 // 使用装饰器定义 Schema。
// SchemaConf 填写 Schema 本身的顶级属性。
@SchemaConf({
desc: 'my desc',
})
export class Config { export class Config {
// 基本的数据类型 // 基本的数据类型
@DefineSchema({ type: 'number', required: true }) @DefineSchema({ type: 'number', required: true })
......
{ {
"name": "koishi-utils-schemagengen", "name": "koishi-utils-schemagengen",
"version": "1.0.6", "version": "1.0.7",
"description": "在 Koishi.js 中,使用类装饰器定义 Schema", "description": "在 Koishi.js 中,使用类装饰器定义 Schema",
"main": "dist/src/index.js", "main": "dist/src/index.js",
"typings": "dist/src/index.d.ts", "typings": "dist/src/index.d.ts",
......
export const SchemaMetaKey = '_koishi_schema_meta'; export const SchemaMetaKey = '_koishi_schema_meta';
export const SchemaKeysMetaKey = '_koishi_schemakeys_meta'; export const SchemaKeysMetaKey = '_koishi_schemakeys_meta';
export const SchemaClassKey = '_koishi_schema_class_meta';
import { SchemaOptions } from './def'; import { SchemaClassOptions, SchemaOptions } from './def';
import 'reflect-metadata'; import 'reflect-metadata';
import { SchemaKeysMetaKey, SchemaMetaKey } from './constants'; import { SchemaClassKey, SchemaKeysMetaKey, SchemaMetaKey } from './constants';
import { Schema } from 'koishi'; import { Schema } from 'koishi';
import { import {
ClassConstructor, ClassConstructor,
...@@ -43,6 +43,13 @@ export function DefineSchema(options: SchemaOptions): PropertyDecorator { ...@@ -43,6 +43,13 @@ export function DefineSchema(options: SchemaOptions): PropertyDecorator {
}; };
} }
export function SchemaConf(options: SchemaClassOptions): ClassDecorator {
return (obj) => {
const objClass = obj;
Reflect.defineMetadata(SchemaClassKey, options, objClass);
};
}
export function UseSchema(schema: Schema) { export function UseSchema(schema: Schema) {
return DefineSchema({ schema }); return DefineSchema({ schema });
} }
......
...@@ -9,13 +9,16 @@ export type SchemaType = ...@@ -9,13 +9,16 @@ export type SchemaType =
| 'never' | 'never'
| ClassConstructor<any>; | ClassConstructor<any>;
export interface SchemaOptions { export interface SchemaClassOptions {
schema?: Schema<any>;
desc?: string; desc?: string;
required?: boolean; required?: boolean;
hidden?: boolean; hidden?: boolean;
comment?: string; comment?: string;
default?: any; default?: any;
}
export interface SchemaOptions extends SchemaClassOptions {
schema?: Schema<any>;
dict?: boolean; dict?: boolean;
array?: boolean; array?: boolean;
type?: SchemaType; type?: SchemaType;
......
...@@ -4,9 +4,9 @@ import { ...@@ -4,9 +4,9 @@ import {
plainToClass, plainToClass,
TransformOptions, TransformOptions,
} from 'class-transformer'; } from 'class-transformer';
import { SchemaOptions, SchemaOptionsDict } from './def'; import { SchemaClassOptions, SchemaOptions, SchemaOptionsDict } from './def';
import 'reflect-metadata'; import 'reflect-metadata';
import { SchemaKeysMetaKey, SchemaMetaKey } from './constants'; import { SchemaClassKey, SchemaKeysMetaKey, SchemaMetaKey } from './constants';
import _ from 'lodash'; import _ from 'lodash';
function getBasePropertySchemaFromOptions(options: SchemaOptions) { function getBasePropertySchemaFromOptions(options: SchemaOptions) {
...@@ -32,14 +32,7 @@ function getBasePropertySchemaFromOptions(options: SchemaOptions) { ...@@ -32,14 +32,7 @@ function getBasePropertySchemaFromOptions(options: SchemaOptions) {
} }
} }
function getPropertySchemaFromOptions<PT>(options: SchemaOptions): Schema<PT> { function applyOptionsToSchema(schema: Schema, options: SchemaClassOptions) {
let schema = getBasePropertySchemaFromOptions(options);
if (options.dict) {
schema = Schema.dict(schema);
}
if (options.array) {
schema = Schema.array(schema);
}
if (options.required != undefined) { if (options.required != undefined) {
schema._required = options.required; schema._required = options.required;
} }
...@@ -52,6 +45,20 @@ function getPropertySchemaFromOptions<PT>(options: SchemaOptions): Schema<PT> { ...@@ -52,6 +45,20 @@ function getPropertySchemaFromOptions<PT>(options: SchemaOptions): Schema<PT> {
if (options.comment != undefined) { if (options.comment != undefined) {
schema._comment = options.comment; schema._comment = options.comment;
} }
if (options.desc != undefined) {
schema.desc = options.desc;
}
}
function getPropertySchemaFromOptions<PT>(options: SchemaOptions): Schema<PT> {
let schema = getBasePropertySchemaFromOptions(options);
if (options.dict) {
schema = Schema.dict(schema);
}
if (options.array) {
schema = Schema.array(schema);
}
applyOptionsToSchema(schema, options);
return schema; return schema;
} }
...@@ -83,11 +90,17 @@ function schemaOptionsFromClass<T>( ...@@ -83,11 +90,17 @@ function schemaOptionsFromClass<T>(
} }
export function schemaFromClass<T>(cl: ClassConstructor<T>): Schema<T> { export function schemaFromClass<T>(cl: ClassConstructor<T>): Schema<T> {
let schema: Schema;
const optionsDict = schemaOptionsFromClass(cl); const optionsDict = schemaOptionsFromClass(cl);
if (!optionsDict) { if (!optionsDict) {
return Schema.any(); schema = Schema.any();
} else {
schema = schemasFromDict<T>(optionsDict);
} }
return schemasFromDict<T>(optionsDict); const extraOptions: SchemaClassOptions =
Reflect.getMetadata(SchemaClassKey, cl) || {};
applyOptionsToSchema(schema, extraOptions);
return schema;
} }
export function schemaTransform<T>(cl: ClassConstructor<T>, data: any): T { export function schemaTransform<T>(cl: ClassConstructor<T>, data: any): T {
......
import { DefineSchema, schemaFromClass, schemaTransform } from '../src'; import {
DefineSchema,
SchemaConf,
schemaFromClass,
schemaTransform,
} from '../src';
import { Schema } from 'koishi'; import { Schema } from 'koishi';
@SchemaConf({
desc: 'my desc',
})
class B { class B {
@DefineSchema({ type: 'number', default: 2 }) @DefineSchema({ type: 'number', default: 2, desc: 'aaaaa' })
aa: number; aa: number;
@DefineSchema({ type: 'boolean', default: true }) @DefineSchema({ type: 'boolean', default: true })
bb: boolean; bb: boolean;
} }
@SchemaConf({
desc: 'my base desc',
})
class A { class A {
@DefineSchema({ type: 'number', required: true }) @DefineSchema({ type: 'number', required: true })
a: number; a: number;
...@@ -30,6 +41,7 @@ class A { ...@@ -30,6 +41,7 @@ class A {
} }
const schema = schemaFromClass(A); const schema = schemaFromClass(A);
console.log(JSON.stringify(schema, null, 2));
const testObject = { const testObject = {
a: 4, a: 4,
...@@ -42,7 +54,7 @@ const testObject = { ...@@ -42,7 +54,7 @@ const testObject = {
// console.log(JSON.stringify(testValidate, null, 2)); // console.log(JSON.stringify(testValidate, null, 2));
const testTransform = schemaTransform(A, testObject); const testTransform = schemaTransform(A, testObject);
console.log(JSON.stringify(testTransform, null, 2)); //console.log(JSON.stringify(testTransform, null, 2));
console.log(testTransform.bi instanceof B); console.log(testTransform.bi instanceof B);
console.log(testTransform.biArr[0] instanceof B); console.log(testTransform.biArr[0] instanceof B);
console.log(testTransform.biDict[0].cccc instanceof B); console.log(testTransform.biDict[0].cccc instanceof B);
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