odatafy-mongodb
Version:
convert oData requests through odatafy to MongoDB queries
185 lines (184 loc) • 7.58 kB
JavaScript
;
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateLookupFromExpand = void 0;
var odatafy_parser_1 = require("odatafy-parser");
var filterGenerator_1 = require("./filterGenerator");
var sortGenerator_1 = require("./sortGenerator");
var limitGenerator_1 = require("./limitGenerator");
var skipGenerator_1 = require("./skipGenerator");
var selectGenerator_1 = require("./selectGenerator");
/**
* Get a MongoDB lookup stage based on oData expand parameter
* @param expr expression of the oData expand parameter
* @param collectionMap collection map to map properties of a data model to collection names
* @returns MongoDB lookup stage
*/
function generateLookupFromExpand(expr, collectionMap) {
var result = [];
var expNode = odatafy_parser_1.expandParser.parse(expr);
expNode.value.forEach(function (node) {
//generate lookup pipeline
var pipeline = [];
//Is path node without options
if (node.nodeType == odatafy_parser_1.NodeTypes.ExpandPathNode) {
var extractedPaths_1 = [];
node.value.forEach(function (itemNode) {
if (itemNode.nodeType == odatafy_parser_1.NodeTypes.ExpandIdentifierNode) {
extractedPaths_1.push(itemNode.value);
}
});
var path = extractedPaths_1.join('.');
if (path in collectionMap) {
result = __spreadArray(__spreadArray([], __read(result), false), __read(getLookupQuery(path, collectionMap[path])), false);
}
}
//Is path node with options
if (node.nodeType == odatafy_parser_1.NodeTypes.ExpandPathNodeWithOptions) {
var extractedPaths_2 = [];
node.value.forEach(function (itemNode) {
if (itemNode.nodeType == odatafy_parser_1.NodeTypes.ExpandIdentifierNode) {
extractedPaths_2.push(itemNode.value);
}
});
var path = extractedPaths_2.join('.');
if (path in collectionMap) {
//only process options after checking if field is in collectionMap to safe some performance
var optionsPipeline = [];
if (node.optionType == 'default') {
//@ts-expect-error
if (node.options.filter) {
//@ts-expect-error
optionsPipeline.push((0, filterGenerator_1.generateMatchStage)(node.options.filter));
}
//@ts-expect-error
if (node.options.orderby) {
//@ts-expect-error
optionsPipeline.push((0, sortGenerator_1.generateSortStage)(node.options.orderby));
}
//@ts-expect-error
if (node.options.skip) {
//@ts-expect-error
optionsPipeline.push((0, skipGenerator_1.generateSkipStage)(node.options.skip));
}
//@ts-expect-error
if (node.options.top) {
//@ts-expect-error
optionsPipeline.push((0, limitGenerator_1.generateLimitStage)(node.options.top));
}
//@ts-expect-error
if (node.options.select) {
//@ts-expect-error
optionsPipeline.push((0, selectGenerator_1.generateProjectStage)(node.options.select));
}
result = __spreadArray(__spreadArray([], __read(result), false), __read(getLookupQuery(path, collectionMap[path], optionsPipeline)), false);
}
}
}
return pipeline;
});
return result;
}
exports.generateLookupFromExpand = generateLookupFromExpand;
function getLookupQuery(field, collection, pipeline) {
if (pipeline === void 0) { pipeline = []; }
var query = [
{
"$addFields": {
"mongodbODataTempJoinIsArray": {
"$isArray": "$".concat(field),
},
},
},
{
"$lookup": {
from: "".concat(collection),
let: {
"mongodbODataTempJoinIsArray": "$mongodbODataTempJoinIsArray",
"mongodbODataTempJoinFieldValue": "$".concat(field)
},
pipeline: __spreadArray([
{
"$match": {
"$expr": {
"$eq": [
{
"$cond": {
"if": "$$mongodbODataTempJoinIsArray",
"then": {
"$in": [
"$_id",
"$$mongodbODataTempJoinFieldValue"
]
},
"else": {
"$eq": [
"$_id",
"$$mongodbODataTempJoinFieldValue"
]
},
},
},
true
]
}
}
}
], __read(pipeline), false),
as: "".concat(field)
},
}
];
var extension = [{
"$set": {},
}, {
"$project": {
"mongodbODataTempJoinIsArray": 0,
},
}];
extension[0]["$set"]["".concat(field)] = {
"$cond": {
"if": "$mongodbODataTempJoinIsArray",
"then": "$".concat(field),
"else": {
"$cond": {
"if": {
"$eq": [
"$".concat(field),
[],
],
},
"then": null,
"else": {
"$first": "$".concat(field),
},
},
},
},
};
return __spreadArray(__spreadArray([], __read(query), false), __read(extension), false);
}