UNPKG

takorogo

Version:
383 lines (349 loc) 12.1 kB
(function() { 'use strict'; var Postprocessor, utils, _, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; _ = require('lodash'); utils = require('./utils'); Postprocessor = (function() { function Postprocessor() { this.processRules = __bind(this.processRules, this); this.processDefinition = __bind(this.processDefinition, this); this.processEnumeration = __bind(this.processEnumeration, this); } Postprocessor.supportedRules = ['definition', 'enumeration', 'index', 'attribute', 'relation', 'resolvedRelation', 'link', 'meta']; Postprocessor.directMetadata = ['title', 'description']; Postprocessor.absoluteReferencePathForClass = function(className, ctx) { return "" + ctx.__path + "/definitions/" + className; }; Postprocessor.prototype.cleanRefs = function() { this.typeRefs = []; this.typeDefs = {}; return this.mainClass = false; }; Postprocessor.prototype.postprocess = function(data) { var schema; this.cleanRefs(); schema = this.processRules(data, { __path: '#' }); this.resolveTypeReferences(schema); this.cleanUpSchema(schema); return schema; }; Postprocessor.prototype.cleanUpSchema = function(schema) { delete schema.__path; _.forEach(this.typeDefs, function(def) { return delete def.__path; }); if (this.mainClass) { _.defaults(schema, this.mainClass); } return schema; }; Postprocessor.prototype.processMeta = function(meta, ctx) { var _ref; if (ctx == null) { ctx = {}; } if (_ref = meta.key, __indexOf.call(this.constructor.directMetadata, _ref) >= 0) { ctx[meta.key] = meta.value; } else { utils.addAsObjectMember(ctx, 'metadata', meta.key, meta.value); } return ctx; }; Postprocessor.prototype.processEnumeration = function(enumeration, ctx) { var destructuredClassTitle, elements, klass; if (ctx == null) { ctx = {}; } elements = enumeration.elements.map(function(element) { return element.name; }); destructuredClassTitle = "__" + enumeration.title + "__"; klass = _.merge(_.omit(enumeration, ['elements']), { title: destructuredClassTitle, additionalProperties: false, required: elements }); klass.required.forEach((function(_this) { return function(key) { return _this.addPropertyToContext(key, {}, klass); }; })(this)); enumeration = { __path: this.constructor.absoluteReferencePathForClass(enumeration.title, ctx), type: 'array', title: enumeration.title, elements: elements, minItems: elements.length, maxItems: elements.length }; enumeration.destructuredTo = { $ref: this.constructor.absoluteReferencePathForClass(destructuredClassTitle, enumeration) }; this.processDefinition(klass, enumeration); utils.addAsObjectMember(ctx, 'definitions', enumeration.title, enumeration); this.registerDefinition(enumeration); return ctx; }; Postprocessor.prototype.processDefinition = function(klass, ctx) { if (ctx == null) { ctx = {}; } klass.__path = this.constructor.absoluteReferencePathForClass(klass.title, ctx); if ((klass.rules != null) && klass.rules.length > 0) { this.processRules(klass.rules, klass); } if (klass.isMainDefinition) { this.mainClass = { title: klass.title, type: klass.type, $ref: klass.__path }; } klass = _.omit(klass, ['rules', 'rule', 'isMainDefinition']); utils.addAsObjectMember(ctx, 'definitions', klass.title, klass); this.registerDefinition(klass); return ctx; }; Postprocessor.prototype.processRule = function(rule, ctx) { var method, _ref; if ((_ref = rule.rule, __indexOf.call(this.constructor.supportedRules, _ref) >= 0)) { method = "process" + (utils.capitalizeFirst(rule.rule)); return this[method](rule, ctx); } else { throw new Error("Unrecognized Takorogo rule " + rule.rule + "."); } }; Postprocessor.prototype.processRules = function(rules, ctx) { if (ctx == null) { ctx = {}; } rules.forEach((function(_this) { return function(rule) { return _this.processRule(rule, ctx); }; })(this)); return ctx; }; Postprocessor.prototype.processIndex = function(index, ctx) { if (ctx == null) { ctx = {}; } index = _.omit(index, ['rule']); index.key = index.key.map((function(_this) { return function(field) { if (field.type != null) { _this.processAttribute({ attribute: field }, ctx); } return field.name; }; })(this)); utils.pushAsArrayItem(ctx, 'indexes', index); index.key.forEach((function(_this) { return function(key) { var _ref; if (((_ref = ctx.properties) != null ? _ref[key] : void 0) == null) { _this.addPropertyToContext(key, {}, ctx); } return utils.pushAsArrayUniqueItem(ctx, 'required', key); }; })(this)); return ctx; }; Postprocessor.prototype.processAttribute = function(property, ctx) { var name; if (ctx == null) { ctx = {}; } if (property.attribute.aliasOf != null) { utils.addAsObjectMember(ctx, 'aliases', property.attribute.name, property.attribute.aliasOf.name); } name = property.attribute.name; property = _.omit(property.attribute, ['aliasOf', 'name']); this.processPropertyType(property, ctx); this.addPropertyToContext(name, property, ctx); return ctx; }; Postprocessor.prototype.addPropertyToContext = function(name, property, ctx) { property = this.expandPropertyPath(name, property); name = name.split('.')[0]; utils.addAsObjectMember(ctx, 'properties', name, property); return ctx; }; Postprocessor.prototype.expandPropertyPath = function(name, property) { var path, wrapper; path = name.split('.'); if (path.length > 1) { wrapper = { type: 'object', properties: {} }; wrapper.properties[path[1]] = this.expandPropertyPath(path.slice(1).join('.'), property); property = wrapper; } return property; }; Postprocessor.prototype.registerTypeReference = function(property, ctx) { return this.typeRefs.push({ property: property, ctx: ctx }); }; Postprocessor.prototype.registerDefinition = function(definition) { return this.typeDefs[definition.__path] = definition; }; Postprocessor.prototype.findTypeReference = function(name, ctx) { var $ref, path; $ref = this.constructor.absoluteReferencePathForClass(name, ctx); if (this.typeDefs[$ref] != null) { return $ref; } else { path = ctx.__path.split('/').slice(0, -1).join('/'); if (path) { return this.findTypeReference(name, { __path: path }); } else { return false; } } }; Postprocessor.prototype.resolveTypeReference = function(property, unresolved) { var $ref, ref; ref = property.property; $ref = this.findTypeReference(ref.type.title, property.ctx); if ($ref) { ref.type.$ref = $ref; } else { ref.type.type = ref.type.title; unresolved[ref.type.title] = true; } return _.merge(property.property, _.omit(ref.type, ['title'])); }; Postprocessor.prototype.resolveTypeReferences = function(schema) { var unresolved; unresolved = {}; this.typeRefs.forEach((function(_this) { return function(ref) { return _this.resolveTypeReference(ref, unresolved); }; })(this)); unresolved = Object.keys(unresolved); if (unresolved.length > 0) { schema.unresolvedTypes = unresolved; } return schema; }; Postprocessor.prototype.processPropertyType = function(property, ctx) { var _ref, _ref1, _ref2; if (ctx == null) { ctx = {}; } if (((_ref = property.type) != null ? _ref.rule : void 0) != null) { this.processRule(property.type, ctx); property.type = _.pick(property.type, ['type', 'title', 'isArrayOf', 'arrayDepth']); } if ((_ref1 = property.type) != null ? _ref1.isArrayOf : void 0) { this.processArrayType(property, ctx); } if (((_ref2 = property.type) != null ? _ref2.type : void 0) === 'object') { this.registerTypeReference(property, ctx); } return ctx; }; Postprocessor.prototype.processArrayType = function(property, ctx) { var arrayDepth; arrayDepth = property.type.arrayDepth || 1; property.items = { type: _.omit(property.type, ['isArrayOf', 'arrayDepth']) }; property.type = 'array'; this.registerTypeReference(property.items, ctx); while (arrayDepth-- > 1) { property.items = { type: 'array', items: property.items }; } return ctx; }; Postprocessor.prototype.processRelation = function(relation, ctx, addAttribute) { var relType, _i, _len, _ref, _ref1; if (ctx == null) { ctx = {}; } if (addAttribute == null) { addAttribute = true; } if (addAttribute) { this.processAttribute({ attribute: relation.attribute }, ctx); } relation = _.merge(_.omit(relation, ['rule', 'attribute']), { property: relation.attribute.name }); _ref = ['in', 'out']; for (_i = 0, _len = _ref.length; _i < _len; _i++) { relType = _ref[_i]; if (((_ref1 = relation[relType]) != null ? _ref1.attributes : void 0) != null) { relation[relType].attributes = relation[relType].attributes.map((function(_this) { return function(attr) { var _ref2; if (!((_ref2 = ctx.properties) != null ? _ref2[attr.name] : void 0)) { _this.processAttribute({ attribute: attr }, ctx); } return attr.name; }; })(this)); } } utils.addAsObjectMember(ctx, 'relations', relation.property, relation); return ctx; }; Postprocessor.prototype.processResolvedRelation = function(relation, ctx) { var attribute, _i, _len, _ref; if (ctx == null) { ctx = {}; } _ref = relation.resolve.key; for (_i = 0, _len = _ref.length; _i < _len; _i++) { attribute = _ref[_i]; this.processAttribute({ attribute: attribute }, ctx); utils.pushAsArrayUniqueItem(ctx, 'required', attribute.name); } relation.resolve = { key: relation.resolve.key.map(function(attr) { return attr.name; }) }; this.processRelation(relation, ctx, false); return ctx; }; Postprocessor.prototype.processLink = function(link, ctx) { if (ctx == null) { ctx = {}; } this.processAttribute({ attribute: link.attribute }, ctx); link = _.merge(_.omit(link, ['rule', 'attribute']), { property: link.attribute.name }); utils.addAsObjectMember(ctx, 'links', link.property, link); return ctx; }; return Postprocessor; })(); module.exports = Postprocessor; }).call(this); //# sourceMappingURL=postprocessor.js.map