UNPKG

@juneil/tschema

Version:
110 lines 4.45 kB
"use strict"; 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