initial
This commit is contained in:
+115
@@ -0,0 +1,115 @@
|
||||
'use strict';
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
var Mixed = require('../../schema/mixed');
|
||||
var mpath = require('mpath');
|
||||
|
||||
/*!
|
||||
* @param {Schema} schema
|
||||
* @param {Object} doc POJO
|
||||
* @param {string} path
|
||||
*/
|
||||
|
||||
module.exports = function getSchemaTypes(schema, doc, path) {
|
||||
var pathschema = schema.path(path);
|
||||
|
||||
if (pathschema) {
|
||||
return pathschema;
|
||||
}
|
||||
|
||||
function search(parts, schema) {
|
||||
var p = parts.length + 1;
|
||||
var foundschema;
|
||||
var trypath;
|
||||
|
||||
while (p--) {
|
||||
trypath = parts.slice(0, p).join('.');
|
||||
foundschema = schema.path(trypath);
|
||||
if (foundschema) {
|
||||
if (foundschema.caster) {
|
||||
// array of Mixed?
|
||||
if (foundschema.caster instanceof Mixed) {
|
||||
return foundschema.caster;
|
||||
}
|
||||
|
||||
var schemas = null;
|
||||
if (doc != null && foundschema.schema != null && foundschema.schema.discriminators != null) {
|
||||
var discriminators = foundschema.schema.discriminators;
|
||||
var keys = mpath.get(trypath + '.' + foundschema.schema.options.discriminatorKey,
|
||||
doc);
|
||||
schemas = Object.keys(discriminators).
|
||||
reduce(function(cur, discriminator) {
|
||||
if (keys.indexOf(discriminator) !== -1) {
|
||||
cur.push(discriminators[discriminator]);
|
||||
}
|
||||
return cur;
|
||||
}, []);
|
||||
}
|
||||
|
||||
// Now that we found the array, we need to check if there
|
||||
// are remaining document paths to look up for casting.
|
||||
// Also we need to handle array.$.path since schema.path
|
||||
// doesn't work for that.
|
||||
// If there is no foundschema.schema we are dealing with
|
||||
// a path like array.$
|
||||
if (p !== parts.length && foundschema.schema) {
|
||||
var ret;
|
||||
if (parts[p] === '$') {
|
||||
if (p + 1 === parts.length) {
|
||||
// comments.$
|
||||
return foundschema;
|
||||
}
|
||||
// comments.$.comments.$.title
|
||||
ret = search(parts.slice(p + 1), schema);
|
||||
if (ret) {
|
||||
ret.$isUnderneathDocArray = ret.$isUnderneathDocArray ||
|
||||
!foundschema.schema.$isSingleNested;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (schemas != null && schemas.length > 0) {
|
||||
ret = [];
|
||||
for (var i = 0; i < schemas.length; ++i) {
|
||||
var _ret = search(parts.slice(p), schemas[i]);
|
||||
if (_ret != null) {
|
||||
_ret.$isUnderneathDocArray = _ret.$isUnderneathDocArray ||
|
||||
!foundschema.schema.$isSingleNested;
|
||||
if (_ret.$isUnderneathDocArray) {
|
||||
ret.$isUnderneathDocArray = true;
|
||||
}
|
||||
ret.push(_ret);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
ret = search(parts.slice(p), foundschema.schema);
|
||||
|
||||
if (ret) {
|
||||
ret.$isUnderneathDocArray = ret.$isUnderneathDocArray ||
|
||||
!foundschema.schema.$isSingleNested;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return foundschema;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// look for arrays
|
||||
var parts = path.split('.');
|
||||
for (var i = 0; i < parts.length; ++i) {
|
||||
if (parts[i] === '$') {
|
||||
// Re: gh-5628, because `schema.path()` doesn't take $ into account.
|
||||
parts[i] = '0';
|
||||
}
|
||||
}
|
||||
return search(parts, schema);
|
||||
};
|
||||
Reference in New Issue
Block a user