popurelate
Version:
Easily populate and filter documents using data from related collections.
58 lines (57 loc) • 2.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getMongooseModelRelations = exports.addMongooseRelations = void 0;
const addMongooseRelations = (db, options = {}) => {
const models = db.getModelsByEngine("mongoose");
const relations = exports.getMongooseModelRelations(models);
if (options.logger)
options.logger(relations);
for (const modelName in relations) {
const relation = relations[modelName];
db.addRelation(modelName, relation);
}
};
exports.addMongooseRelations = addMongooseRelations;
const getMongooseModelRelations = (models) => {
const mongooseModelNameToModelName = buildModelsTree(models);
const relationsByModels = {};
for (const mongooseModelName in mongooseModelNameToModelName) {
const { modelName, mongooseModel } = mongooseModelNameToModelName[mongooseModelName];
const relations = {};
mongooseModel.schema.eachPath(prop => {
const schema = mongooseModel.schema.path(prop);
let ref = null;
const amIArray = Array.isArray(schema.options.type);
if (amIArray) {
const firstOptions = schema.options.type[0];
ref = firstOptions.ref;
}
if (!ref)
ref = schema.options.ref;
if (typeof ref !== "string")
return;
const secondModel = mongooseModelNameToModelName[ref];
if (secondModel) {
const field = prop + (amIArray ? "[]" : "");
relations[field] = secondModel.modelName;
}
});
if (Object.keys(relations).length > 0) {
relationsByModels[modelName] = relations;
}
}
return relationsByModels;
};
exports.getMongooseModelRelations = getMongooseModelRelations;
const buildModelsTree = (models) => {
const mongooseModelNameToModelName = {};
for (const modelName in models) {
const model = models[modelName];
const mongooseModelName = model.modelName;
mongooseModelNameToModelName[mongooseModelName] = {
modelName,
mongooseModel: model,
};
}
return mongooseModelNameToModelName;
};