mongoose-schema-jsonschema
Version:
Mongoose extension that allows to build json schema for mongoose models, schemas and queries
112 lines (88 loc) • 2.03 kB
JavaScript
const assert = require('assert');
function findPath(obj, path) {
let spec;
let isArray;
let cont;
const jssPath = path.split('.');
const prop = jssPath.pop();
if (jssPath.length) {
cont = jssPath.reduce((o, p) => {
while (o && o.type === 'array') o = o.items;
return o.properties[p];
}, obj);
while (cont && cont.type === 'array') cont = cont.items;
} else {
cont = obj;
}
if (cont === undefined) return undefined;
const parent = cont;
cont = cont.properties;
const baseCont = cont;
spec = cont[prop];
isArray = false;
while (spec && spec.type === 'array') {
isArray = true;
cont = spec;
spec = spec.items;
}
return {
spec,
cont,
baseCont,
prop,
isArray,
parent,
};
}
function ensurePath(obj, path) {
assert.ok(obj);
let cont;
const jssPath = path.split('.');
const first = jssPath.shift();
cont = obj;
while (cont.type === 'array') cont = cont.items;
if (!cont.properties) cont.properties = {};
if (jssPath.length === 0) {
return {
cont,
prop: first,
};
}
cont.properties[first] = cont.properties[first] || {
title: first,
type: 'object',
};
const spec = cont.properties[first];
return ensurePath(spec, jssPath.join('.'));
}
const compose2 = (f, g) => (...args) => f(g(...args));
const idX = x => x;
const compose = (...fns) => (
fns.length > 0 ? fns.reduce(compose2) : idX
);
const hasProperty = Function.prototype.call.bind(
Object.prototype.hasOwnProperty,
);
const readConstraint = constraint => (Array.isArray(constraint) ? constraint[0] : constraint);
const normalizeSelection = fields => Object.keys(fields).reduce(
(target, key) => Object.defineProperty(
target,
key.replace(/^-/, ''),
{
value: fields[key],
enumerable: true,
writable: true,
configurable: true,
},
),
{},
);
module.exports = {
findPath,
ensurePath,
compose,
idX,
hasProperty,
readConstraint,
normalizeSelection,
};