UNPKG

@odata2ts/odata-query-objects

Version:

Q-Objects are the magic sauce for the odata-query-builder and allow for renaming and type conversion

144 lines 6.49 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.QueryObject = exports.ENUMERABLE_PROP_DEFINITION = void 0; function getMapping(q) { // need to use a for-in loop, because of getters which are located at the prototype level const result = new Map(); for (let key in q) { // @ts-ignore const value = q[key]; if (typeof value === "object" && typeof value.getPath === "function") { const odataName = value.getPath(); result.set(odataName, key); } } return result; } exports.ENUMERABLE_PROP_DEFINITION = { enumerable: true }; class QueryObject { constructor(__prefix) { this.__prefix = __prefix; } __getPropMapping() { if (!this.__propMapping) { this.__propMapping = getMapping(this); } return this.__propMapping; } /** * Adds the prefix of this QueryObject including a separating slash in front of the given path. * Only applies, if this QueryObject has a prefix. * * @param path the path to be prefixed * @protected */ withPrefix(path) { return this.__prefix ? `${this.__prefix}/${path}` : path; } // public convertFromOData(odataModel: Array<object>): Array<PartialDeep<T>>; convertFromOData(odataModel) { if (odataModel === null || odataModel === undefined) { return odataModel; } if (typeof odataModel !== "object") { throw new Error("The model must be an object!"); } const isList = Array.isArray(odataModel); const models = isList ? odataModel : [odataModel]; const result = models.map((model) => { var _a; const typeByCi = (_a = model["@odata.type"]) === null || _a === void 0 ? void 0 : _a.replace(/^#/, ""); return Object.entries(model).reduce((collector, [key, value]) => { let propKey = this.__getPropMapping().get(key); let finalKey = propKey; if (typeByCi) { const newPropKey = this.__getPropMapping().get(`${typeByCi}/${key}`); if (newPropKey && typeof this.__subtypeMapping !== "undefined") { propKey = newPropKey; finalKey = newPropKey.replace(new RegExp(`^${this.__subtypeMapping[typeByCi]}_`), ""); } } const prop = propKey ? this[propKey] : undefined; if (prop && finalKey) { // complex props const asComplexType = prop; if (typeof asComplexType.getEntity === "function") { // workaround: some V2 services wrap expanded entity collections in an extra results object #125 // => we unwrap this to stay true to the generated model interfaces const wrappedValue = value; const sanitizedValue = asComplexType.isCollectionType() && wrappedValue && typeof wrappedValue === "object" && typeof wrappedValue.results === "object" && Array.isArray(wrappedValue.results) ? wrappedValue.results : value; const entity = asComplexType.getEntity(); collector[finalKey] = entity.convertFromOData(sanitizedValue); } // primitive props else { collector[finalKey] = prop.converter ? prop.converter.convertFrom(value) : value; } } // be permissive here to allow passing unknown values as they are else { collector[key] = value; } return collector; }, {}); }); return isList ? result : result[0]; } convertToOData(userModel, failForUnknownProps = false) { if (userModel === null || userModel === undefined) { return userModel; } if (typeof userModel !== "object") { throw new Error("The model must be an object!"); } const isList = Array.isArray(userModel); const models = isList ? userModel : [userModel]; const result = models.map((model) => { var _a; // @ts-ignore const typeByCi = (_a = model["@odata.type"]) === null || _a === void 0 ? void 0 : _a.replace(/^#/, ""); return Object.entries(model).reduce((collector, [key, value]) => { let prop = this[key]; let finalKey = prop === null || prop === void 0 ? void 0 : prop.getPath(); if (typeByCi && typeof this.__subtypeMapping !== "undefined") { const qName = this.__subtypeMapping[typeByCi]; const subProp = this[`${qName}_${key}`]; if (subProp) { prop = subProp; finalKey = subProp.getPath().replace(new RegExp(`^${typeByCi}/`), ""); } } const asEntity = prop; if (typeof (asEntity === null || asEntity === void 0 ? void 0 : asEntity.getEntity) === "function") { const entity = asEntity.getEntity(); collector[finalKey] = entity.convertToOData(value); } else if (prop) { collector[finalKey] = prop.converter ? prop.converter.convertTo(value) : value; } // control information is passed as is else if (key.startsWith("@")) { collector[key] = value; } else if (failForUnknownProps) { const knownProps = [...this.__getPropMapping().values()].join(","); throw new Error(`Property [${key}] not found (in strict mode)! Known user model props: ${knownProps}`); } else { // passing unknown value as is collector[key] = value; } return collector; }, {}); }); return isList ? result : result[0]; } } exports.QueryObject = QueryObject; //# sourceMappingURL=QueryObject.js.map