@juneil/tschema
Version:
110 lines • 4.45 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const common_1 = require("../common");
class JSONSchemaDraft07 {
constructor(name, properties) {
this.name = name;
this.properties = properties;
this.schema = 'http://json-schema.org/draft-07/schema#';
this.id = '';
this.id = `http://tschema.com/${this.name.toLowerCase()}.json`;
}
serializeProperties(properties, ctx) {
return properties
.map(property => this.type(property, ctx))
.map(property => this.enum(property))
.reduce((a, property) => (Object.assign({}, a, { [property.key]: property.result })), {});
}
serializeRequired(properties) {
return properties
.filter(p => this.required(p))
.map(p => p.key);
}
hasMetadata(classToCheck) {
return common_1.isAnyClass(classToCheck) && !!Reflect.getMetadata(common_1.PROPERTIES, classToCheck);
}
toJSONSchema(root = true, id = true) {
const ctx = {
definitions: []
};
const json = {
title: this.name,
description: 'JSON Schema generated by TSchema',
type: 'object',
properties: this.serializeProperties(this.properties, ctx),
required: this.serializeRequired(this.properties),
};
if (root) {
return Object.assign({ $schema: this.schema, $id: this.id }, json);
}
else if (id) {
return Object.assign({ $id: `${this.name.toLowerCase()}.json` }, json);
}
return json;
}
type(property, ctx) {
const rule = property.rules.find(r => r.rule === common_1.TYPE);
switch (rule.value) {
case Number:
return Object.assign({}, property, { result: { type: this.integer(property) ? 'integer' : 'number' } });
case String:
return Object.assign({}, property, { result: { type: 'string' } });
case Boolean:
return Object.assign({}, property, { result: { type: 'boolean' } });
case Array:
return Object.assign({}, property, { result: Object.assign({ type: 'array' }, this.item(property)) });
case undefined:
return Object.assign({}, property, { result: { type: 'null' } });
default:
if (this.hasMetadata(rule.value)) {
ctx.definitions = ctx.definitions || [];
ctx.definitions.push(rule.value);
const result = new JSONSchemaDraft07(rule.value.name.toLowerCase(), Reflect.getMetadata(common_1.PROPERTIES, rule.value))
.toJSONSchema(false, false);
return Object.assign({}, property, { result });
}
return Object.assign({}, property, { result: { type: 'object' } });
}
}
item(property) {
const rule = property.rules.find(r => r.rule === common_1.ITEM) || {};
let result;
switch (rule.value) {
case Number:
result = { type: 'number' };
break;
case String:
result = { type: 'string' };
break;
case Boolean:
result = { type: 'boolean' };
break;
default:
if (this.hasMetadata(rule.value)) {
result = new JSONSchemaDraft07(rule.value.name.toLowerCase(), Reflect.getMetadata(common_1.PROPERTIES, rule.value))
.toJSONSchema(false, false);
}
else {
result = { type: 'object' };
}
}
return { items: result };
}
enum(property) {
const rule = property.rules.find(r => r.rule === common_1.ENUM);
if (rule && rule.value && rule.value.length) {
return Object.assign({}, property, { result: Object.assign({}, property.result, { enum: rule.value }) });
}
return property;
}
integer(property) {
const rule = property.rules.find(r => r.rule === common_1.INTEGER);
return !!rule;
}
required(property) {
const rule = property.rules.find(r => r.rule === common_1.REQUIRED);
return !!rule;
}
}
exports.JSONSchemaDraft07 = JSONSchemaDraft07;
//# sourceMappingURL=draft-07.js.map