popurelate
Version:
Easily populate and filter documents using data from related collections.
102 lines (101 loc) • 4.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.decomposePipelines = void 0;
/* eslint-disable max-params */
const _1 = require(".");
const decomposePipelines = (transformedPipelines, counter, helper) => {
const is = helper.pipelineIs;
for (let i = 0; i < transformedPipelines.length; ++i) {
const each = transformedPipelines[i];
if (!each.useOptimizer)
continue;
let decomposed = null;
if (is.query(each.pipeline)) {
decomposed = decomposeQuery(each.pipeline);
}
if (is.addFields(each.pipeline)) {
decomposed = decomposeAddFields(each.pipeline);
}
if (is.populate(each.pipeline)) {
decomposed = decomposePopulation(each.pipeline);
}
if (!decomposed || decomposed.length <= 1)
continue;
transformedPipelines.splice(i, 1, ...decomposed.map((e) => (Object.assign(Object.assign({}, _1.wrapPipeline(e, counter)), { useOptimizer: each.useOptimizer, partiallyUseOptimizer: each.partiallyUseOptimizer, cannotBeRemoved: each.cannotBeRemoved, invisible: each.invisible, pipeline: e, IAmDependedOnFields: new Set(each.IAmDependedOnFields), IAmChangingFields: _1.copyChangingFields(each.IAmChangingFields), sameSettersWith: new Set(each.sameSettersWith) }))));
i += decomposed.length - 1;
}
};
exports.decomposePipelines = decomposePipelines;
const decomposeQuery = (pipeline) => {
const keys = Object.keys(pipeline.query);
if (keys.length <= 1)
return null;
const pipelines = [];
for (const key in pipeline.query) {
pipelines.push({
query: {
[key]: pipeline.query[key],
},
});
}
return pipelines;
};
const decomposeAddFields = (pipeline) => {
const keys = Object.keys(pipeline.addFields);
if (keys.length <= 1)
return null;
const pipelines = [];
for (const key in pipeline.addFields) {
pipelines.push({
addFields: {
[key]: pipeline.addFields[key],
},
});
}
return pipelines;
};
const decomposePopulation = (pipeline) => {
if (!pipeline.populate.children)
return null;
const pipelines = [];
deepPushPopulation(pipeline, pipelines);
return pipelines;
};
const deepPushPopulation = (populationPipeline, pipelines = [], path = [], root = null) => {
const copiedMe = Object.assign({}, populationPipeline);
copiedMe.populate = Object.assign(Object.assign({}, copiedMe.populate), { children: undefined });
if (root) {
root = deepCopyPopulation(root);
const parent = findPopulationElement(root, path.slice(0, -1));
parent.populate.children = { [path[path.length - 1]]: copiedMe };
parent.populate.alreadyPopulated = true;
}
pipelines.push(root || copiedMe);
if (populationPipeline.populate.children) {
for (const key in populationPipeline.populate.children) {
deepPushPopulation(populationPipeline.populate.children[key], pipelines, [...path, key], root || populationPipeline);
}
}
return copiedMe;
};
const findPopulationElement = (root, path) => {
let current = root;
for (let keyIndex = 0; keyIndex < path.length; ++keyIndex) {
const nextKey = path[keyIndex];
if (!current.populate.children)
return null;
current = current.populate.children[nextKey];
}
return current;
};
const deepCopyPopulation = (populationPipeline) => {
const copiedMe = Object.assign({}, populationPipeline);
copiedMe.populate = Object.assign({}, copiedMe.populate);
if (copiedMe.populate.children) {
copiedMe.populate.children = Object.assign({}, copiedMe.populate.children);
for (const key in copiedMe.populate.children) {
copiedMe.populate.children[key] = deepCopyPopulation(copiedMe.populate.children[key]);
}
}
return copiedMe;
};