123 lines
4.1 KiB
JavaScript
123 lines
4.1 KiB
JavaScript
'use strict';
|
|
|
|
/**
|
|
* Module dependencies.
|
|
*/
|
|
var schemaBuilder = require('./schema-builder');
|
|
var typeConverter = require('./type-converter');
|
|
var TypeRegistry = require('./type-registry');
|
|
|
|
/**
|
|
* Export the modelHelper singleton.
|
|
*/
|
|
var modelHelper = module.exports = {
|
|
/**
|
|
* Given a class (from remotes.classes()), generate a model definition.
|
|
* This is used to generate the schema at the top of many endpoints.
|
|
* @param {Class} modelClass Model class.
|
|
* @param {TypeRegistry} typeRegistry Registry of types and models.
|
|
* @return {Object} Associated model definition.
|
|
*/
|
|
registerModelDefinition: function(modelCtor, typeRegistry) {
|
|
var lbdef = modelCtor.definition;
|
|
|
|
if (!lbdef) {
|
|
// The model does not have any definition, it was most likely
|
|
// created as a placeholder for an unknown property type
|
|
return;
|
|
}
|
|
|
|
var name = lbdef.name;
|
|
if (typeRegistry.isDefined(name)) {
|
|
// The model is already included
|
|
return;
|
|
}
|
|
|
|
var swaggerDef = {
|
|
description: typeConverter.convertText(
|
|
lbdef.description || (lbdef.settings && lbdef.settings.description)),
|
|
properties: {},
|
|
required: []
|
|
};
|
|
|
|
var properties = lbdef.rawProperties || lbdef.properties;
|
|
|
|
// Iterate through each property in the model definition.
|
|
// Types may be defined as constructors (e.g. String, Date, etc.),
|
|
// or as strings; swaggerSchema.builFromLoopBackType() will take
|
|
// care of the conversion.
|
|
Object.keys(properties).forEach(function(key) {
|
|
var prop = properties[key];
|
|
|
|
// Hide hidden properties.
|
|
if (modelHelper.isHiddenProperty(lbdef, key))
|
|
return;
|
|
|
|
// Eke a type out of the constructors we were passed.
|
|
var schema = schemaBuilder.buildFromLoopBackType(prop, typeRegistry);
|
|
|
|
var desc = typeConverter.convertText(prop.description || prop.doc);
|
|
if (desc) schema.description = desc;
|
|
|
|
// Required props sit in a per-model array.
|
|
if (prop.required || (prop.id && !prop.generated)) {
|
|
swaggerDef.required.push(key);
|
|
}
|
|
|
|
// Assign the schema to the properties object.
|
|
swaggerDef.properties[key] = schema;
|
|
});
|
|
|
|
if (lbdef.settings) {
|
|
var strict = lbdef.settings.strict;
|
|
var additionalProperties = lbdef.settings.additionalProperties;
|
|
var notAllowAdditionalProperties = strict || (additionalProperties !== true);
|
|
if (notAllowAdditionalProperties){
|
|
swaggerDef.additionalProperties = false;
|
|
}
|
|
}
|
|
|
|
if (!swaggerDef.required.length) {
|
|
// "required" must have at least one item when present
|
|
delete swaggerDef.required;
|
|
}
|
|
|
|
typeRegistry.register(name, swaggerDef);
|
|
|
|
// Add models from settings
|
|
if (lbdef.settings && lbdef.settings.models) {
|
|
for (var m in lbdef.settings.models) {
|
|
var model = modelCtor[m];
|
|
if (typeof model !== 'function' || !model.modelName) continue;
|
|
modelHelper.registerModelDefinition(model, typeRegistry);
|
|
// TODO it shouldn't be necessary to reference the model here,
|
|
// let accepts/returns/property reference it instead
|
|
typeRegistry.reference(model.modelName);
|
|
}
|
|
}
|
|
|
|
// Generate model definitions for related models
|
|
for (var r in modelCtor.relations) {
|
|
var rel = modelCtor.relations[r];
|
|
if (rel.modelTo) {
|
|
modelHelper.registerModelDefinition(rel.modelTo, typeRegistry);
|
|
// TODO it shouldn't be necessary to reference the model here,
|
|
// let accepts/returns/property reference it instead
|
|
typeRegistry.reference(rel.modelTo.modelName);
|
|
}
|
|
if (rel.modelThrough) {
|
|
modelHelper.registerModelDefinition(rel.modelThrough, typeRegistry);
|
|
// TODO it shouldn't be necessary to reference the model here,
|
|
// let accepts/returns/property reference it instead
|
|
typeRegistry.reference(rel.modelThrough.modelName);
|
|
}
|
|
}
|
|
},
|
|
|
|
isHiddenProperty: function(definition, propName) {
|
|
return definition.settings &&
|
|
Array.isArray(definition.settings.hidden) &&
|
|
definition.settings.hidden.indexOf(propName) !== -1;
|
|
},
|
|
};
|